/*
 * Program:
 *   clio.cpp
 * Summary:
 *   Experiments in visualizing page usage.
 * Authors:
 *   Samuel A. Rebelsky
 * Version:
 *   0.1 of July 2003.
 * Warning:
 *   The organization of this program is totally ad-hoc.
 */



/********************************************************/
/*                      Headers                         */
/*******************************************************/
int numSessions;
extern "C"{ //for C to C++ compatability
#include <stdlib.h>
#include "clio.h"
#include "cliographics.h"

//for glui
#include <string.h>
#include <GL/glut.h>
#include "/home/lindseyd/OPENGL/glui_v2_1_beta/glui.h"
}
/****************************************************/
/*                   Constants                      */
/****************************************************/

/* The initial width and height of the main widnow. */
#define WIDTH 1250
#define HEIGHT 800

/*different date selections, GLUI need numeric ID's*/
enum {DAY_ALL=500, DAY_60, DAY_30, DAY_7, DAY_1, DAY_OTHER};


/* Callback ID's - passed to control func, GLUI
   requires numerical ID's*/
enum {CHANGE_VISUALIZATION_ID=100, LOAD_SAVED_ID, SAVE_BUTTON_ID,DONE_BUTTON_ID
      , CHANGE_USER_1_ID,CHANGE_USER_2_ID,CHANGE_USER_3_ID, CHANGE_TIME_ID
      , TIME_BUTTON_ID, SAVE_MENU_ID};
enum {CLOSE_SAVE_SUCCESS_ID=600, CLOSE_SAVE_ERROR_ID,SAVE_MENU_BUTTON_ID
      , LOAD_MENU_ID, CLOSE_LOAD_ERROR_ID, TIME_ID, CHANGE_SESSION1_ID
, CHANGE_SESSION2_ID, CHANGE_SESSION3_ID, MULTIPLE_ID, SINGLE_ID};
#define SESSION_ID 900

char * session[5]={" ", "1","2","3","4"};


/**************************************************/
/*                   Globals                      */
/**************************************************/

int mainWin;		/* The id of the main window. */
int ww, wh;     /*The current width and height the window*/
int xtrans;	/* The amount translated in the X dimension. */
int ytrans;	/* The amount translated in the Y dimension. */
int ztrans;	/* The amount translated in the Z dimension. */

int num_users=1, num_sessions=1; /*number of users/sessions 
                                   currently visualized*/


/**************************************************/
/*              GLUI Controls                     */
/**************************************************/

/*Options for user interface attribute mapping*/
char *name[]= {" ", "Category", "URL", "Time Spent",
              "Time Accessed", "Session","Windows"};

/*Array of all students that have data*/
char *users[]= {" ", "Lindseyd", "Rebelsky", "Brantley", "Bearywes",
                "ToTue"};
/*Size of users*/
int numberOfStudents = 5;


bool occupied1=true, occupied2=false, occupied3=false,
  occupied4=true, occupied5=false, occupied6=false;

/*range of data to visualize*/
char start_time[sizeof(GLUI_String)]={"mm:dd:yyyy"};
char  end_time[sizeof(GLUI_String)]={"mm:dd:yyyy"};
char save_file_name[FILENAME_MAX];
char load_file_name[FILENAME_MAX];

/* "Live variables */
float scale = 1.0;
int   show_axes = 1;
int x_pos=0, y_pos=0, z_pos=0, w_pos=0, h_pos=0, d_pos=0, c_pos=0, s_pos=0, l_pos=0, t_pos=0;

/* Controls */
GLUI *glui, *glui2, *save_menu, *save_success, *save_error, *load_save, *glui_data,
  *error_load;
GLUI_RadioGroup *curr_vis_choices, *choose_times;
GLUI_Button *load_saved, *save_curr, *time_button, *done_button,
  *close_save_success, *close_save_error, *multiple, *single;
GLUI_Listbox *x_list, *y_list, *z_list, *w_list, 
  *h_list,*d_list, *c_list, *t_list, *l_list, *s_list, 
  *user1, *user2, *user3,*time_panel, *session_panel1,*session_panel2,
  *session_panel3 ;
GLUI_EditText *s_box, *e_box, *s_file, *l_file;

GLUI_Panel *multiple_session, *time_period;

/**************************************************/
/*           Rotation Matrices                    */
/**************************************************/
float view_rotate[16] = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
float obj_pos[] = { 0.0, 0.0, 0.0 };

/**************************************************/
/*           Lighting Attributes                  */
/**************************************************/
float light0_position[]= {0.0f,0.0f, 50.0f, 0.0f};
float light0_ambient[]= {0.0f, 0.0f, 0.0f, 1.0f};
float light0_diffuse[]= {1.0f,1.0f, 1.0f, 1.0f};
float light0_specular[]= {0.0, 0.0, 0.0, 1.0};

float light1_position[]={50,50,-50};
float light1_ambient[]= {0.0f, 0.0f, 0.0f, 1.0f};
float light1_diffuse[]= {1.0f,1.0f, 1.0f, 1.0f};
float light1_specular[]= {0.0, 0.0, 0.0, 1.0};

float light2_position[]={0,1,0};
float light2_ambient[]= {0.0f, 0.0f, 0.0f, 1.0f};
float light2_diffuse[]= {1.0f,1.0f, 1.0f, 1.0f};
float light2_specular[]= {0.0, 0.0, 0.0, 1.0};

/**************************************************/
/*           Material Attributes                  */
/**************************************************/
float mat_diff_amb[]= {0.0f, 0.0f, 0.0f, 1.0f};
float mat_emission[] = {0.3, 0.2, 0.2, 1.0};


/*************************************************/
/*         Function declarations                 */
/*************************************************/

/* GLUT CALLBACKS */


/* Display the current world. */
void display(void);

/* Handle keyboard input. */
void keyboard(unsigned char, int, int);

/* Handle a change in size to the window */
void resize(int, int);

/* Set up everything. */
void clioInit(void);

/* Set up GLUI Interface */
void setUpUserInterface(void);

/*control mouse events*/
void mouse(int button, int state, int x, int y);

/*control GLUI events*/
void control_cb(int ID);

/*control motion events*/
void motion(int x, int y);


/********************************************/
/*          Local Functions                 */
/********************************************/



void setNewAttributes();



/**********************************************/
/**********************************************/
/**********************************************/


/*******************************************/
/*                   Main                  */
/*******************************************/

int 
main (int argc, char **argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 
  glutInitWindowPosition(0,0);     
  glutInitWindowSize(WIDTH, HEIGHT);               
           
  mainWin = glutCreateWindow("Exploring Clio's Worlds"); 
  wh = glutGet(GLUT_WINDOW_HEIGHT);  
  ww = glutGet(GLUT_WINDOW_WIDTH); 
  
  clioInit();                                           
  
  glutDisplayFunc( display );

  GLUI_Master.set_glutReshapeFunc( resize );  
  GLUI_Master.set_glutKeyboardFunc( keyboard );
  GLUI_Master.set_glutSpecialFunc( NULL );
  GLUI_Master.set_glutMouseFunc( mouse );
  glutMotionFunc( motion );
  
  /****************************************/
  /*       Set up OpenGL lights           */
  /****************************************/                                       
  glShadeModel(GL_FLAT);              
  glEnable(GL_LIGHTING);
  
  //Automatically scales normal vectors to unit length
  glEnable(GL_NORMALIZE);
  
  //Enable light sources
  glEnable(GL_LIGHT0);
  glEnable(GL_LIGHT1);
  glEnable(GL_LIGHT2);
  
//   /******************************************************/
//   /*            Set up Material Properties              */
//   /******************************************************/
  glEnable(GL_COLOR_MATERIAL);
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_diff_amb);

  /***************************************************/
  /*            Enable z-buffering                   */
  /***************************************************/

  glEnable(GL_DEPTH_TEST);

  /***************************************************/
  /*       Set up user Interface controls            */
  /***************************************************/
  setUpUserInterface();
  
  // Register the idle callback with GLUI, *not* with GLUT 
  GLUI_Master.set_glutIdleFunc( NULL );
  
  glutMainLoop();
} //main


/*****************************************************/
/*              clioInit()                           */ 
/*****************************************************/

/*
 * Procedure:
 *   clioInit
 * Purpose:
 *   Initializes everything for this version of Clio 3D to work.
 */
void clioInit(void)
{
  glClearColor(0.0, 0.0, 0.0, 0.0); //clear to black

    //initial position of light source
  glLightfv(GL_LIGHT0, GL_POSITION, light0_position);

  //constant amount of light at every point
   glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
  
  //partially absorbed/ partially reflected
  glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);

  //direction of a perfect reflection
  glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
  //Need glOrtho here?
  
  glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
  glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
  glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
  glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular);

  
  glLightfv(GL_LIGHT1, GL_POSITION, light2_position);
  glLightfv(GL_LIGHT1, GL_AMBIENT, light2_ambient);
  glLightfv(GL_LIGHT1, GL_DIFFUSE, light2_diffuse);
  glLightfv(GL_LIGHT1, GL_SPECULAR, light2_specular);
  //sets viewport taking into account the submenu size
  int tx, ty,tw,th;
  GLUI_Master.get_viewport_area(&tx, &ty, &tw, &th);
  glViewport(tx, ty, tw,th);
  
  glMatrixMode(GL_PROJECTION);	//sets 'camera' or field of view matrix
  glLoadIdentity();		//loads current matrix

  glOrtho(0.0, 110.0,-10.0, 110.0, -10.0, 110.0); 
		
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  // Prepare test values
  //loadData(NULL);
  // Set up default visualization
  cityScape();

  glFinish();
} // clioInit



/******************************************/
/*         void display()                 */
/******************************************/

void display(void)
{
  //sets viewport taking into account the submenu size
  int tx, ty,tw,th;
  GLUI_Master.get_viewport_area(&tx, &ty, &tw, &th);


  int i,j,k,l;
  glClear(GL_COLOR_BUFFER_BIT);
  
 
  int user=1, session=1;
  for(l=1; l <= (num_users*num_sessions); l++){
    loadData(NULL);
    glViewport(tx,ty,(tw/num_users), (th/num_sessions));
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,110,-10,110,-10,110);
    
    tx += (tw/num_users);
    user += 1;
    
    if((l % num_users) == 0){
      ty += (th/num_sessions);
      tx = 0;
      session += 1;
      user = 1;
    }
  

  glMatrixMode(GL_MODELVIEW);
  
  
  glClear( GL_DEPTH_BUFFER_BIT);
  
  //draw user, session

  if (show_axes){
    glDisable(GL_LIGHTING);
    
    //PUSH*
    glPushMatrix();
    /*Scale axes*/
    glScalef( scale, scale, scale);

    /* Show X, Y, and Z axis (R,G,B) */
    glBegin(GL_LINES);
      glColor3f(1.0, 0.0, 0.0);
      glVertex3f(0.0, 0.0, 0.0);
      glVertex3f(500.0, 0.0, 0.0);
      
      glColor3f(0.0, 1.0, 0.0);
      glVertex3f(0.0, 0.0, 0.0);
      glVertex3f(0.0,  500.0, 0.0);
      
      glColor3f(0.0, 0.0, 1.0);
      glVertex3f(0.0, 0.0, 0.0);
      glVertex3f(0.0, 0.0, 500.0);
    glEnd();
    
    //POP*
    glPopMatrix();
    glEnable(GL_LIGHTING);
  }

  glMatrixMode( GL_MODELVIEW);
  glLoadIdentity();


  glTranslatef( 0.0, 0.0, -20.6f);
  glTranslatef( obj_pos[0], obj_pos[1], -obj_pos[2]);
   
  glMultMatrixf( view_rotate );

  glScalef( scale, scale, scale);
  
   /*allows lights to be transformed with objects*/
//   glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
//   glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
//   glLightfv(GL_LIGHT2, GL_POSITION, light2_position);

  //render objects using: translate, then draw, then pop

#ifdef BOXES
  for (i = 0; i <= 3; i++) {
    for (j = 0; j <= 3; j++) {
      for (k = 0; k <= 3; k++) {
        clioBox(1,MAXC,
                500-500*i, 500-500*j, 500-500*k,
                50, 50, 50);
      }
    }
  }
#endif /* BOXES */
  

  
  for (i = 0; i < numvisits; ++i) {
    clioBox(getColor(visits+i), getShade(visits+i),
            getX(visits+i), getY(visits+i), getZ(visits+i),
            getW(visits+i), getH(visits+i), getD(visits+i));
  } /* for */
  }
  glFinish();  
  glutSwapBuffers();
} //display



/*
 * Procedure:
 *   keyboard
 * Purpose:
 *   React to the user's choice of keyboard key.
 * Possibilities:
 *   ?? Need to think more about keyboard- make
 *   sure to sync the variables with the GLUI
 *   interface however!
 */
void keyboard(unsigned char key, int x, int y)
{

} // keyboard

/*********************************Resize Routines****************************/


void resize(int width, int height)
{
#ifdef RESIZE_CODE 
  GLUI_Master.auto_set_viewport();

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  if (ww <= wh)
    glOrtho(0, 110, 
            -10 * wh/ ww, 110* wh/ww,
            -10 * wh/ ww, 110* wh/ww);
  else
    glOrtho(0, 110, 
            -10 * ww/ wh, 110* ww/wh,
            -10 * ww/ wh, 110* ww/wh);
 
  
  glMatrixMode(GL_MODELVIEW);
#endif /* RESISE_CODE */

  ww = width;
  wh = height;
} // resize



/****************************Control Functions*******************************/
void mouse(int button, int state, int x, int y)
{
}

void control_cb(int ID)
{
  switch(ID){
  

  case CHANGE_VISUALIZATION_ID:
    fprintf(stderr, "CHANGE TO: %d", curr_vis_choices->get_int_val());
    switch(curr_vis_choices->get_int_val()){
    case 0:
      load_saved->disable();
      //Boxes in Space
      boxesInSpace();
      break;
    case 1:
      load_saved->disable();
      //City Scape
      cityScape();
      glutPostRedisplay();
      break;
    case 2:
      load_saved->disable(); 
      categories();

      glutPostRedisplay();
      break;
    case 3:
      //Enable Load Saved Button
      load_saved->enable();
      break;
    }
    glutPostRedisplay();
    break;
  


  case LOAD_SAVED_ID:
    //load saved id
    load_save->show();
    break;
  
  case LOAD_MENU_ID:
    fprintf(stderr, "FILE NAME TO RECOVER: %s\n",
            load_file_name);
    get_from_file(load_file_name);
    l_file->set_text(" ");
    load_save->hide();
    glutPostRedisplay();
    break;
    
  case CLOSE_LOAD_ERROR_ID:
    error_load->hide();
    break;
 
  case DONE_BUTTON_ID:
    //when done setting attributes, display them
    setNewAttributes();
    glutPostRedisplay();
    break;
  
  case SAVE_BUTTON_ID:
    //save current attributes
    save_menu->show();
    break;

  case SAVE_MENU_ID:
    int ok;
    fprintf(stderr, "File Name to Save: %s\n", 
            save_file_name);
    ok = write_to_file(save_file_name);
    
    s_file->set_text(" ");
    
    if (ok == 0)
      save_success->show();
    else
      save_error->show();
    save_menu->hide();
    glutPostRedisplay();
      break;
    
  case CLOSE_SAVE_SUCCESS_ID:
    save_success->hide();
    break;
  case CLOSE_SAVE_ERROR_ID:
    save_error->hide();

  case CHANGE_USER_1_ID:
    //get different data
    //position on screen
    if((user1->get_int_val()) == 300){
      num_users--;
      occupied1= false;
    }
    else{ 
      if(!occupied1)
        num_users++;
      occupied1= true;
    }
    

    glutPostRedisplay();
    break;
  
  case CHANGE_USER_2_ID:
    //get different data
    //position on screen
    if((user2->get_int_val()) == 300){
      num_users--;
      occupied2= false;
    }
    else{ 
      if(!occupied2)
        num_users++;
      occupied2= true;
    }
  
    glutPostRedisplay();
    break;
    
  case CHANGE_USER_3_ID:
    //get different data
    //position on screen
    if((user3->get_int_val()) == 300){
      num_users--;
      occupied3= false;
    }
    else{ 
      if(!occupied3)
        num_users++;
      occupied3= true;
    }
 
    glutPostRedisplay();
    break;

  case CHANGE_SESSION1_ID:
    if((session_panel1->get_int_val())== SESSION_ID)
      if(occupied4){
        num_sessions--;
        occupied4=false;
      }
      else
        ;
    else {
      if(!occupied4)
        num_sessions++;
      occupied4=true;
    }
    glutPostRedisplay();
    break;

  case CHANGE_SESSION2_ID:
    if((session_panel2->get_int_val())== SESSION_ID)
      if(occupied5){
        num_sessions--;
        occupied5=false;
      }
      else
        ;
    else {
      if(!occupied5)
        num_sessions++;
      occupied5=true;
    }
    glutPostRedisplay();
    break;

    case CHANGE_SESSION3_ID:
    if((session_panel3->get_int_val())== SESSION_ID)
      if(occupied6){
        num_sessions--;
        occupied6=false;
      }
      else
        ;
    else {
      if(!occupied6)
        num_sessions++;
      occupied6=true;
    }
    glutPostRedisplay();
    break;


  case CHANGE_TIME_ID:
    s_box->disable();
    e_box->disable();

    switch(time_panel->get_int_val()){
    case DAY_ALL:
      break;
    case DAY_60:
      break;
    case DAY_30:
      break;
    case DAY_7:
      break;
    case DAY_1:
      break;
    case DAY_OTHER:
      s_box->enable();
      e_box->enable();
      time_button->enable();
      break;
    }
    break;

  case TIME_BUTTON_ID:
    //read e_box
    //read s_box
    //get new data
    fprintf(stderr, "Start time: %s\n End Time %s\n", 
            start_time, end_time);
    glutPostRedisplay();

    break;
  
  case SINGLE_ID:
    num_sessions=1;
    multiple_session->disable();
    multiple->enable();
    time_period->enable();
    break;
  case MULTIPLE_ID:
    time_period->disable();
    single->enable();
    multiple_session->enable();
    //need to restore correct num_sessions
    //currently will be set at 1, since the time
    //period always shows one session
    
    //if the first slot is empty, so far have 0 sessions,
    if((session_panel1->get_int_val()) == SESSION_ID) 
      num_sessions--;
    //if the other slots are full, add one to number of sessions
    if ((session_panel2->get_int_val() != SESSION_ID))
      num_sessions++;
    if((session_panel3->get_int_val() != SESSION_ID))
      num_sessions++; 
    break;
  }
}

void motion(int x, int y)
{
}

/*****************************HELPER FUNCTIONS*****************************/
/*
 * Given the name of a standard "continuous" function as a string, 
 * return that function.
 *   Returns NULL if the name is not known.  Clever programmers
 * check the return value.
 */
void setNewAttributes(){

  getX= getContinuousFunction(name[(-200+x_pos)]);
  if(getX==NULL)
    getX= getConstant5C;

  getY= getContinuousFunction(name[(-200+y_pos)]);
  if(getY==NULL)
    getY= getConstant5C;

  getZ= getContinuousFunction(name[(-200+z_pos)]);
  if(getZ==NULL)
    getZ= getConstant5C;

  getW= getContinuousFunction(name[(-200+w_pos)]);
  if(getW== NULL)
    getW= getConstant5C;

  getH= getContinuousFunction(name[(-200+h_pos)]);
  if(getH== NULL)
    getH= getConstant5C;

  getD= getContinuousFunction(name[(-200+d_pos)]);   
  if(getD==NULL)
    getD= getConstant5C;

  getColor= getDiscreteFunction(name[(-200+c_pos)]);
  if(getColor== NULL)
    getColor= getTypeD;

  getShape= getDiscreteFunction(name[(-200+s_pos)]);
  if(getShape== NULL)
    getShape= getTypeD;
  
//   fprintf(stderr, "Category, %s", name[1]);
//   fprintf(stderr, "x_pos %d", x_pos);
//  getX= getContinuousFunction(name[(x_pos-200)]);
  //getShade not implemented
  // getShade= getConstant100C;
}


//Color and SHape should not have URL Option
//Session,  " " not implemented
discrete
getDiscreteFunction(char *name1)
{
  if ((0 == strcasecmp(name1, "Time Spent")) ||
      (0 == strcasecmp(name1, "getLength")) ) {
    return getLengthD;
  }
  else if ((0 == strcasecmp(name1, "Time Accessed")) ||
           (0 == strcasecmp(name1, "getStart"))){
    return getStartD;
  }
  
  else if ((0 == strcasecmp(name1, "Category")) ||
           (0 == strcasecmp(name1, "getType"))){
    return getTypeD;
  }
  else if ((0 == strcasecmp(name1, "Windows")) ||
           (0 == strcasecmp(name1, "getUWS"))){
    return getUWSD;
  }
  else if (0 == strcasecmp(name1, "getConstant0")){
    return getConstant0D;
  }
  else if (0 == strcasecmp(name1, "getConstant5")){
    return getConstant5D;
  }
  else if (0 == strcasecmp(name1,"getConstant10")){
    return getConstant10D;
  }
  else if (0 == strcasecmp(name1,"getConstant100")){
    return getConstant100D;
  }
  else {
    return NULL;
  }
} /* getDiscreteFunction */

continuous
getContinuousFunction(char *name1) 
{
  if ((0 == strcasecmp(name1, "Time Spent"))||
      (0 == strcasecmp(name1, "getLength"))){
    return getLengthC;
  }
  else if ((0 == strcasecmp(name1, "Time Accessed"))||
      (0 == strcasecmp(name1, "getStart"))){
    return getStartC;
  }
  else if ((0 == strcasecmp(name1, "URL"))||
      (0 == strcasecmp(name1, "getPage"))){
    return getPageC;
  }
  else if ((0 == strcasecmp(name1, "Category"))||
      (0 == strcasecmp(name1, "getType"))){
    return getTypeC;
  }
  else if ((0 == strcasecmp(name1, "Windows"))||
      (0 == strcasecmp(name1, "getUWS"))){
    return getUWSC;
  }
  else if (0 == strcasecmp(name1, "getConstant0")){
    return getConstant0C;
  }
  else if (0 == strcasecmp(name1, "getConstant5")){
    return getConstant5C;
  }
  else if (0 == strcasecmp(name1,"getConstant10")){
    return getConstant10C;
  }
  else if (0 == strcasecmp(name1,"getConstant100")){
    return getConstant100C;
  }
  else {
    return  NULL;
  }
} /* getContinuousFunction */

/*
 * Given one of the standard "continuous" function, return the name 
 * of that function.
 */
char *
getContinuousName(continuous c)
{
  if (c == getLengthC) {
    return "getLength";
  }
  else if (c == getStartC) {
    return "getStart";
  }
  else if (c == getTypeC) {
    return "getType";
  }
  else if (c == getPageC){
    return "getPage";
  }
  else if (c == getUWSC){
    return "getUWS";
  }
  else if (c == getConstant0C){
    return "getConstant0";
  }
  else if (c == getConstant5C){
    return "getConstant5";
  }
  
  else if (c == getConstant10C){
    return "getConstant10";
   }
  else if (c == getConstant100C){
    return "getConstant100";
  }
  else {
    return "getSomething";
  }
} // getContinuousName(continuous c)

char *
getDiscreteName(discrete c)
{
  if (c == getLengthD) {
    return "getLength";
  }
  else if (c == getStartD) {
    return "getStart";
  }
  else if (c == getTypeD) {
    return "getType";
  }
 
  else if (c == getUWSD){
    return "getUWS";
  }
  else if (c == getConstant0D){
    return "getConstant0";
  }
  else if (c == getConstant5D){
    return "getConstant5";
  }
  
  else if (c == getConstant10D){
    return "getConstant10";
   }
  else if (c == getConstant100D){
    return "getConstant100";
  }
  else {
    return "getSomething";
  }
} // getDiscreteName(continuous c)



/* Notes: Possibly want to compare either
 * 1) different students during different times
 * 2) same student during different times
 */

/*****************************************************/
/*               setUpUserInterface()                */
/*****************************************************/

/*
 * Procedure:
 *     setUpUserInterface()
 * Purpose:
 *     Sets up the GLUI user interface user in Clio 3D
 *     and establishes the call back fuctions or "live
 *     variables" used to react to user input
 */

void setUpUserInterface(void)
{
  numSessions= 5; //how??
  /*counter variable*/
  int i;
  /*****************************************************/
  /*              GLUI Floating Panel                  */
  /*****************************************************/
 
   glui = GLUI_Master.create_glui_subwindow(mainWin, GLUI_SUBWINDOW_RIGHT);
//glui = GLUI_Master.create_glui("");

  GLUI_Rollout *nav= glui->add_rollout("Navigation Controls"); 
  
  GLUI_Rotation *rotation= glui->add_rotation_to_panel(nav,"Rotation",
                                                       view_rotate); 
  // glui->add_column_to_panel(nav, false);

 
  GLUI_Translation *xy= glui->add_translation_to_panel(nav,"Translation",
                                                       GLUI_TRANSLATION_XY, 
                                                       obj_pos);
  // glui->add_column_to_panel(nav, false);

  GLUI_Translation *z = 
    glui->add_translation_to_panel(nav,"Zoom", GLUI_TRANSLATION_Z, 
                                   &obj_pos[2]);

  z->set_speed( 5);
  // glui->add_column_to_panel(nav, false);

  GLUI_Spinner *scale_spinner = 
    glui->add_spinner_to_panel( nav, "Scale:",
				GLUI_SPINNER_FLOAT, &scale);
  scale_spinner->set_float_limits( .2f, 4.0 );
  scale_spinner->set_alignment( GLUI_ALIGN_LEFT );


  glui->add_checkbox_to_panel( nav, "Draw axes", &show_axes );



  
 
  glui->set_main_gfx_window(mainWin);

  /*****************************************************/
  /*              GLUI Bottom Panel                    */
  /*****************************************************/
  
   glui2 = GLUI_Master.create_glui_subwindow( mainWin,
                                            GLUI_SUBWINDOW_BOTTOM );
 
    //    glui2 = GLUI_Master.create_glui("Visualization Attributes" );

   /***************************************/
  /*   Current Visualization Selection    */
  /****************************************/
  GLUI_Rollout *currVisSelection = 
    glui2->add_rollout("Current Visualization");

  curr_vis_choices=
    glui2->add_radiogroup_to_panel(currVisSelection,
                                  NULL,CHANGE_VISUALIZATION_ID,control_cb);
  glui2->add_radiobutton_to_group( curr_vis_choices, "Boxes in Space" );
  glui2->add_radiobutton_to_group( curr_vis_choices, "City Scape" );
  glui2->add_radiobutton_to_group( curr_vis_choices, "Categories");

  glui2->add_radiobutton_to_group( curr_vis_choices, "Other" );
    
  load_saved =
    glui2->add_button_to_panel(currVisSelection, "Load Saved", 
                               LOAD_SAVED_ID, control_cb);
  load_saved->disable();					     
     glui2->add_column(false);
 
  /***************************************/
  /*     Visualization Attributes        */
  /***************************************/
  

  GLUI_Rollout *currVisAttributes =
    glui2->add_rollout("Visualization Attributes");
  
  x_list = glui2->add_listbox_to_panel(currVisAttributes, "X Position",
                                       &x_pos);
  for(i=0; i < 7; ++i)
    x_list->add_item(200+i,name[i]);
  //default is city scape
  x_list->set_int_val(7);
      
  y_list = glui2->add_listbox_to_panel(currVisAttributes, "Y Position",
                                       &y_pos);
  for(i=0; i < 7; ++i)
    y_list->add_item(200+i,name[i]);
  y_list->set_int_val(4);

  z_list = glui2->add_listbox_to_panel(currVisAttributes, "Z Position",
                                       &z_pos);

  for(i=0; i < 7; ++i)
    z_list->add_item(200+i,name[i]);
  z_list->set_int_val(0);

  w_list = glui2->add_listbox_to_panel(currVisAttributes, "Width",
                                       &w_pos);
  for(i=0; i < 7; ++i)
    w_list->add_item(200+i,name[i]);
  w_list->set_int_val(0);

  glui2->add_column_to_panel(currVisAttributes,false);


  h_list = glui2->add_listbox_to_panel(currVisAttributes, "Height",
                                      &h_pos);
  for(i=0; i < 7; ++i)
    h_list->add_item(200+i,name[i]);
  h_list->set_int_val(3);
  

  d_list = glui2->add_listbox_to_panel(currVisAttributes, "Depth",
                                       &d_pos);
  
  for(i=0; i < 7; ++i)
    d_list->add_item(200+i,name[i]);
  d_list->set_int_val(3);

  c_list = glui2->add_listbox_to_panel(currVisAttributes, "Color",
                                       &c_pos);
  for(i=0; i < 7; ++i)
    c_list->add_item(200+i,name[i]);
  

  t_list = glui2->add_listbox_to_panel(currVisAttributes, "Texture",
                                       &t_pos);
  for(i=0; i < 7; ++i)
    t_list->add_item(200+i,name[i]);

  glui2->add_column_to_panel(currVisAttributes,false);


  l_list = glui2->add_listbox_to_panel(currVisAttributes, "Lighting",
                                      &l_pos);
  for(i=0; i < 7; ++i)
    l_list->add_item(200+i,name[i]);
  


  s_list = glui2->add_listbox_to_panel(currVisAttributes, "Shape",
                                      &s_pos);
  for(i=0; i < 7; ++i)
    s_list->add_item(200+i,name[i]);
  glui2->add_separator_to_panel(currVisAttributes);
  
  done_button =
    glui2->add_button_to_panel(currVisAttributes, "Done",
                               DONE_BUTTON_ID, control_cb);
  save_curr =
    glui2->add_button_to_panel(currVisAttributes, "Save Current Settings",
                               SAVE_BUTTON_ID, control_cb);

  glui2->add_column(false);
  glui2->set_main_gfx_window( mainWin );
  
  //glui_data = GLUI_Master.create_glui_subwindow(mainWin, GLUI_SUBWINDOW_RIGHT );
  GLUI_Rollout *dataSelect = 
    glui2->add_rollout("Data Selection");

  /***************************************/
  /*      Current Student Selection      */
  /***************************************/
  GLUI_Panel *currStudents = 
    glui2->add_panel_to_panel(dataSelect, "Students");
  
  /*callback id's for list of students = 300 + position 
    in array*/
  user1 = 
    glui2->add_listbox_to_panel(currStudents, "Student 1", NULL
                               ,CHANGE_USER_1_ID, control_cb);
  user1->add_item(301, users[1]);
  for(i=0; i < numberOfStudents; ++i){
    if(i == 1)
      ;
    else
      user1->add_item(300+i, users[i]); 
  }
  user2 = glui2->add_listbox_to_panel(currStudents, "Student 2", NULL
                               ,CHANGE_USER_2_ID, control_cb);
  for(i=0; i < numberOfStudents; ++i)
    user2->add_item(300+i, users[i]); 


 user3 = glui2->add_listbox_to_panel(currStudents, "Student 3", NULL
                               ,CHANGE_USER_3_ID, control_cb);
  for(i=0; i < numberOfStudents; ++i)
    user3->add_item(300+i, users[i]); 
  
  glui2->add_column_to_panel(dataSelect,false);
  
  

  GLUI_Panel *timeSelect=
    glui2->add_panel_to_panel(dataSelect, "Times");
  
  time_period=
      glui2->add_panel_to_panel(timeSelect, "", GLUI_PANEL_NONE);

  single =
    glui2->add_button_to_panel(time_period, "Time Period", SINGLE_ID,
                               control_cb);


  time_panel =
    glui2->add_listbox_to_panel(time_period, "Select Time", NULL,
                               CHANGE_TIME_ID, control_cb);
  time_panel->add_item(DAY_ALL, "All");
  time_panel->add_item(DAY_60,"Last 60 days");
  time_panel->add_item(DAY_30,"Last 30 days");
  time_panel->add_item(DAY_7,"Last week");
  time_panel->add_item(DAY_1,"Today only");
  time_panel->add_item(DAY_OTHER, "Other");

  s_box=
    glui2->add_edittext_to_panel(time_period, "Start time",
                                 GLUI_EDITTEXT_TEXT, &start_time); 
  s_box->set_w( 150 );
  s_box->disable();

  e_box=
    glui2->add_edittext_to_panel(time_period, "End time",
                                 GLUI_EDITTEXT_TEXT, &end_time); 
  e_box->set_w( 150 );
  e_box->disable();

  time_button =
    glui2->add_button_to_panel(time_period, "Ok",
                               TIME_BUTTON_ID, control_cb);
  time_button->disable();
  
  glui2->add_column_to_panel(timeSelect,false);

  multiple_session =
    glui2->add_panel_to_panel(timeSelect, "",GLUI_PANEL_NONE);
  
  multiple =
    glui2->add_button_to_panel(multiple_session, "Multiple Sessions", 
                               MULTIPLE_ID, control_cb);
  
  session_panel1=
    glui2->add_listbox_to_panel(multiple_session, "Select Session 1:", NULL, 
                                CHANGE_SESSION1_ID, control_cb);
  session_panel1->add_item(SESSION_ID+1, session[1]);
  for(int i=0; i < numSessions; i++){
    if(i == 1 )
      ;
    else
      session_panel1->add_item(SESSION_ID+i, session[i]);
  }
 session_panel2=
    glui2->add_listbox_to_panel(multiple_session, "Select Session 2:", NULL, 
                                CHANGE_SESSION2_ID, control_cb);
  for(int i=0; i < numSessions; i++){
    session_panel2->add_item(SESSION_ID+i, session[i]);
  }
 session_panel3=
    glui2->add_listbox_to_panel(multiple_session, "Select Session 3:", NULL, 
                                CHANGE_SESSION3_ID, control_cb);
  for(int i=0; i < numSessions; i++){
    session_panel3->add_item(SESSION_ID+i, session[i]);
  }

  glui2->set_main_gfx_window( mainWin );


  multiple_session->disable();
  multiple->enable();
  /***************************************/
  /*                Save File            */
  /***************************************/
   save_menu = GLUI_Master.create_glui("save");
   s_file =
     save_menu->add_edittext("Save As:", GLUI_EDITTEXT_TEXT, &save_file_name);
   s_file->set_w(150);
   save_menu->add_button("OK",SAVE_MENU_ID, control_cb);
  
   save_menu->set_main_gfx_window( mainWin );
   save_menu->hide();

  /***************************************/
  /*         Success File Save           */
  /***************************************/
   save_success = GLUI_Master.create_glui("" );
   save_success->add_statictext("Settings Successfully Saved");
   save_success->add_button("OK", CLOSE_SAVE_SUCCESS_ID, control_cb);
   save_success->set_main_gfx_window( mainWin );
   save_success->hide();
   
  /***************************************/
  /*          Error File Save            */
  /***************************************/
   save_error = GLUI_Master.create_glui("");
   save_error->add_statictext("Error: Settings NOT saved");
   save_error->add_button("OK", CLOSE_SAVE_ERROR_ID, control_cb);
   
   save_error->set_main_gfx_window( mainWin );
   save_error->hide();

   /***************************************/
   /*                Load File            */
  /***************************************/
   load_save = GLUI_Master.create_glui("Load Saved Settings");
   l_file=
     load_save->add_edittext("File Name: ", GLUI_EDITTEXT_TEXT, 
                             &load_file_name);
   s_file->set_w(150);
   load_save->add_button("OK", LOAD_MENU_ID, control_cb);

   load_save->set_main_gfx_window( mainWin);
   load_save->hide();
   
   /***************************************/
   /*          Error Load File            */
  /***************************************/
   error_load = GLUI_Master.create_glui("404");
   error_load->add_statictext("File not found");
   error_load->add_button("OK", CLOSE_LOAD_ERROR_ID, control_cb);
   error_load->set_main_gfx_window(mainWin);
   error_load->hide();

}  
void error_load_save(void)
{
  error_load->show();
}

