/****************************************************************************/
/*                                                                          */
/*  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_keyboard.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/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xutil.h>
# 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/Text.h>
# include <Xm/TextF.h>
# include <Xm/LabelG.h>
# include <Xm/DrawingA.h>
# include <Xm/CascadeB.h>
# include <Xm/MessageB.h>

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

# include "C_ide.h"
# include "MOTIF_windefs.h"
#include "C_volvis.h"
# include "C_navigator.h"

static XKeyEvent kb_event;
static Widget text;
extern C_IDE_keyboard_lookup keyboard_lookup[C_MAX_OPERATION_NUMBER];
extern C_ide_operation_map
rd_operation_map[C_MAX_RD_NUMBER][C_MAX_OPERATION_NUMBER];

void C_generate_kb_map()
{
 extern C_IDE_keyboard_lookup keyboard_lookup[C_MAX_OPERATION_NUMBER];
 extern Widget vv_toplevel;
 
 Display *display;
 int i;

 display = XtDisplay(vv_toplevel);

 keyboard_lookup[0].flag = 1;
 keyboard_lookup[0].state = 0;
 keyboard_lookup[0].keycode = XKeysymToKeycode(display, (KeySym)XK_z);
 sprintf(rd_operation_map[C_KEYBOARD][0].name, "Key: z");
 
 keyboard_lookup[1].flag = 1;
 keyboard_lookup[1].state = 0;
 keyboard_lookup[1].keycode = XKeysymToKeycode(display, (KeySym)XK_x);
 sprintf(rd_operation_map[C_KEYBOARD][1].name, "Key: x");
 
 for (i=2; i< C_MAX_OPERATION_NUMBER; i++)
  {
   keyboard_lookup[i].flag = -1;
  }
}

void kb_output(w,client_data,event)
Widget w;
caddr_t client_data;
XKeyEvent *event;
{
  Display *display;
  char buffer[30], buffer1[30];
  KeySym keysym;

  display = XtDisplay(w);

  switch (event->state)
   {
      case 0:
          sprintf(buffer, "%s", "Key: "); 
          break;
      case ShiftMask: 
          sprintf(buffer, "%s", "Shift+");
          break;
      case ControlMask:
          sprintf(buffer, "%s", "Control+");
          break;
      case LockMask:
          sprintf(buffer, "%s", "Lock+");
          break;
      case Button1Mask:
          sprintf(buffer, "%s", "Button1+");
          break;
      case Button2Mask:
          sprintf(buffer, "%s", "Button2+");
          break;
      case Button3Mask:
          sprintf(buffer, "%s", "Button3+");
          break;
      default: 
          XmTextSetString(w, "Null");
          return;
    }

  keysym = XKeycodeToKeysym(display, event->keycode, 2);

  sprintf(buffer1, "%s", XKeysymToString(keysym));
  
  if (strstr(buffer1, "Control") ||
      strstr(buffer1, "Caps_Lock") ||
      strstr(buffer1, "Shift"))
     {
       XmTextSetString(w, "Null");
       return;
     }

  sprintf(buffer, "%s%s", buffer, buffer1);

  XmTextSetEditable(text, 1);
  XmTextSetString(w, buffer);
  XmTextSetEditable(text, 0);


printf("\n keycode is %d \n", event->keycode);

  kb_event.keycode = event->keycode;
  kb_event.state = event->state;
}

void assign_kb_operation(w, client_data, call_data)
Widget w;
int client_data;
caddr_t call_data;
{
  extern void update_operation_map();
  extern void C_update_selection_label();
  char buffer[20];
  int i, operation;

  sprintf(buffer, "%s", XmTextGetString(text));

  if (!strcmp(buffer, "Null")) return; 

  operation = -1;

  for (i =0; i< C_MAX_OPERATION_NUMBER; i++)
   {
    if (keyboard_lookup[i].flag != -1)
     {
       if ((keyboard_lookup[i].state == kb_event.state) &&
          (keyboard_lookup[i].keycode == kb_event.keycode))
             {operation =i;
              keyboard_lookup[i].flag = -1;
              sprintf(rd_operation_map[C_KEYBOARD][i].name,
                      "%s", "*  null"); 
             }
     }
   }
  keyboard_lookup[client_data].flag = 1;
  keyboard_lookup[client_data].state = kb_event.state;
  keyboard_lookup[client_data].keycode = kb_event.keycode;

  sprintf(rd_operation_map[C_KEYBOARD][client_data].name, "%s", buffer);

  update_operation_map(C_KEYBOARD, operation, client_data);

  C_update_selection_label();
}

extern create_bottom_line(top_keyboard_panel)
Widget top_keyboard_panel;
{
    extern C_WindowDefs     window_defs;
    extern void C_ide_quit();
    extern void C_create_operation_map();
  
    Widget frame;
    Widget rc;
    Widget button[4];

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

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

    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 );
    XtAddCallback(button[0], XmNactivateCallback,
                  C_create_operation_map, C_KEYBOARD);
    
    n=0;
    C_Set_Color_Button( args, n, window_defs );
    button[1] = XmCreatePushButton( rc, " Simulation", args, n );

    n=0;
    C_Set_Color_Button( args, n, window_defs );
    button[2] = XmCreatePushButton( rc, "Help", args, n );
 
    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_keyboard_panel);
    
    XtManageChildren(button, 4);
}


void create_keyboard_ui(top_keyboard_panel)
Widget top_keyboard_panel;
{
 int           i, n;
 char temp_string[30];
 Arg           args[20];
 XmString      string, string1;

 extern C_WindowDefs    window_defs;

  Widget operation_pulldown;
  Widget pulldown_options[C_MAX_OPERATION_NUMBER];
  Widget operation_menu;

  Widget label, frame, rc, rc1;


    n = 0;
    XtSetArg (args[n], XmNx, 10); n++;
    XtSetArg (args[n], XmNy, 15);  n++;
    C_Set_Color_Label( args, n, window_defs ); 
    string = XmStringCreate ("Key Assignment", XmSTRING_DEFAULT_CHARSET);
    XtSetArg (args[n], XmNlabelString, string); n++;
    label = XmCreateLabelGadget(top_keyboard_panel, "", args, n);
    XtManageChild( label);

    n = 0;
    XtSetArg (args[n], XmNx, 140); n++;
    XtSetArg (args[n], XmNy, 10); n++;
    XtSetArg( args[n], XmNwidth, 150 ); n++;
    XtSetArg( args[n], XmNheight, 40 ); n++;
    XtSetArg( args[n], XmNvalue, "" ); n++;
    C_Set_Color_Text( args, n, window_defs );
    text = XmCreateText (top_keyboard_panel, "", args, n);
    XmTextSetString(text, "Null");
    XtManageChild( text);
    XtAddEventHandler(text, KeyPressMask, FALSE, kb_output, NULL);

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

    n =0;
    XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
    C_Set_Color_RowColumn( args, n, window_defs );
    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_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++;
       pulldown_options[i] = XmCreatePushButtonGadget(
             operation_pulldown, temp_string, args, n);
       XtAddCallback (pulldown_options[i], XmNactivateCallback,
                      assign_kb_operation, i);
       XmStringFree (string);
    }
    XtManageChildren (pulldown_options, C_MAX_OPERATION_NUMBER);

     n = 0;
     string = XmStringCreate ("Operation Number", XmSTRING_DEFAULT_CHARSET);
     XtSetArg (args[n], XmNlabelString, string); n++;
     C_Set_Color_OptionMenu( args, n, window_defs );
     XtSetArg (args[n], XmNsubMenuId, operation_pulldown); n++;
     XtSetArg (args[n], XmNmenuHistory, pulldown_options[0]); n++;
     operation_menu = XmCreateOptionMenu(rc, "", args, n);
     XmStringFree(string);

     create_bottom_line(top_keyboard_panel);

     XtManageChild(operation_menu);
}
         
