/****************************************************************************/
/*                                                                          */
/*  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: C_MOTIF_ide_mouse.c
 *                    Author: ???????????????
 *                      Date: ???????????????
 *               Description: Mouse Control Panel Interface
 *      Modification History:
 *
 *              Who?            When?           Why?
 *      --------------------------------------------------------------------
 *       Theodossiou Andreas  03/93-05/93   cse528 project
 */


/******************************************************************/
/*                The standard C include files                    */
/******************************************************************/
# include <stdio.h>
# include <string.h>


/******************************************************************/
/*               The MOTIF include files                          */
/******************************************************************/
# include <X11/Intrinsic.h>
# include <X11/Shell.h>
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# include <Xm/Xm.h>
# include <Xm/RowColumn.h>
# include <Xm/Frame.h>
# include <Xm/Form.h>
# include <Xm/ToggleBG.h>
# include <Xm/ToggleB.h>
# include <Xm/Text.h>
# include <Xm/PushB.h>
# include <Xm/PushBG.h>
# include <Xm/LabelG.h>
# include <Xm/CascadeB.h>
# include <Xm/BulletinB.h>
# include <Xm/FileSB.h>
# include <Xm/SelectioB.h>
# include <Xm/DialogS.h>
# include <Xm/MessageB.h>

/******************************************************************/
/*                  VolVis include files                          */
/******************************************************************/
#include "MOTIF_windefs.h"
#include "C_ide.h"
#include "C_volvis.h"


char *mouse_label_names[C_MOUSE_MAX_LABELS]   = {"Translation",
                                                "Rotation",
                                                "Trans-Rota"};
char *mouse_trans_names[C_MAX_TRANS]     = {"Traid Mouse"};
char *mouse_rot_names[C_MAX_ROT]         = {"Trackball      ",
                                          "Arcball",
                                          "Slides"};
char *mouse_trans_rot_names[C_MAX_TRANS_ROT] = {"    Manual     "};


/*
 *        Procedure Name:  dummy
 *          Return Value:  void
 *       Input Variables:  none
 *      Output Variables:  none
 *      Update Variables:  none
 *      Global Variables:  none
 *           Description:  Used as a trick to pass both general menu and specific menu
 *                         item parameters to the call backs for menus 
 */
static void dummy() {}


/* Both Widgets are used by callbacks to modify their sensitivity */
Widget simulation_switch;


/*
 *        Procedure Name:  C_translation_callback
 *          Return Value:  void
 *       Input Variables:  Widget widget; 
 *                         C_IDE_simulation_method *client_data;
 *                         XmRowColumnCallbackStruct *call_data;
 *      Output Variables:  none
 *      Update Variables:  client_data
 *      Global Variables:  char *mouse_trans_names 
 *           Description:  Callback for the translation option menu. C_ide_simulation_method's
 *                         address is passed and the appropriate assignment is performed. It also
 *                         sets the simulation_switch to Sentitive
 */
void C_translation_callback(widget, client_data, call_data)
Widget widget;
C_IDE_simulation_method *client_data;
XmRowColumnCallbackStruct *call_data;
{
   client_data->mouse.trans_simu = (int) call_data->data;
   XtSetSensitive(simulation_switch,True);
}


/*
 *        Procedure Name:  C_rotation_callback
 *          Return Value:  void
 *       Input Variables:  Widget widget;
 *                         C_IDE_simulation_method *client_data;
 *                         XmRowColumnCallbackStruct *call_data;
 *      Output Variables:  none
 *      Update Variables:  client_data
 *      Global Variables:  char *mouse_rot_names 
 *           Description:  Callback for the rotation option menu. C_ide_simulation_method's
 *                         address is passed and the appropriate assignment is performed. The
 *                         Sensitivity of the simulation_switch is set to True
 */
void C_rotation_callback(widget, client_data, call_data)
Widget widget;
C_IDE_simulation_method *client_data;
XmRowColumnCallbackStruct *call_data;
{
   client_data->mouse.rot_simu = (int) call_data->data;
   XtSetSensitive(simulation_switch,True);
}



/*
 *        Procedure Name:  C_tran_rot_callback
 *          Return Value:  void
 *       Input Variables:  Widget widget;
 *                         C_IDE_simulation_method *client_data;
 *                         XmRowColumnCallbackStruct *call_data;
 *      Output Variables:  none
 *      Update Variables:  client_data
 *      Global Variables:  char *mouse_trans_rot_names 
 *           Description:  Callback for the trans_rot option menu. C_ide_simulation_method's
 *                         address is passed and the appropriate assignment is performed. The
 *                         Sensitivity of the simulation_switch is set to False
 */
void C_tran_rot_callback(widget, client_data, call_data)
Widget widget;
C_IDE_simulation_method *client_data;
XmRowColumnCallbackStruct *call_data;
{
   client_data->mouse.trans_rot_simu = (int) call_data->data;
   XtSetSensitive(simulation_switch,False);
}



/*
 *        Procedure Name:  C_simulate_switch_callback
 *          Return Value:  void
 *       Input Variables:  Widget widget;
 *                         C_IDE_simulation_method *client_data;
 *                          XmRowColumnCallbackStruct *call_data;
 *      Output Variables:  none
 *      Update Variables:  client_data
 *      Global Variables:  none
 *           Description:  Callback for the simulation switch option menu. C_ide_simulation_method's
 *                         address is passed and the appropriate assignment is performed. The
 */
void C_simulate_switch_callback(widget, client_data, call_data)
Widget widget;
C_IDE_simulation_method *client_data;
XmRowColumnCallbackStruct *call_data;
{

   client_data->mouse.simulate_switch_simu = (int) call_data->data;
}


/*
 *        Procedure Name:  create_mouse_ui
 *          Return Value:  void
 *       Input Variables:  Widget top_mouse_panel
 *      Output Variables:  none
 *      Update Variables:  none
 *      Global Variables:  C_Window_Defs window_defs (extern)
 *           Description:  Creates the mouse user interface by appropriate calls to 
 *                         other functions
 */
void create_mouse_ui(top_mouse_panel)
Widget top_mouse_panel;
{

   extern  C_WindowDefs     window_defs;
   extern  Widget mouse_token_bulletin;
   
   /***    Internal Routines  ***/

   void C_ide_mouse_create_simulation_method();
   void C_ide_mouse_switch_simulate();
   void C_ide_mouse_create_control_panel_bottom();

   /***    Local Variables     ***/
   Widget flabel[3], frame;
   Arg args[20];
   XmString string;
   int n;

   n = 0;
   XtSetArg( args[n], XmNx, 10 ); n++;
   XtSetArg( args[n], XmNy, 10 ); n++;
   string = XmStringCreate ("Information", XmSTRING_DEFAULT_CHARSET);
   XtSetArg (args[n], XmNlabelString, string); n++;
   C_Set_Color_Label( args, n, window_defs ); 
   flabel[0] = XmCreateLabelGadget(top_mouse_panel, "", args, n);
   XtManageChild(flabel[0]);

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

   n = 0;
   XtSetArg( args[n], XmNx, 120 ); n++;
   XtSetArg( args[n], XmNy, 10 ); n++;
   string = XmStringCreate ("     Mouse data display panel    ", 
                            XmSTRING_DEFAULT_CHARSET);
   XtSetArg (args[n], XmNlabelString, string); n++;
   C_Set_Color_Label( args, n, window_defs ); 
   mouse_token_bulletin=XmCreateLabel (frame, " ", args, n);
   XtManageChild(mouse_token_bulletin);
   XmStringFree (string);
   
   n = 0;
   XtSetArg( args[n], XmNx, 300 ); n++;
   XtSetArg( args[n], XmNy, 80); n++;
   string = XmStringCreate ("Simulation Switch", XmSTRING_DEFAULT_CHARSET);
   XtSetArg (args[n], XmNlabelString, string); n++;
   C_Set_Color_Label( args, n, window_defs ); 
   flabel[1] = XmCreateLabelGadget(top_mouse_panel, "Simulation Switch",
                                   args, n);
   XtManageChild(flabel[1]);
   XmStringFree (string);

   C_ide_mouse_switch_simulate(top_mouse_panel); /* create option menu in simulation switch */

   n = 0;
   XtSetArg( args[n], XmNx, 10 ); n++;
   XtSetArg( args[n], XmNy, 50 ); n++;
   C_Set_Color_Label( args, n, window_defs ); 
   flabel[2] = XmCreateLabelGadget(top_mouse_panel, "Simulation Methods", 
                                   args, n);
   XtManageChild(flabel[2]);

   C_ide_mouse_create_simulation_method(top_mouse_panel); /* create option menus is simulation method */

   n = 0;
   XtSetArg( args[n], XmNx, 10 ); n++;
   XtSetArg( args[n], XmNy, 260); n++;

   C_ide_mouse_create_control_panel_bottom(top_mouse_panel, n, args);  /* create bottom panel */

}


/*
 *        Procedure Name:  C_ide_mouse_switch_simulate
 *          Return Value:  void
 *       Input Variables:  Widget parent
 *      Output Variables:  none
 *      Update Variables:  none
 *      Global Variables:  Widget simulation_switch
 *                         C_Window_Defs window_defs (extern)
 *                         C_IDE_simulation_method C_ide_simulation_method (extern)
 *           Description:  Creates the label, pulldown and option menu for the simulation
 *                         switch
 */
void C_ide_mouse_switch_simulate(parent)
Widget parent;
{

    extern C_IDE_simulation_method C_ide_simulation_method;
    extern C_WindowDefs     window_defs;
    Widget frame;
    Widget pulldown;
    Widget pulldown_options[C_MAX_SELECTION_NUMBER-2];
    
    char   temp_string[20];

    Arg args[20];
    XmString string;

    int n;

    int i;

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

    n = 0;
    C_Set_Color_PullDown( args, n, window_defs );
    pulldown =
            XmCreatePulldownMenu(frame, "pulldown", args, n);
    XtAddCallback(pulldown,XmNentryCallback,
                  C_simulate_switch_callback,&C_ide_simulation_method);

    /* Pulldown options */
  
    for (i = 0; i< C_MAX_SELECTION_NUMBER-2; i++)
     {
       sprintf(temp_string, "%d", i+1);
       string = XmStringCreate (temp_string, XmSTRING_DEFAULT_CHARSET);
       string = XmStringConcat( 
                   XmStringCreate (" ", XmSTRING_DEFAULT_CHARSET),
                   string);
       XtSetArg (args[n], XmNlabelString, string); n++;
      
       pulldown_options[i] = 
                     XmCreatePushButtonGadget(pulldown, "", args, n);

       /* trick to pass both menu general and menu item specific parametrs to callback */
       XtAddCallback(pulldown_options[i],XmNactivateCallback,dummy,i+1);
       XmStringFree(string);
     }

    XtManageChildren(pulldown_options, C_MAX_SELECTION_NUMBER-2);
 

    /* Initialize the global variable */

    n = 0;
    string = XmStringCreate ("Selection: ", XmSTRING_DEFAULT_CHARSET);
    XtSetArg (args[n], XmNlabelString, string); n++;
    XtSetArg (args[n], XmNsubMenuId, pulldown); n++;
    C_Set_Color_OptionMenu( args, n, window_defs );
    XtSetArg (args[n], XmNmenuHistory,pulldown_options[0]), n++;
    simulation_switch = XmCreateOptionMenu(frame, "selection_number_menu", args, n);
    XmStringFree(string);

    XtManageChild(simulation_switch);

}
    
  
/*
 *        Procedure Name:  C_ide_mouse_create_simulation_method
 *          Return Value:  void
 *       Input Variables:  Widget parent
 *      Output Variables:  none
 *      Update Variables:  none
 *      Global Variables:  C_Window_Defs window_defs (extern) 
 *                         C_IDE_simulation_method C_ide_simulation_method (extern)
 *                         char *mouse_label_names 
 *                         char *mouse_trans_names
 *                         char *mouse_rot_names 
 *                         char *mouse_trans_rot_names 
 *           Description:  Creates the three option menus in the Simulation method of
 *                         the mouse control panel.
 */
void C_ide_mouse_create_simulation_method(parent)
Widget parent;
{
    extern C_WindowDefs     window_defs;
    extern C_IDE_simulation_method C_ide_simulation_method;

    Arg args[30];
    int n,i,toppos;
    XmString string;

    Widget frame;

    Widget form;
  
    Widget rc;

    Widget label, flabel[C_MOUSE_MAX_LABELS];

    Widget translation_pulldown;
    Widget translation_options[C_MAX_TRANS];
    Widget translation_menu;

    Widget rotation_pulldown;
    Widget rotation_options[C_MAX_ROT];
    Widget rotation_menu;

    Widget tran_rot_pulldown;
    Widget tran_rot_options[C_MAX_TRANS_ROT];
    Widget tran_rot_menu;

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

    /* Form is used to force equal sizes */

    n = 0;
    C_Set_Color_RowColumn( args, n, window_defs );
    form = XmCreateForm(frame, "form", args, n);
    XtManageChild (form);

    n =0; 
    C_Set_Color_RowColumn( args, n, window_defs );
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
    XtSetArg(args[n], XmNleftPosition, 40); n++;
    XtSetArg(args[n], XmNrightPosition, 100); n++;
    XtSetArg(args[n], XmNtopPosition,1); n++;
    XtSetArg(args[n], XmNbottomPosition, 99); n++;
    XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
    XtSetArg(args[n], XmNpacking, XmPACK_COLUMN); n++;
    XtSetArg(args[n], XmNnumColumns, 1); n++;
    rc = XmCreateRowColumn(form, "rc", args, n);
    XtManageChild (rc);

    /* Create the labels */

    toppos = 10;
    for (i=0; i<C_MOUSE_MAX_LABELS; i++) { 
        n = 0;
        XtSetArg(args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
        XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
        XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
        XtSetArg(args[n], XmNleftPosition, 1); n++;
        XtSetArg(args[n], XmNrightPosition,38); n++;
        XtSetArg(args[n], XmNtopPosition, toppos); n++;
        string = XmStringCreate (mouse_label_names[i],
                                 XmSTRING_DEFAULT_CHARSET);
        XtSetArg (args[n], XmNlabelString, string); n++;
        flabel[i] = XmCreateLabelGadget(form,
                                        mouse_label_names[i],
                                        args, n);
        XtManageChild(flabel[i]);
        XmStringFree(string);
        toppos += 32;
    }

    n = 0;
    C_Set_Color_PullDown( args, n, window_defs );
    translation_pulldown = XmCreatePulldownMenu(rc, "pulldown", args, n);
    XtAddCallback(translation_pulldown,XmNentryCallback,
                  C_translation_callback,&C_ide_simulation_method);

  
    /* Translation option menu items */

    for (i=0; i<C_MAX_TRANS; i++) {
        n = 0;
        string = XmStringCreate (mouse_trans_names[i], 
                                 XmSTRING_DEFAULT_CHARSET);
        XtSetArg (args[n], XmNlabelString, string); n++;
        translation_options[i] = XmCreatePushButtonGadget(
                                  translation_pulldown,
                                  mouse_trans_names[i],
                                  args, n);
        /* "dummy" tric */
        XtAddCallback(translation_options[i],XmNactivateCallback,dummy,i);
        XmStringFree (string);
    }
    XtManageChildren (translation_options, C_MAX_TRANS);

    n = 0;
    XtSetArg (args[n], XmNsubMenuId, translation_pulldown); n++;
    XtSetArg (args[n], XmNmenuHistory,
              translation_options[0]); n++; /* "Traid Mouse" is initial option */
    C_Set_Color_OptionMenu( args, n, window_defs );
    translation_menu = XmCreateOptionMenu(
                        rc, "translation_option_menu", args, n);

    XtManageChild(translation_menu);

    n = 0;
    C_Set_Color_PullDown( args, n, window_defs );
    rotation_pulldown = XmCreatePulldownMenu(rc, "pulldown", args, n);
    XtAddCallback(rotation_pulldown,XmNentryCallback,
                  C_rotation_callback,&C_ide_simulation_method);


    /* Rotation option menu items */

    for (i=0; i<C_MAX_ROT; i++) {
        n = 0;
        string = XmStringCreate (mouse_rot_names[i], 
                                 XmSTRING_DEFAULT_CHARSET);
        XtSetArg (args[n], XmNlabelString, string); n++;
        rotation_options[i] = XmCreatePushButtonGadget(
                                  rotation_pulldown,
                                  mouse_rot_names[i],
                                  args, n);
        /* "dummy" trick */
        XtAddCallback(rotation_options[i],XmNactivateCallback,dummy,i);
        XmStringFree (string);
    }
    XtManageChildren (rotation_options, C_MAX_ROT);

    n = 0;
    XtSetArg (args[n], XmNsubMenuId, rotation_pulldown); n++;
    C_Set_Color_OptionMenu( args, n, window_defs );
    XtSetArg (args[n], XmNmenuHistory,
              rotation_options[0]); n++; /* "Trackball" is onitial option */
    rotation_menu = XmCreateOptionMenu( rc, "rotation_option_menu", args, n);
    XtManageChild(rotation_menu);

    n = 0;
    C_Set_Color_PullDown( args, n, window_defs );
    tran_rot_pulldown = XmCreatePulldownMenu(rc, "pulldown", args, n);
    XtAddCallback(tran_rot_pulldown,XmNentryCallback,
                  C_tran_rot_callback,&C_ide_simulation_method);

    
    /* Trans_Rota option menu items */

    for (i=0; i<C_MAX_TRANS_ROT; i++) {
        n = 0;
        string = XmStringCreate (mouse_trans_rot_names[i], 
                                 XmSTRING_DEFAULT_CHARSET);
        XtSetArg (args[n], XmNlabelString, string); n++;
        tran_rot_options[i] = XmCreatePushButtonGadget(
                                  tran_rot_pulldown,
                                  mouse_trans_rot_names[i],
                                  args, n);
        /* "dummy" trick */
        XtAddCallback(tran_rot_options[i],XmNactivateCallback,dummy,i);
        XmStringFree (string);
    }
    XtManageChildren (tran_rot_options, C_MAX_TRANS_ROT);

    n = 0;
    XtSetArg (args[n], XmNsubMenuId, tran_rot_pulldown); n++;
    XtSetArg (args[n], XmNmenuHistory,
              tran_rot_options[0]); n++; /* "Manual" is the initial option */
    C_Set_Color_OptionMenu( args, n, window_defs );
    tran_rot_menu = XmCreateOptionMenu(
                        rc, "tran_rot_option_menu", args, n);
    XtManageChild(tran_rot_menu);
}


/*
 *        Procedure Name:  C_ide_mouse_create_control_panel_bottom
 *          Return Value:  void
 *       Input Variables:  Widget top_mouse_panel
 *                         int n 
 *                         Arg args
 *      Output Variables:  none
 *      Update Variables:  none
 *      Global Variables:  C_Window_Defs window_defs (extern)
 *           Description:  Creates the bottom control panel. Positioning coordinates
 *                         are pased in the arguments. The Selection Map button creates
 *                         a Selection Map that only displays information. The user can
 *                         not modify or define new settings
 */
void C_ide_mouse_create_control_panel_bottom(top_mouse_panel, n, args)
Widget top_mouse_panel;
int n;
Arg args[20];
{
   
    extern C_WindowDefs     window_defs;
    extern void  C_ide_quit();
    extern void C_create_operation_map();

    Widget frame;
    Widget rc;
    Widget button[4];
    XmString string;

    C_Set_Color_Frame( args, n, window_defs );
    frame = XmCreateFrame( top_mouse_panel, "frame", args, n );

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

    n=0;
    C_Set_Color_Button( args, n, window_defs );
    button[0] = XmCreatePushButton( rc, "Map", args, n );
    XtManageChild(button[0]);
    XtAddCallback(button[0], XmNactivateCallback, 
                  C_create_operation_map, C_MOUSE);


    n=0;
    C_Set_Color_Button( args, n, window_defs );
    button[1] = XmCreatePushButton( rc, " Simulation", args, n );
    XtManageChild(button[1]);

    n=0;
    C_Set_Color_Button( args, n, window_defs );
    button[2] = XmCreatePushButton( rc, "Help", args, n );
    XtManageChild(button[2]);

    n=0;
    C_Set_Color_Button( args, n, window_defs );
    button[3] = XmCreatePushButton( rc, "Close", args, n);
    XtAddCallback(button[3], XmNactivateCallback, C_ide_quit, top_mouse_panel);
    XtManageChild(button[3]);

    XtManageChild(frame);
}
