/****************************************************************************/
/*                                                                          */
/*  VolVis is a volume visualization system for investigating, manipulating */
/*  and rendering geometric and volumetric data.                            */
/*                                                                          */
/*  Copyright (C) 1993 by the Research Foundation of the State University   */
/*                            of New York                                   */
/*                                                                          */
/*  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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.               */
/*                                                                          */
/*  For information on VolVis, contact us at:                               */
/*                                                                          */
/*                volvis@cs.sunysb.edu                         (email)      */
/*                                                                          */
/*                Lisa Sobierajski & Ricardo Avila             (US Mail)    */
/*                Department of Computer Science                            */
/*                State University of New York at Stony Brook               */
/*                Stony Brook, New York  11794-4400                         */
/*                                                                          */
/****************************************************************************/



/*
 *                  File: MOTIF_ide_operation.c
 *                Author: He, Taosong
 *                  Date: 1/19/93
 *           Description: MOTIF routines for input device UI creation
 *  Modification History:
 *
 *         who?         when?           why?
 *    -----------------------------------------------------------
 *
 */

/******************************************************************/
/*                The standard C include file                     */
/******************************************************************/

# include <stdio.h>
# include <stdlib.h>
# include <string.h>

/******************************************************************/
/*               The MOTIF include file                           */
/******************************************************************/


# include <X11/keysym.h>
# include <Xm/Xm.h>
# include <Xm/Form.h>
# include <Xm/Frame.h>
# include <Xm/RowColumn.h>
# include <Xm/ToggleBG.h>
# include <Xm/ToggleB.h>
# include <Xm/PushB.h>
# include <Xm/PushBG.h>
# include <Xm/BulletinB.h>
# include <Xm/DialogS.h>
# include <Xm/Text.h>
# include <Xm/TextF.h>
# include <Xm/LabelG.h>
# include <Xm/DrawingA.h>
# include <Xm/CascadeB.h>

/******************************************************************/
/*                  VolVis include file                           */
/******************************************************************/

# include "C_ide.h"
# include "MOTIF_windefs.h"

extern C_IDE_VD_configuration IDE_VD_configuration[C_MAX_VD_NUMBER];

C_ide_operation_map rd_operation_map[C_MAX_RD_NUMBER][C_MAX_OPERATION_NUMBER];

Widget selection_window[C_MAX_VD_NUMBER];
Widget operation_window[C_MAX_RD_NUMBER];
Widget toggle[C_MAX_VD_NUMBER][C_MAX_SELECTION_NUMBER];
static Widget operation_label[C_MAX_RD_NUMBER][C_MAX_OPERATION_NUMBER];

static int active_selection_number = 0;

void temp_init_operation()
{
   int i,j;
   
   for (j=0; j< C_MAX_RD_NUMBER; j++)
    {
      operation_window[j] = NULL;
      for (i=0; i< C_MAX_OPERATION_NUMBER; i++)
        {
          sprintf(rd_operation_map[j][i].name, "%s", "*  null");
        }
    }

   for (j=0; j< C_MAX_VD_NUMBER; j++)
        selection_window[j] = NULL;

}

void selection_toggle(w, client_data, call_data)
Widget w;
int client_data;
XmToggleButtonCallbackStruct *call_data;
{
   if (call_data->set)
    active_selection_number = client_data;
}

char *get_device_label(device)
int device;
{
    char *string = "                                           ";
    
    switch (device)
      {

        case C_MOUSE: sprintf(string, "%s", " mouse     ");
                      break;
        case C_ISOTRAK: sprintf(string, "%s", " isotrak     ");
                        break;
        case C_DATAGLOVE: sprintf(string, "%s", " dataglove ");
                        break;
        case C_KEYBOARD: sprintf(string, "%s", " keyboard ");
                         break;
        case C_SPACEBALL: sprintf(string, "%s", " spaceball ");
                         break;
        default : return("*     null");
                         break;
       }
      return(string);
}

char *get_selection_label(selection, vd_device)
int selection;
int vd_device;
{
    int device, op_no;

    char *string = "                                           ";
    
    device = IDE_VD_configuration[vd_device].selection[selection].source_device;

    string = get_device_label(device);
    
    if (string[0] == '*') 
               return("     null");

    op_no = IDE_VD_configuration[vd_device].selection[selection].operation_number;

    if (rd_operation_map[device][op_no].name[0] == '*')
               return("     null");
    sprintf(string, "%s %s", string, rd_operation_map[device][op_no].name);
 
    return(string);
}

XmString get_selection_string(sel_no, vd_device)
int sel_no;
int vd_device;
{
  XmString string;
  char temp_string1[40];
  char temp_string[60]; 
  
  sprintf(temp_string1, "%s", get_selection_label(sel_no, vd_device));
  if (sel_no == C_MAX_SELECTION_NUMBER-1)
        sprintf(temp_string, "start: %s", temp_string1);
   else
        sprintf(temp_string, "sel %d: %s" , sel_no+1, temp_string1);
   string = XmStringCreate(temp_string, XmSTRING_DEFAULT_CHARSET);
  
   return(string);
} 

XmString get_operation_label(device, operation)
int device;
int operation;
{
     int n;
     char temp_string[30];

     n = 0;
     if (rd_operation_map[device][operation].name[0] == '*')
      sprintf(temp_string, "operation %d :    null", operation+1);
     else
      sprintf(temp_string, "operation %d : %s", operation+1,
            rd_operation_map[device][operation].name);
     return(XmStringCreate (temp_string, XmSTRING_DEFAULT_CHARSET));
}

void create_operation_label(parent, device)
Widget parent;
int device;
{
 extern C_WindowDefs    window_defs;
 Widget frame, rc;

 Arg args[20];
 XmString string;

 char temp_string[60];

 int i, n;

   n = 0;
   XtSetArg (args[n], XmNx, 10); n++;
   XtSetArg (args[n], XmNy, 10);  n++;
   C_Set_Color_Frame( args, n, window_defs );
   frame = XmCreateFrame (parent, "frame", args, n);
   XtManageChild (frame);

   n = 0;
   C_Set_Color_RowColumn( args, n, window_defs );
   XtSetArg(args[n], XmNentryAlignment, XmALIGNMENT_BEGINNING);
   XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
   rc = XmCreateRowColumn(frame, "rc", args, n);
   XtManageChild (rc);

   for (i=0; i<C_MAX_OPERATION_NUMBER; i++)
    {
     n = 0;
     C_Set_Color_Label( args, n, window_defs ); 
     string = get_operation_label(device, i);
     XtSetArg (args[n], XmNlabelString, string); n++;
     operation_label[device][i] = XmCreateLabelGadget(rc, "", args, n);
    } 
   XtManageChildren(operation_label[device], C_MAX_OPERATION_NUMBER);
  
}


void C_create_operation_map(w, client_data, call_data)
Widget w;
int client_data;
caddr_t *call_data;
{
 extern Widget vv_toplevel;
 extern C_WindowDefs     window_defs;

 void C_ide_create_help_exit();

 Arg args[20];
 XmString string, string1;

 int n;

 char char_string[20];

  if (operation_window[client_data] )
    {
      XtManageChild(operation_window[client_data]);
      return;
    }

  

   n = 0;
   XtSetArg( args[n], XmNautoUnmanage, False ); n++;
   XtSetArg( args[n], XmNautoUnmanage, False ); n++;
   
   switch (client_data)
    {
      case C_MOUSE: string = XmStringCreate(" Mouse Operation Map", 
                                              XmSTRING_DEFAULT_CHARSET);
                    break;
      case C_KEYBOARD: string = XmStringCreate(" Keyboard Operation Map", 
                                              XmSTRING_DEFAULT_CHARSET);
                    break;
      case C_ISOTRAK: string = XmStringCreate(" Isotrak Operation Map", 
                                              XmSTRING_DEFAULT_CHARSET);
                    break;
      case C_DATAGLOVE: string = XmStringCreate(" DataGlove Operation Map", 
                                              XmSTRING_DEFAULT_CHARSET);
                    break;
      case C_SPACEBALL: string = XmStringCreate(" Spaceball Operation Map", 
                                              XmSTRING_DEFAULT_CHARSET);
                    break;
      default : return;
     }
    XtSetArg( args[n], XmNdialogTitle, string ); n++;
    C_Set_Color_Dialog( args, n, window_defs );
 
    operation_window[client_data] = XmCreateBulletinBoardDialog(
                        vv_toplevel, "Operation Map", args, n);

    C_ide_create_help_exit(operation_window[client_data], 
                       10+25*C_MAX_OPERATION_NUMBER);

    create_operation_label(operation_window[client_data], client_data); 

    XtManageChild(operation_window[client_data]);
}


void update_operation_map(device, operation1, operation2)
int device;
int operation1;
int operation2;
{
   int n;
   Arg args[20];
   XmString string;

   if (!operation_window[device]) return;

   if (operation1 != -1)
    {
     n =0;
     string = get_operation_label(device, operation1);
     XtSetArg (args[n], XmNlabelString, string); n++;
     XtSetValues(operation_label[device][operation1], args, n);
     XmStringFree(string);
    }

   n =0;
   string = get_operation_label(device, operation2);
   XtSetArg (args[n], XmNlabelString, string); n++;
   XtSetValues(operation_label[device][operation2], args, n);
   XmStringFree(string);
  
}

void item_selection_callback(w, client_data, call_data)
Widget w;
int client_data;
caddr_t *call_data;
{
   int i,n ;
   int temp_sel;

   int device, vd_device, op_no;

   Arg args[20];
   XmString string;

   vd_device = client_data/10000;
   client_data = client_data-vd_device*10000;
   device = client_data/100;
   op_no = client_data-device*100;

   temp_sel = -1;

   for (i=0; i< C_MAX_SELECTION_NUMBER; i++)
     {
       if ((IDE_VD_configuration[vd_device].selection[i].source_device 
            == device)
           && (IDE_VD_configuration[vd_device].selection[i].operation_number 
               == op_no))
        {
           temp_sel = i;
           IDE_VD_configuration[vd_device].selection[i].source_device = -1;
           break;
        }
    }
   IDE_VD_configuration[vd_device].selection[active_selection_number].source_device = device;
   IDE_VD_configuration[vd_device].selection[active_selection_number].operation_number = op_no;

   n = 0;
   string = get_selection_string(active_selection_number, vd_device);
   XtSetArg (args[n], XmNlabelString, string); n++;
   XtSetValues(toggle[vd_device][active_selection_number], args, n);
   XmStringFree(string);

   if (temp_sel != -1)
      {
        n = 0;
        string = get_selection_string(temp_sel, vd_device);
        XtSetArg (args[n], XmNlabelString, string); n++;
        XtSetValues(toggle[vd_device][temp_sel], args, n);
        XmStringFree(string);
      }
}

 
void create_modify_map(parent, vd_device)
int vd_device;
Widget parent;
{
   extern C_WindowDefs    window_defs;
   Widget frame;
   Widget radiobox;
   Widget selection_label;
   Arg args[20];
   XmString string;

   int i, n;

   n = 0;
   XtSetArg( args[n], XmNx, 10); n++;
   XtSetArg( args[n], XmNy, 10); n++;
   C_Set_Color_Label( args, n, window_defs ); 
   selection_label = XmCreateLabelGadget(parent, "Selection Bar", args, n);
   XtManageChild(selection_label);
   
   n = 0;
   XtSetArg (args[n], XmNx, 10); n++;
   XtSetArg (args[n], XmNy, 40);  n++; 
   C_Set_Color_Frame( args, n, window_defs );
   frame = XmCreateFrame (parent, "frame", args, n);
   XtManageChild (frame);

   n = 0;
   XtSetArg( args[n], XmNorientation, XmVERTICAL ); n++;
   C_Set_Color_RadioBox( args, n, window_defs );
   radiobox = XmCreateRadioBox (frame, "radiobox", args, n);
   XtManageChild (radiobox);

   for (i=0; i< C_MAX_SELECTION_NUMBER-1; i++) 
    {
       n = 0;
       string = get_selection_string(i, vd_device); 
       XtSetArg (args[n], XmNlabelString, string); n++;
       C_Set_Color_ToggleButton( args, n, window_defs );
       toggle[vd_device][i] = XtCreateWidget ("", xmToggleButtonWidgetClass, 
                                   radiobox, args, n);
       XtAddCallback(toggle[vd_device][i], XmNvalueChangedCallback,
                                 selection_toggle, i);
       XmStringFree(string);
    }
   n = 0;
   string = get_selection_string(C_MAX_SELECTION_NUMBER-1, vd_device);
   XtSetArg (args[n], XmNlabelString, string); n++;
   C_Set_Color_ToggleButton( args, n, window_defs );
   toggle[vd_device][C_MAX_SELECTION_NUMBER-1] = 
           XtCreateWidget ("", xmToggleButtonWidgetClass,
                           radiobox, args, n);
   XtAddCallback(toggle[vd_device][C_MAX_SELECTION_NUMBER-1], 
        XmNvalueChangedCallback, selection_toggle, C_MAX_SELECTION_NUMBER-1);
   XmStringFree(string);

   n = 0;
   XtSetArg( args[n], XmNset, TRUE ); n++;
   XtSetValues (toggle[vd_device][0], args, n);

   XtManageChildren (toggle[vd_device], C_MAX_SELECTION_NUMBER);
}

void C_ide_create_help_exit(parent, position)
Widget parent;
int position;
{
   extern C_WindowDefs    window_defs;
   extern void C_ide_quit();

   Widget frame, rc;
   Widget button[2];

   int n;
   Arg args[20];
   XmString string;

        n = 0;
        XtSetArg( args[n], XmNx, 10); n++;
        XtSetArg( args[n], XmNy, position); n++;
        C_Set_Color_Frame( args, n, window_defs );
        frame = XmCreateFrame( parent, "frame", args, n );
        XtManageChild(frame);

        n =0;
        C_Set_Color_RowColumn( args, n, window_defs );
        XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
        XtSetArg(args[n], XmNpacking, XmPACK_COLUMN); n++;
        XtSetArg(args[n], XmNnumColumns, 2); n++;
        rc = XmCreateRowColumn(frame, "rc", args, n);
        XtManageChild (rc);

        n=0;
        C_Set_Color_Button( args, n, window_defs );
        button[0] = XmCreatePushButton( rc, "Help", args, n);
   
        n=0;
        C_Set_Color_Button( args, n, window_defs );
        button[1] = XmCreatePushButton( rc, "Close", args, n);
        XtAddCallback(button[1], XmNactivateCallback, C_ide_quit, parent);

        XtManageChildren(button,2);
}


void create_device_menu(parent, vd_device)
Widget parent;
int vd_device;
{
   extern C_WindowDefs     window_defs;

   Widget device_label;

   Arg args[20];
   XmString string, string1;

   char temp_string[20], temp_string1[20];  

   int i, n, j;

   Widget frame, rc;
   Widget selection_pulldown[C_MAX_RD_NUMBER];
   Widget sel_pulldown_options[C_MAX_RD_NUMBER][C_MAX_SELECTION_NUMBER];
   Widget selection_menu[C_MAX_RD_NUMBER];

    n = 0;
    XtSetArg( args[n], XmNx, 280); n++;
    XtSetArg( args[n], XmNy, 110); n++;
    C_Set_Color_Label( args, n, window_defs ); 
    device_label = XmCreateLabelGadget(parent, "Device Assignment", args, n);
    XtManageChild(device_label);

    n = 0;
    XtSetArg( args[n], XmNx, 270); n++;
    XtSetArg( args[n], XmNy, 140); n++;
    C_Set_Color_Frame( args, n, window_defs );
    frame = XmCreateFrame(parent, "frame", args, n );
    XtManageChild( frame );

    n =0;
    C_Set_Color_RowColumn( args, n, window_defs );
    XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
    rc = XmCreateRowColumn(frame, "rc", args, n);
    XtManageChild (rc);


    for (j=0; j< C_MAX_RD_NUMBER; j++)
     {
      sprintf(temp_string1, "%s", get_device_label(j));
      if (temp_string1[0] != '*') 
       {  
        n = 0;
        C_Set_Color_PullDown( args, n, window_defs );
        selection_pulldown[j] = XmCreatePulldownMenu(rc, "pulldown", args, n);

        for (i=0; i<C_MAX_OPERATION_NUMBER; i++)
         {
           n = 0;
           sprintf(temp_string, "%d", i+1);
           string = XmStringCreate (temp_string, XmSTRING_DEFAULT_CHARSET);
           XtSetArg (args[n], XmNlabelString, string); n++;
           sel_pulldown_options[j][i] = XmCreatePushButtonGadget(
             selection_pulldown[j], "", args, n);
           XtAddCallback (sel_pulldown_options[j][i], XmNactivateCallback,
                          item_selection_callback, vd_device*10000+j*100+i);
           XmStringFree (string);
           XtManageChild(sel_pulldown_options[j][i]);
         }

        n = 0;
        string = XmStringCreate (temp_string1, XmSTRING_DEFAULT_CHARSET);
        XtSetArg (args[n], XmNlabelString, string); n++;
        C_Set_Color_OptionMenu( args, n, window_defs );
        XtSetArg (args[n], XmNsubMenuId, selection_pulldown[j]); n++;       
        XtSetArg (args[n], XmNmenuHistory, sel_pulldown_options[j][0]), n++;
        selection_menu[j] = XmCreateOptionMenu(rc, "selection_number_menu", 
                                            args, n);
        XmStringFree(string);
        XtManageChild(selection_menu[j]);

       }   
      }
}

void create_operation_menu(parent)
Widget parent;
{
  extern C_WindowDefs    window_defs;
  Widget frame, rc;
  Widget operation_label;
  
  Widget operation_pulldown;
  Widget op_pulldown_options[C_MAX_RD_NUMBER];
  Widget operation_menu;

  Arg args[20];
  XmString string;

  char temp_string[30];

  int i, n;

    n = 0;
    XtSetArg( args[n], XmNx, 280); n++;
    XtSetArg( args[n], XmNy, 10); n++;
    C_Set_Color_Label( args, n, window_defs ); 
    operation_label = XmCreateLabelGadget(parent, "Operation Map", args, n);
    XtManageChild(operation_label);

    n = 0;
    XtSetArg( args[n], XmNx, 270); n++;
    XtSetArg( args[n], XmNy, 40); n++;
    C_Set_Color_Frame( args, n, window_defs );
    frame = XmCreateFrame(parent, "frame", args, n );
    XtManageChild( frame );

    n =0;
    C_Set_Color_RowColumn( args, n, window_defs );
    XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
    rc = XmCreateRowColumn(frame, "rc", args, n);
    XtManageChild (rc);

    n = 0;
    C_Set_Color_PullDown( args, n, window_defs );
    operation_pulldown = XmCreatePulldownMenu(rc, "pulldown", args, n);

    for (i=0; i<C_CURRENT_RD_NUMBER; i++)
     {
       n = 0;
       sprintf(temp_string, "%s", get_device_label(i));
       if (temp_string[0] != '*')
        {
          string = XmStringCreate (temp_string, XmSTRING_DEFAULT_CHARSET);
          XtSetArg (args[n], XmNlabelString, string); n++;
          op_pulldown_options[i] = XmCreatePushButtonGadget(
             operation_pulldown, temp_string, args, n);
          XtAddCallback (op_pulldown_options[i], XmNactivateCallback,
                         C_create_operation_map, i);
          XmStringFree (string);
          XtManageChild(op_pulldown_options[i]);
         }
      }

     n = 0;
     C_Set_Color_OptionMenu( args, n, window_defs );
     XtSetArg (args[n], XmNsubMenuId, operation_pulldown); n++;
     XtSetArg (args[n], XmNmenuHistory, op_pulldown_options[C_MOUSE]); n++;
     operation_menu = XmCreateOptionMenu(rc, "", args, n);

     XtManageChild(operation_menu);
}

void C_update_selection_label()
{
   int i, j;

   Arg args[20];
   XmString string;
   int n;
  
   for (i=0;  i< C_MAX_VD_NUMBER; i++)
    {
     if (selection_window[i])
      {
        for (j=0; j < C_MAX_SELECTION_NUMBER; j++)
         {
           n = 0;
           string = get_selection_string(j, i);
           XtSetArg (args[n], XmNlabelString, string); n++;
           XtSetValues(toggle[i][j], args, n);
           XmStringFree(string);
         }
      }
    }
}


void C_create_selection_map(w, vd_device, call_data)
Widget w;
int vd_device;
caddr_t call_data;
{
  
   extern Widget vv_toplevel;
   extern C_WindowDefs     window_defs;

   Arg args[20];
   XmString string; 

   char char_string[20];

   int n;

   if (selection_window[vd_device])
     {
         XtManageChild(selection_window[vd_device]);
         return;
     }

   if (vd_device == 0)
       string = XmStringCreate("Selection Control      Default Virtual Device", 
                                   XmSTRING_DEFAULT_CHARSET);
   else
      {
       sprintf(char_string, 
               "Selection Control      Virtual Device %d", vd_device);
       string = XmStringCreate(char_string, XmSTRING_DEFAULT_CHARSET);
       }

   n = 0;
   XtSetArg( args[n], XmNdialogTitle, string ); n++;
   XtSetArg( args[n], XmNautoUnmanage, False ); n++;
   C_Set_Color_Dialog( args, n, window_defs );
   selection_window[vd_device] = XmCreateBulletinBoardDialog(
                        vv_toplevel, "Selection Map", args, n);
   XmStringFree(string);
   

   create_modify_map(selection_window[vd_device], vd_device);
   create_operation_menu(selection_window[vd_device]);
   C_ide_create_help_exit(selection_window[vd_device], 
                    150+25*C_MAX_SELECTION_NUMBER);
   create_device_menu(selection_window[vd_device], vd_device);
   XtManageChild(selection_window[vd_device]);

}

