/****************************************************************************/
/*                                                                          */
/*  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_ide_ui.c
 *                Author: He, Taosong 
 *                  Date: 1/19/93 
 *           Description: C 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>

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

# include "C_ide.h"

/* Global variable: IDE_VD_change_mode
 *                   This variable records whether the user is assigning
 *                   virtual device for a specific drawingarea. If so,
 *                   IDE_VD_change_mode = VD number. And virtual device 
 *                   allocation panel will not pop up when VD button is pushed.
 */

static int IDE_VD_change_mode = -1;

/*
 *        Procedure Name: C_set_VD_change_mode                    
 *          Return Value:
 *       Input Variables: 
 *      Output Variables:
 *      Update Variables: IDE_VD_change_mode
 *      Global Variables:
 *           Description: Assign value to IDE_VD_change_mode 
 */

void C_set_VD_change_mode(value) 
int  value;
{
  IDE_VD_change_mode = value;
}

/*
 *        Procedure Name: C_check_VD_change_mode
 *          Return Value: whether IDE_VD_change_mode is -1
 *       Input Variables: 
 *      Output Variables:
 *      Update Variables: 
 *      Global Variables:
 *           Description: check the mode of IDE_VD_change_mode 
 */

int C_check_VD_change_mode()
{
  if (IDE_VD_change_mode != -1) return(1);
  else                          return(0);
}

/*
 *        Procedure Name: C_set_VD_handler 
 *          Return Value: void
 *       Input Variables: window index of the specific drawingarea 
 *      Output Variables:
 *      Update Variables:
 *      Global Variables: IDE_device_allocation
 *           Description: Assign virtual device to the specific drawingarea.
 */

void C_set_VD_handler(window_index)
int  window_index;
{
  extern int  IDE_device_allocation[C_MAX_WINDOW_NUMBER];

  IDE_device_allocation [window_index] = IDE_VD_change_mode;
}

void C_init_vd_default(device, vd_number)
int device;
int vd_number; 
{
  extern C_IDE_VD_configuration IDE_VD_configuration[C_MAX_VD_NUMBER];

  IDE_VD_configuration[vd_number].device_involved[C_MOUSE]=0;
  IDE_VD_configuration[vd_number].device_involved[C_ISOTRAK]=0;
  IDE_VD_configuration[vd_number].device_involved[C_SPACEBALL]=1;
  IDE_VD_configuration[vd_number].device_involved[C_DATAGLOVE]=1;

  switch (device)
   {
     case C_MOUSE:
        
        IDE_VD_configuration[vd_number].device_involved[C_MOUSE]=8;

        IDE_VD_configuration[vd_number].orientation_mode = C_EULER;
        IDE_VD_configuration[vd_number].ori = C_MOUSE;

        IDE_VD_configuration[vd_number].oriazi = C_MOUSE;
        IDE_VD_configuration[vd_number].oriele = C_MOUSE;
        IDE_VD_configuration[vd_number].orirol = C_MOUSE;

        IDE_VD_configuration[vd_number].pos2dx = C_MOUSE;
        IDE_VD_configuration[vd_number].pos2dy = C_MOUSE;

        IDE_VD_configuration[vd_number].pos3dx = C_MOUSE;
        IDE_VD_configuration[vd_number].pos3dy = C_MOUSE;
        IDE_VD_configuration[vd_number].pos3dz = C_MOUSE;

        break;

      case C_SPACEBALL:
 
        IDE_VD_configuration[vd_number].device_involved[C_SPACEBALL] = 9;

        IDE_VD_configuration[vd_number].orientation_mode = C_MATRIX;
        IDE_VD_configuration[vd_number].ori = C_SPACEBALL;

        IDE_VD_configuration[vd_number].oriazi = C_SPACEBALL;
        IDE_VD_configuration[vd_number].oriele = C_SPACEBALL;
        IDE_VD_configuration[vd_number].orirol = C_SPACEBALL;

        IDE_VD_configuration[vd_number].pos2dx = C_SPACEBALL;
        IDE_VD_configuration[vd_number].pos2dy = C_SPACEBALL;

        IDE_VD_configuration[vd_number].pos3dx = C_SPACEBALL;
        IDE_VD_configuration[vd_number].pos3dy = C_SPACEBALL;
        IDE_VD_configuration[vd_number].pos3dz = C_SPACEBALL;

        break;
 
      default:

        break;
     }
}


/*
 *        Procedure Name: C_initialize_VD_default 
 *          Return Value: void
 *       Input Variables: 
 *      Output Variables:
 *      Update Variables: IDE_VD_configuration[0]
 *      Global Variables: IDE_VD_configuration
 *           Description: Initialize the default virtual device
 */

void C_initialize_VD_default()
{
   extern C_IDE_VD_configuration IDE_VD_configuration[C_MAX_VD_NUMBER];
   extern void C_ide_open_line();
   extern void C_init_selection();
   extern void C_copy_selection();

   C_init_vd_default(C_MOUSE, IDE_DEFAULT);

   C_init_selection(C_MOUSE, IDE_DEFAULT);

   C_copy_selection();

} 

/*         Global variable: allocated_device
 *                          This variable keeps the current selected 
 *                          real device.
 */ 

static int             allocated_device;

/*
 *        Procedure Name: C_set_device
 *          Return Value: void 
 *       Input Variables: real device 
 *      Output Variables:
 *      Update Variables:
 *      Global Variables:
 *           Description: Set the allocated device to real device name.
 */

void C_set_device(real_device_name)
int real_device_name;
{
  allocated_device = real_device_name;
}

/*
 *        Procedure Name: C_check_allocate_device                            
 *          Return Value: whether a real device is selected
 *       Input Variables: 
 *      Output Variables:
 *      Update Variables:
 *      Global Variables:
 *           Description: check whether a real device is currently selected 
 *                        for virtual device configuration.
 */

int C_check_allocate_device()
{
  if (allocated_device == -1) return(1);
  else                        return(0);
}        

/*
 *        Procedure Name: C_get_allocated_device
 *          Return Value: void
 *       Input Variables: 
 *      Output Variables: currently selected real device
 *      Update Variables: 
 *      Global Variables:
 *           Description: get the currently selected real device 
 */

void C_get_allocated_device(device)
int *device;
{
  *device = allocated_device;
}

/*         Global variable: vd_index
 *                          This variable keeps the virtual device number
 *                          which is currently being configured.
 */

static int             vd_index;

/*
 *        Procedure Name: C_set_VD_configuration_2dx;
 *                        C_set_VD_configuration_2dy;
 *                        C_set_VD_configuration_3dx;
 *                        C_set_VD_configuration_3dy;
 *                        C_set_VD_configuration_3dz;
 *                        C_set_VD_configuration_ori;
 *                        C_set_VD_configuration_oriazi;
 *                        C_set_VD_configuration_oriele;
 *                        C_set_VD_configuration_orirol;
 *          Return Value: void 
 *       Input Variables: 
 *      Output Variables: The currently selected real device
 *      Update Variables: IDE_VD_configuration
 *      Global Variables: IDE_VD_configuration
 *           Description: Reconfigure the virtual device configuration
 */

void C_set_VD_configuration_2dx(value)
int *value;
{
  extern C_IDE_VD_configuration IDE_VD_configuration[C_MAX_VD_NUMBER];

  IDE_VD_configuration[vd_index].device_involved[ 
                  IDE_VD_configuration[vd_index].pos2dx]--;
  IDE_VD_configuration[vd_index].pos2dx = allocated_device;
  IDE_VD_configuration[vd_index].device_involved[ 
                  IDE_VD_configuration[vd_index].pos2dx]++;
  *value = allocated_device; 
}

void C_set_VD_configuration_2dy(value)
int *value;
{
  extern C_IDE_VD_configuration IDE_VD_configuration[C_MAX_VD_NUMBER];

  IDE_VD_configuration[vd_index].device_involved[
                   IDE_VD_configuration[vd_index].pos2dy]--;
  IDE_VD_configuration[vd_index].pos2dy = allocated_device;
  IDE_VD_configuration[vd_index].device_involved[
                   IDE_VD_configuration[vd_index].pos2dy]++;
  *value = allocated_device;
}

void C_set_VD_configuration_3dx(value)
int *value;
{
  extern C_IDE_VD_configuration IDE_VD_configuration[C_MAX_VD_NUMBER];

  IDE_VD_configuration[vd_index].device_involved[
                      IDE_VD_configuration[vd_index].pos3dx]--;
  IDE_VD_configuration[vd_index].pos3dx = allocated_device;
  IDE_VD_configuration[vd_index].device_involved[
                      IDE_VD_configuration[vd_index].pos3dx]++;
  *value = allocated_device;
}

void C_set_VD_configuration_3dy(value)
int *value;
{
  extern C_IDE_VD_configuration IDE_VD_configuration[C_MAX_VD_NUMBER];

  IDE_VD_configuration[vd_index].device_involved[
                      IDE_VD_configuration[vd_index].pos3dy]--;
  IDE_VD_configuration[vd_index].pos3dy = allocated_device;
  IDE_VD_configuration[vd_index].device_involved[
                      IDE_VD_configuration[vd_index].pos3dy]++;
  *value = allocated_device;
}

void C_set_VD_configuration_3dz(value)
int *value;
{
  extern C_IDE_VD_configuration IDE_VD_configuration[C_MAX_VD_NUMBER];

  IDE_VD_configuration[vd_index].device_involved[
                    IDE_VD_configuration[vd_index].pos3dz]--;
  IDE_VD_configuration[vd_index].pos3dz = allocated_device;
  IDE_VD_configuration[vd_index].device_involved[
                    IDE_VD_configuration[vd_index].pos3dz]++;
  *value = allocated_device;
}


void C_set_VD_configuration_ori(value)
int *value;
{
  extern C_IDE_VD_configuration IDE_VD_configuration[C_MAX_VD_NUMBER];
  IDE_VD_configuration[vd_index].device_involved[
                      IDE_VD_configuration[vd_index].ori]--;
  IDE_VD_configuration[vd_index].ori = allocated_device;
  IDE_VD_configuration[vd_index].device_involved[
                     IDE_VD_configuration[vd_index].ori]++;
  *value = allocated_device;
}


void C_set_VD_configuration_oriazi(value)
int *value;
{
  extern C_IDE_VD_configuration IDE_VD_configuration[C_MAX_VD_NUMBER];

  IDE_VD_configuration[vd_index].device_involved[
                     IDE_VD_configuration[vd_index].oriazi]--;
  IDE_VD_configuration[vd_index].oriazi = allocated_device;
  IDE_VD_configuration[vd_index].device_involved[
                     IDE_VD_configuration[vd_index].oriazi]++;
  *value = allocated_device;
}

void C_set_VD_configuration_oriele(value)
int *value;
{
  extern C_IDE_VD_configuration IDE_VD_configuration[C_MAX_VD_NUMBER];

  IDE_VD_configuration[vd_index].device_involved[
                     IDE_VD_configuration[vd_index].oriele]--;
  IDE_VD_configuration[vd_index].oriele = allocated_device;
  IDE_VD_configuration[vd_index].device_involved[
                     IDE_VD_configuration[vd_index].oriele]++;
  *value = allocated_device;
}

void C_set_VD_configuration_orirol(value)
int *value;
{
  extern C_IDE_VD_configuration IDE_VD_configuration[C_MAX_VD_NUMBER];

  IDE_VD_configuration[vd_index].device_involved[
                     IDE_VD_configuration[vd_index].orirol]--;
  IDE_VD_configuration[vd_index].orirol = allocated_device;
  IDE_VD_configuration[vd_index].device_involved[
                     IDE_VD_configuration[vd_index].orirol]++;
  *value = allocated_device;
}

/*        Global variable: selection_number
 *                         This variable keeps the currently selection which
 *                         is to be assigned event.
 */

static int        selection_number = -1;

/*
 *        Procedure Name: C_set_selection_number 
 *          Return Value: void
 *       Input Variables: the selection number
 *      Output Variables:
 *      Update Variables:
 *      Global Variables:
 *           Description: Set the selection number
 */

void C_set_selection_number(sel_number)
int      sel_number;
{
  selection_number = sel_number;
}

/*
 *        Procedure Name: C_set_selection_number
 *          Return Value: whether a selection number is selected 
 *       Input Variables: 
 *      Output Variables:
 *      Update Variables:
 *      Global Variables:
 *           Description: check whether a selection is waiting for assignment.

int C_check_selection_number()
{
  if (selection_number == -1) return(1);
  else                            return(0);      
}


        
/*          Global variable: IDE_current_VD_number
 *                            This variable keeps the current virtual device
 *                            number.
 */
int                 IDE_current_VD_number=0;

/*
 *        Procedure Name: C_VD_allocate
 *          Return Value:
 *       Input Variables: 
 *      Output Variables:
 *      Update Variables:
 *      Global Variables: IDE_VD_configuration
 *           Description: Pop up the virtual device allocation panel. (C code)
 *                        The function check whether a new virtual device is
 *                        added or just a exist virtual device is reconfigured. 
 */

int  C_VD_allocate(client_data, redisplay)
int  *client_data;
int  *redisplay;
{
     extern C_IDE_VD_configuration   IDE_VD_configuration[C_MAX_VD_NUMBER];

         if (*client_data == C_MAX_VD_NUMBER+1) 
          {
           if (IDE_current_VD_number == C_MAX_VD_NUMBER-1)  
              {
               printf(" Too many Virtual Device");
               return(0);
              }
               
           IDE_current_VD_number++;
           IDE_VD_change_mode = -1;
           IDE_VD_configuration[IDE_current_VD_number] =
           IDE_VD_configuration[IDE_DEFAULT];
           *client_data = IDE_current_VD_number;
           *redisplay = 1;
          }
 
         vd_index  = *client_data;
  
         if (IDE_VD_change_mode != -1) 
          {
             IDE_VD_change_mode = *client_data;
             return(0);
          }
 
         allocated_device = -1;
         return(1);
}


