/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * filename: xlabels.c                                                     *
 *                                                                         *
 * UTIL C-source: Medical Image Conversion Utility                         *
 *                                                                         *
 * purpose      : label routines                                           *
 *                                                                         *
 * project      : (X)MedCon by Erik Nolf                                   *
 *                                                                         *
 * Functions    : XMdcGetEcatLabelNumbers()     - Get ECAT label numbers   *
 *                XMdcGetImageLabelIndex()      - Get image label index    *
 *                XMdcGetImageLabelTimes()      - Get image label times    *
 *                XMdcPrintImageLabelIndex()    - Print index labels       *
 *                XMdcPrintImageLabelTimes()    - Print times labels       *
 *                XMdcLabelSelCallbackApply()   - Label Apply   callback   *
 *                XMdcUnsensitiveColNumFrames() - Set frames unusable      *
 *                XMdcSensitiveColNumFrames()   - Set frames   usable      *
 *                XMdcLabelSel()                - Label selection          *
 *                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
 */

/*
   Copyright (C) 1997-2026 by Erik Nolf

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any later
   version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
   Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation, Inc.,
   59 Place - Suite 330, Boston, MA 02111-1307, USA.  */

/****************************************************************************
                              H E A D E R S
****************************************************************************/

#include "m-depend.h"

#include <stdio.h>
#ifdef LIBMDC_HAVE_STRING_H
#include <string.h>
#endif
#ifdef LIBMDC_HAVE_STRINGS_H
#ifndef _WIN32
#include <strings.h>
#endif
#endif

#include "xmedcon.h"

/****************************************************************************
                              D E F I N E S
****************************************************************************/

static GtkWidget *wlabel = NULL;
static GtkWidget *colFrame = NULL, *numFrame = NULL;

/****************************************************************************
                            F U N C T I O N S
****************************************************************************/

void XMdcGetEcatLabelNumbers(Uint32 realnumber, Uint32 *plane, Uint32 *frame,
                                                Uint32 *gate,  Uint32 *bed)
{
  /* realnumber = absolute image number, 0-based */
  /* fi->number = total number images  , 1-based */
  /* fi->dim[3] = number of planes     , 1-based */
  /* fi->dim[4] = number of frames     , 1-based */
  /* fi->dim[5] = number of gates      , 1-based */
  /* fi->dim[6] = number of beds       , 1-based */

  Uint32 p, f, g, b;
  Uint32 images_in_frame, images_in_gate, images_in_bed;

  images_in_bed   = my.fi->number  / my.fi->dim[6];
  images_in_gate  = images_in_bed  / my.fi->dim[5];
  images_in_frame = images_in_gate / my.fi->dim[4];

  b = realnumber / images_in_bed;                         /* bed   NR     */
  *bed   = b;                                             /* keep 0-based */

  g = (realnumber / images_in_gate)  % my.fi->dim[5];     /* gate  NR     */
  *gate  = g+1;                                           /* make 1-based */

  f = (realnumber / images_in_frame) % my.fi->dim[4];     /* frame NR     */
  *frame = f+1;                                           /* make 1-based */

  p = (realnumber % images_in_frame);                     /* plane NR     */
  *plane = p+1;                                           /* make 1-based */
}

char *XMdcGetImageLabelIndex(Uint32 nr)
{
   switch (sLabelSelection.CurStyle) {
     case XMDC_LABEL_STYLE_ABS :   sprintf(labelindex,"%u",my.realnumber[nr]+1);
                                   break;
     case XMDC_LABEL_STYLE_PAGE:   sprintf(labelindex,"%u",nr+1);
                                   break;
     case XMDC_LABEL_STYLE_ECAT:
       {
          Uint32 p, f, g, b;
          XMdcGetEcatLabelNumbers(my.realnumber[nr],&p,&f,&g,&b);
          sprintf(labelindex,"%u.%u.%u.%u.%u",f,p,g,0,b); /* date = 0 default */
       }
       break;
   }

   return(labelindex);
}

char *XMdcGetImageLabelTimes(Uint32 nr)
{
  IMG_DATA *id;
  Uint32 i, f;
  float duration;
  char s[10], d[10];


  if (my.fi->dynnr == 0) { labeltimes[0]='\0'; return(labeltimes); }

  i = my.realnumber[nr];
  id = &my.fi->image[i];

  f = id->frame_number;
  duration = MdcSingleImageDuration(my.fi,f-1);
  strncpy(s,MdcGetStrHHMMSS(id->slice_start),10); s[9]='\0';
  strncpy(d,MdcGetStrHHMMSS(duration),10);        d[9]='\0';

  sprintf(labeltimes,"%u S=%s D=%s",f,s,d);

  return(labeltimes);
}



void XMdcPrintImageLabelIndex(GtkWidget *widget, Uint32 nr)
{
  GdkWindow *window;
  GdkDrawingContext *draw_context;
  cairo_region_t *cairo_region;
  cairo_t *cr;
  char *label;

  window = gtk_widget_get_window(widget);

  cairo_region = cairo_region_create();

  /* begin drawing */
  draw_context = gdk_window_begin_draw_frame(window, cairo_region);
  cr = gdk_drawing_context_get_cairo_context(draw_context);

  /* set font */
  cairo_select_font_face(cr, "monospace", CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(cr, 11);

  /* set color */
  switch (sLabelSelection.CurColor) {
    case XMDC_LABEL_RED   : cairo_set_source_rgb(cr, 1, 0, 0); break;
    case XMDC_LABEL_GREEN : cairo_set_source_rgb(cr, 0, 1, 0); break;
    case XMDC_LABEL_BLUE  : cairo_set_source_rgb(cr, 0, 0, 1); break;
    case XMDC_LABEL_YELLOW: cairo_set_source_rgb(cr, 1, 1, 0); break; 
  }

  /* show label */
  label = XMdcGetImageLabelIndex(nr);
  cairo_move_to(cr, 2.0, (double)XMdcScaleH(my.fi->mheight) - 2.0);
  cairo_show_text(cr, label);

  /* end drawing */
  gdk_window_end_draw_frame(window, draw_context);
  cairo_region_destroy(cairo_region);

}

void XMdcPrintImageLabelTimes(GtkWidget *widget, Uint32 nr)
{
  GdkWindow *window;
  GdkDrawingContext *draw_context;
  cairo_region_t *cairo_region;
  cairo_t *cr;
  char *label;

  window = gtk_widget_get_window(widget);

  cairo_region = cairo_region_create();

  /* begin drawing */
  draw_context = gdk_window_begin_draw_frame(window, cairo_region);
  cr = gdk_drawing_context_get_cairo_context(draw_context);

  /* set font */
  cairo_select_font_face(cr, "monospace", CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(cr, 11);

  switch (sLabelSelection.CurColor) {
    case XMDC_LABEL_RED   : cairo_set_source_rgb(cr, 1, 0, 0); break;
    case XMDC_LABEL_GREEN : cairo_set_source_rgb(cr, 0, 1, 0); break;
    case XMDC_LABEL_BLUE  : cairo_set_source_rgb(cr, 0, 0, 1); break;
    case XMDC_LABEL_YELLOW: cairo_set_source_rgb(cr, 1, 1, 0); break;
  }

  /* show label */
  label = XMdcGetImageLabelTimes(nr);
  cairo_move_to(cr, 2.0, 10.0);
  cairo_show_text(cr, label);

  /* end drawing */
  gdk_window_end_draw_frame(window, draw_context);
  cairo_region_destroy(cairo_region);

}

void XMdcLabelSelCallbackApply(GtkWidget *widget, gpointer data)
{
  gint color=XMDC_LABEL_YELLOW, state=MDC_YES, style=XMDC_LABEL_STYLE_PAGE;
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sLabelSelection.On))) {
    MdcDebugPrint("labels: ON "); state = MDC_YES;
  }else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sLabelSelection.Off))) {
    MdcDebugPrint("labels: OFF "); state = MDC_NO;
  }

  MdcDebugPrint("label color: ");
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sLabelSelection.Red))) {
    MdcDebugPrint("\tred"); color = XMDC_LABEL_RED;
  }else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sLabelSelection.Green))) {
    MdcDebugPrint("\tgreen"); color = XMDC_LABEL_GREEN;
  }else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sLabelSelection.Blue))) {
    MdcDebugPrint("\tblue"); color = XMDC_LABEL_BLUE;
  }else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sLabelSelection.Yellow))) {
    MdcDebugPrint("\tyellow"); color = XMDC_LABEL_YELLOW;
  }

  MdcDebugPrint("label number: ");
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sLabelSelection.NrAbsolute))) {
    MdcDebugPrint("\tabsolute"); style = XMDC_LABEL_STYLE_ABS;
  }else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sLabelSelection.NrInPage))) {
    MdcDebugPrint("\tin page");  style = XMDC_LABEL_STYLE_PAGE;
  }else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sLabelSelection.NrEcat))) {
    MdcDebugPrint("\tecat");     style = XMDC_LABEL_STYLE_ECAT;
  }

  if (state!=sLabelSelection.CurState || color!=sLabelSelection.CurColor ||
      style!=sLabelSelection.CurStyle) {
    sLabelSelection.CurState = state;
    sLabelSelection.CurColor = color;
    sLabelSelection.CurStyle = style;
  }

  /* MARK: need some kind of refresh signal here */
   XMdcMainWidgetsInsensitive(); XMdcMainWidgetsResensitive();

}

void XMdcSensitiveColNumFrames(GtkWidget *widget, gpointer data)
{
  gtk_widget_set_sensitive(GTK_WIDGET(colFrame),TRUE);
  gtk_widget_set_sensitive(GTK_WIDGET(numFrame),TRUE);
}

void XMdcUnsensitiveColNumFrames(GtkWidget *widget, gpointer data)
{
  gtk_widget_set_sensitive(GTK_WIDGET(colFrame),FALSE);
  gtk_widget_set_sensitive(GTK_WIDGET(numFrame),FALSE);
}

void XMdcLabelSel(void)
{

  GtkWidget *box1;
  GtkWidget *box2;
  GtkWidget *box3;
  GtkWidget *box4;
  GtkWidget *frame;
  GtkWidget *button;
  GtkWidget *separator;
  GSList *group;

  if (wlabel == NULL) {
    wlabel = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    g_signal_connect(wlabel, "destroy",
                       G_CALLBACK(XMdcMedconQuit), NULL);
    g_signal_connect(wlabel, "delete_event",
                       G_CALLBACK(XMdcHandlerToHide), NULL);


    gtk_window_set_title(GTK_WINDOW(wlabel),"Label Selection");
    gtk_container_set_border_width(GTK_CONTAINER(wlabel),0);

    box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
    gtk_container_add(GTK_CONTAINER(wlabel),box1);
    gtk_widget_show(box1);

    /* create upper box - label */
    box2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
    gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,0);
    gtk_container_set_border_width(GTK_CONTAINER(box2), 5);
    gtk_widget_show(box2);

    box3 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
    gtk_box_pack_start(GTK_BOX(box2),box3,TRUE,TRUE,0);
    gtk_widget_show(box3);

    /* create label ON/OFF frame */
    frame = gtk_frame_new("Label");
    gtk_box_pack_start(GTK_BOX(box3),frame,TRUE,TRUE,0);
    gtk_widget_show(frame);

    box4 = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
    gtk_container_add(GTK_CONTAINER(frame),box4);
    gtk_container_set_border_width(GTK_CONTAINER(box4),5);
    gtk_widget_show(box4);

    /* create radiobuttons */
    button = gtk_radio_button_new_with_label(NULL,"ON");
    gtk_box_pack_start(GTK_BOX(box4),button,TRUE,TRUE,0);
    if (sLabelSelection.CurState == MDC_YES)
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
    g_signal_connect(button, "toggled",
                       G_CALLBACK(XMdcSensitiveColNumFrames),NULL);
    gtk_widget_show(button);
    sLabelSelection.On = button;

    group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
    button = gtk_radio_button_new_with_label(group,"OFF");
    gtk_box_pack_start(GTK_BOX(box4),button,TRUE,TRUE,0);
    if (sLabelSelection.CurState == MDC_NO)
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
    g_signal_connect(button, "toggled",
                       G_CALLBACK(XMdcUnsensitiveColNumFrames),NULL);
    gtk_widget_show(button);
    sLabelSelection.Off = button;
    /* create label colors frame */
    frame = gtk_frame_new("Color"); colFrame = frame;
    gtk_box_pack_start(GTK_BOX(box3),frame,TRUE,TRUE,0);
    gtk_widget_show(frame);

    box4 = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
    gtk_container_add(GTK_CONTAINER(frame),box4);
    gtk_container_set_border_width(GTK_CONTAINER(box4), 10);
    gtk_widget_show(box4);

    /* create radiobuttons */
    button = gtk_radio_button_new_with_label(NULL,"Red");
    gtk_box_pack_start(GTK_BOX(box4),button,TRUE,TRUE,0);
    if (sLabelSelection.CurColor == XMDC_LABEL_RED)
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
    gtk_widget_show(button);
    sLabelSelection.Red = button;

    group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
    button = gtk_radio_button_new_with_label(group,"Green");
    gtk_box_pack_start(GTK_BOX(box4),button,TRUE,TRUE,0);
    if (sLabelSelection.CurColor == XMDC_LABEL_GREEN)
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
    gtk_widget_show(button);
    sLabelSelection.Green = button;

    group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
    button = gtk_radio_button_new_with_label(group,"Blue");
    gtk_box_pack_start(GTK_BOX(box4),button,TRUE,TRUE,0);
    if (sLabelSelection.CurColor == XMDC_LABEL_BLUE)
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
    gtk_widget_show(button);
    sLabelSelection.Blue = button;

    group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
    button = gtk_radio_button_new_with_label(group,"Yellow");
    gtk_box_pack_start(GTK_BOX(box4),button,TRUE,TRUE,0);
    if (sLabelSelection.CurColor == XMDC_LABEL_YELLOW)
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
    gtk_widget_show(button);
    sLabelSelection.Yellow = button;

    /* create label style frame */
    frame = gtk_frame_new("Numbering"); numFrame = frame;
    gtk_box_pack_start(GTK_BOX(box3),frame,TRUE,TRUE,0);
    gtk_widget_show(frame);

    box4 = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
    gtk_container_add(GTK_CONTAINER(frame),box4);
    gtk_container_set_border_width(GTK_CONTAINER(box4), 10);
    gtk_widget_show(box4);

    /* create radiobuttons */
    button = gtk_radio_button_new_with_label(NULL,"Absolute");
    gtk_box_pack_start(GTK_BOX(box4),button,TRUE,TRUE,0);
    if (sLabelSelection.CurStyle == XMDC_LABEL_STYLE_ABS)
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
    gtk_widget_show(button);
    sLabelSelection.NrAbsolute = button;

    group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
    button = gtk_radio_button_new_with_label(group,"In Page");
    gtk_box_pack_start(GTK_BOX(box4),button,TRUE,TRUE,0);
    if (sLabelSelection.CurStyle == XMDC_LABEL_STYLE_PAGE)
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
    gtk_widget_show(button);
    sLabelSelection.NrInPage = button;

    group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));
    button = gtk_radio_button_new_with_label(group,"Ecat/Matrix");
    gtk_box_pack_start(GTK_BOX(box4),button,TRUE,TRUE,0);
    if (sLabelSelection.CurStyle == XMDC_LABEL_STYLE_ECAT)
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
    gtk_widget_show(button);
    sLabelSelection.NrEcat = button;

    /* create horizontal separator */
    separator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
    gtk_box_pack_start(GTK_BOX(box1),separator, FALSE, FALSE, 0);
    gtk_widget_show(separator);

    /* create bottom button box */
    box2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
    gtk_box_pack_start(GTK_BOX(box1),box2,TRUE,TRUE,2);
    gtk_widget_show(box2);

    button = gtk_button_new_with_label("Apply");
    gtk_box_pack_start(GTK_BOX(box2),button,TRUE,TRUE,2);
    g_signal_connect_swapped(button, "clicked",
                       G_CALLBACK(gtk_widget_hide), wlabel);
    g_signal_connect(button, "clicked",
                       G_CALLBACK(XMdcLabelSelCallbackApply), NULL);
    gtk_widget_show(button);

    button = gtk_button_new_with_label("Cancel");
    gtk_box_pack_start(GTK_BOX(box2),button,TRUE,TRUE,2);
    g_signal_connect_swapped(button, "clicked",
        G_CALLBACK(gtk_widget_hide), wlabel);
    gtk_widget_show(button);

  }else{
    /* set buttons to appropriate state */
    GtkWidget *b1, *b2, *b3, *b4;

    gtk_widget_hide(wlabel);

    b1 = sLabelSelection.On;
    b2 = sLabelSelection.Off;
    if (sLabelSelection.CurState == MDC_YES) {
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1),TRUE);
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b2),FALSE);
    }else{
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1),FALSE);
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b2),TRUE);
    }

    b1 = sLabelSelection.Red;
    b2 = sLabelSelection.Green;
    b3 = sLabelSelection.Blue;
    b4 = sLabelSelection.Yellow;
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1),FALSE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b2),FALSE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b3),FALSE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b4),FALSE);
    switch (sLabelSelection.CurColor) {
      case XMDC_LABEL_RED   :
          gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1),TRUE); break;
      case XMDC_LABEL_GREEN :
          gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b2),TRUE); break;
      case XMDC_LABEL_BLUE  :
          gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b3),TRUE); break;
      case XMDC_LABEL_YELLOW:
          gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b4),TRUE); break;
    }

    b1 = sLabelSelection.NrAbsolute;
    b2 = sLabelSelection.NrInPage;
    b3 = sLabelSelection.NrEcat;
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1),FALSE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b2),FALSE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b3),FALSE);
    switch (sLabelSelection.CurStyle) {
      case XMDC_LABEL_STYLE_ABS :
          gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b1),TRUE); break;
      case XMDC_LABEL_STYLE_PAGE:
          gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b2),TRUE); break;
      case XMDC_LABEL_STYLE_ECAT:
          gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b3),TRUE); break;
    }

  }

  if (sLabelSelection.CurState == MDC_NO) {
    XMdcUnsensitiveColNumFrames(NULL,NULL);
  }else{
    XMdcSensitiveColNumFrames(NULL,NULL);
  }

  XMdcShowWidget(wlabel);

}

