/****************************************************************************/
/*                                                                          */
/*  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: ivi_ui.c
 *		      Author: Lisa Sobierajski 
 *			Date: 03/07/92
 *		 Description: Motif Windowing Routines Of The Image Control 
 *	Modification History:
 *
 *		Who?		When?		Why?
 *	--------------------------------------------------------------------
 *
 */

#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <Xm/Xm.h>
#include <Xm/RowColumn.h>
#include <Xm/PushB.h>
#include <Xm/PushBG.h>
#include <Xm/BulletinB.h>
#include <Xm/LabelG.h>
#include <Xm/Text.h>
#include <Xm/TextF.h>
#include <Xm/DrawingA.h>
#include <Xm/Frame.h>

#include "C_volvis.h"
#include "MOTIF_windefs.h"
#include "C_help.h"

void ivi_active_opt_callback();

/* Global Variables For Motif Windowing */
extern Widget		vv_toplevel;	/* Bulletin Board Dialog */
extern Widget		ivi_bbdialog;	/* Bulletin Board Dialog */
extern Widget		ivi_pulldown;
extern Widget		ivi_active_opt[C_MAX_IMAGES];
extern C_WindowDefs	window_defs;

extern C_ImageTable	image_table;

Widget		ivi_option_menu;
Widget		ivi_rowcolumn;

typedef struct		
{
	Widget	info_frame;
	Widget	button_frame;
	int	move_up_amount;
} C_IviToggleInfo;
	
create_ivi_window()
{
	extern void	close_callback();
	extern void	help_callback();

	void		ivi_display_callback();
	void		ivi_delete_callback();

	Arg		args[20];	/* Argument List */
	int		n;		/* Argument Count */
	Widget		ivi_display_button;
	Widget		ivi_delete_button;
	Widget		ivi_help_button;
	Widget		ivi_close_button;
	XmString	ivi_string;
	int		i;

	/********************************************************/		
	/* Create The Image Control Bulletin Board		*/
	/********************************************************/		
	n=0;
	XtSetArg( args[n], XmNx, 0 ); n++;
	XtSetArg( args[n], XmNy, 0 ); n++;
	XtSetArg( args[n], XmNautoUnmanage, False ); n++;
	C_Set_Color_Dialog( args, n, window_defs );
	ivi_bbdialog = XmCreateBulletinBoardDialog( vv_toplevel,
		       "Image Control", args, n );

	/********************************************************/		
	/*	Create a RowColumn for Active Image		*/
	/********************************************************/		
        n = 0;
	C_Set_Color_RowColumn( args, n, window_defs );
        ivi_rowcolumn = 
		XmCreateRowColumn(ivi_bbdialog, "ivi_rowcolumn", args, n);
        XtManageChild (ivi_rowcolumn);
	
	/********************************************************/		
	/*	Create a Pulldown Selection for Active Image	*/
	/********************************************************/		
        n = 0;
	C_Set_Color_PullDown( args, n, window_defs );
        ivi_pulldown = 
		XmCreatePulldownMenu(ivi_rowcolumn, "ivi_pulldown", args, n);

	if (image_table.num_images == 0)
	{
		
            n = 0;
            ivi_string = XmStringCreate ("No Images!!!",
			XmSTRING_DEFAULT_CHARSET);
            XtSetArg (args[n], XmNlabelString, ivi_string); n++;
            ivi_active_opt[0] = 
		XmCreatePushButtonGadget(ivi_pulldown,
			"No Images!!!", args, n);
            XmStringFree (ivi_string);

            XtAddCallback (ivi_active_opt[0], XmNactivateCallback,
                           ivi_active_opt_callback, -1);

            XtManageChildren (ivi_active_opt, 1);
	}
	else
	{
          for (i=0; i<image_table.num_images; i++)
          {
            n = 0;
            ivi_string = XmStringCreate (image_table.image_entry[i]->image_name,
			XmSTRING_DEFAULT_CHARSET);
            XtSetArg (args[n], XmNlabelString, ivi_string); n++;
            ivi_active_opt[i] = 
		XmCreatePushButtonGadget(ivi_pulldown,
			image_table.image_entry[i]->image_name, args, n);
            XmStringFree (ivi_string);

            XtAddCallback (ivi_active_opt[i], XmNactivateCallback,
                           ivi_active_opt_callback, i);

          }

          XtManageChildren (ivi_active_opt, image_table.num_images);
	}

	/********************************************************/		
	/*	Create An Option Menu, And Attach The Pulldown	*/
	/********************************************************/		

        n = 0;
        ivi_string = XmStringCreate ("Active Image:", XmSTRING_DEFAULT_CHARSET);
        XtSetArg (args[n], XmNlabelString, ivi_string); n++;
        XtSetArg (args[n], XmNsubMenuId, ivi_pulldown); n++;
	C_Set_Color_OptionMenu( args, n, window_defs );
	if (image_table.active_image >= 0)
	{
		XtSetArg( args[n], XmNmenuHistory, 
			  ivi_active_opt[image_table.active_image]); n++;
	}
	else 
	{
		XtSetArg (args[n], XmNmenuHistory, ivi_active_opt[0]); n++;
	}
        ivi_option_menu = XmCreateOptionMenu(ivi_rowcolumn, 
				"ivi_option_menu", args, n);

        XtManageChild(ivi_option_menu);


	/************************************************/
	/*     Create The Display  Button		*/
	/************************************************/
	n=0;
	XtSetArg( args[n], XmNx, 10 ); n++;
	XtSetArg( args[n], XmNy, 60 ); n++;
	C_Set_Color_Button( args, n, window_defs );
	ivi_display_button = XtCreateManagedWidget( "Display", 
		xmPushButtonWidgetClass, ivi_bbdialog, args, n );
	XtAddCallback( ivi_display_button, XmNactivateCallback, 
		       ivi_display_callback, NULL );	

	

	/************************************************/
	/*     Create The Delete  Button		*/
	/************************************************/
	n=0;
	XtSetArg( args[n], XmNx, 110 ); n++;
	XtSetArg( args[n], XmNy, 60 ); n++;
	C_Set_Color_Button( args, n, window_defs );
	ivi_delete_button = XtCreateManagedWidget( "Delete ", 
		xmPushButtonWidgetClass, ivi_bbdialog, args, n );
	XtAddCallback( ivi_delete_button, XmNactivateCallback,
		       ivi_delete_callback, NULL );

	/************************************************/
	/*     Create The Close Button			*/
	/************************************************/
	n=0;
	XtSetArg( args[n], XmNx, 210 ); n++;
	XtSetArg( args[n], XmNy, 60 ); n++;
	C_Set_Color_Button( args, n, window_defs );
	ivi_close_button = XtCreateManagedWidget( " Close ", 
		xmPushButtonWidgetClass, ivi_bbdialog, args, n );
	XtAddCallback( ivi_close_button, XmNactivateCallback,
		       close_callback, ivi_bbdialog );

	/************************************************/
	/*     Create The Help Button			*/
	/************************************************/
	n=0;
	XtSetArg( args[n], XmNx, 310 ); n++;
	XtSetArg( args[n], XmNy, 60 ); n++;
	C_Set_Color_Button( args, n, window_defs );
	ivi_help_button = XtCreateManagedWidget( " Help  ", 
		xmPushButtonWidgetClass, ivi_bbdialog, args, n );
	XtAddCallback( ivi_help_button, XmNactivateCallback,
		       help_callback, C_IVI_HELP );

}

void ivi_delete_callback( w, client_data, call_data )
Widget          w;
XtPointer       client_data;
XtPointer       call_data;
{
	int loop;
	extern void	image_expose_callback();

	if ( image_table.active_image >= 0 )
	{
	    if ( image_table.image_entry[image_table.active_image]->parent_win )
			XtDestroyWidget( image_table.image_entry[
				image_table.active_image]->parent_win );

	    for ( loop = image_table.active_image + 1; 
		  loop < image_table.num_images; loop++ )
	    {
		XtRemoveCallback( 
		  image_table.image_entry[loop]->ui_win,
		  XmNexposeCallback, image_expose_callback, loop );
		XtAddCallback( 
		  image_table.image_entry[loop]->ui_win,
		  XmNexposeCallback, image_expose_callback, loop-1 );
	    }
		
	    C_delete_image( &image_table, image_table.active_image );
	}
}


void ivi_active_opt_callback( w, client_data, call_data )
Widget          w;
int             client_data;
caddr_t         call_data;
{
        printf("Client data is: %d\n",client_data);
	image_table.active_image = client_data;
}

void update_ivi_active_opt()
{
	Arg		args[10];	
	int		n;	
	int		loop;
	XmString	ivi_string;
	int		i;

	for (loop=0; loop<C_MAX_IMAGES; loop++)
	{
		if ( ivi_bbdialog )
		{
			if (ivi_active_opt[loop])
			{
			    XtDestroyWidget( ivi_active_opt[loop] ); 	
			    ivi_active_opt[loop] = NULL;
			}
		}
		else ivi_active_opt[loop] = NULL;
		
	}


	if (ivi_bbdialog)
	{	

	  if (image_table.num_images == 0)
	  {
            n = 0;
            ivi_string = XmStringCreate ("No Images!!!",
			XmSTRING_DEFAULT_CHARSET);
            XtSetArg (args[n], XmNlabelString, ivi_string); n++;
            ivi_active_opt[0] = 
		XmCreatePushButtonGadget(ivi_pulldown,
			"No Images!!!", args, n);
            XmStringFree (ivi_string);

            XtAddCallback (ivi_active_opt[0], XmNactivateCallback,
                           ivi_active_opt_callback, -1);

	    XtManageChild(ivi_active_opt[0]);
	  }
	  else
	  {
            for (i=0; i<image_table.num_images; i++)
            {
              n = 0;
              ivi_string= XmStringCreate(image_table.image_entry[i]->image_name,
			XmSTRING_DEFAULT_CHARSET);
              XtSetArg (args[n], XmNlabelString, ivi_string); n++;
              ivi_active_opt[i] = 
		XmCreatePushButtonGadget(ivi_pulldown,
			image_table.image_entry[i]->image_name, args, n);
              XmStringFree (ivi_string);

	      XtManageChild( ivi_active_opt[i] );

              XtAddCallback (ivi_active_opt[i], XmNactivateCallback,
                           ivi_active_opt_callback, i);

            }

	  }


	  if (image_table.active_image >= 0)
	  {
	    	n = 0;
	    	XtSetArg( args[n], XmNmenuHistory, 
			  ivi_active_opt[image_table.active_image]); n++;
        	XtSetArg (args[n], XmNsubMenuId, ivi_pulldown); n++;
	    	XtSetValues( ivi_option_menu, args, n );
	  }
	  else
	  {
	    	n = 0;
	    	XtSetArg( args[n], XmNmenuHistory, 
			  ivi_active_opt[0]); n++;
        	XtSetArg (args[n], XmNsubMenuId, ivi_pulldown); n++;
	    	XtSetValues( ivi_option_menu, args, n );
	  }


	}


}


void create_ivi_display_window(image_num)
int		image_num;
{
	extern void	ivi_setup_drawing_area();
	extern void	close_callback();
	extern void	image_close_callback();
	void		image_expose_callback();
	void		ivi_toggle_callback();

	Arg		args[20];	/* Argument List */
	int		n;		/* Argument Count */

	Widget		active_image_label;
	Widget		draw_frame;
	Widget		frame;
	Widget		info_frame;
	Widget		rowcolumn;
	Widget		button;
	Widget		display_bbdialog;
	Widget		drawing_area;
	Widget		label;
	Widget		bboard;
	XmString	string;
	int		i;
	char		*device;
	Display		*display;
	Window		window;
	int		fildes;
	C_Image		*image;
	int		depth;
	Colormap	colormap;
	int		y;
	char		label_string[100];
	C_IviToggleInfo *toggle_info;
	

	image = image_table.image_entry[image_num]->image;

	/********************************************************/		
	/* Create The Image Viewer Bulletin Board		*/
	/********************************************************/		
	n=0;
	XtSetArg( args[n], XmNx, 0 ); n++;
	XtSetArg( args[n], XmNy, 0 ); n++;
	XtSetArg( args[n], XmNautoUnmanage, False ); n++;
	C_Set_Color_Dialog( args, n, window_defs );
	display_bbdialog = XmCreateBulletinBoardDialog( vv_toplevel,
		image_table.image_entry[image_num]->image_name, 
	        args, n );

        n = 0;
        XtSetArg( args[n], XmNx, 0 ); n++;
        XtSetArg( args[n], XmNy, 0 ); n++;
        XtSetArg( args[n], XmNwidth, image->width ); n++;
        XtSetArg( args[n], XmNheight, image->height ); n++;
        C_Set_Color_Frame( args, n, window_defs );
        draw_frame = XmCreateFrame( display_bbdialog, "draw_frame", args, n );
        XtManageChild( draw_frame );

        n = 0;
        XtSetArg( args[n], XmNx, 0 ); n++;
        XtSetArg( args[n], XmNy, image->height+20 ); n++;
        C_Set_Color_Frame( args, n, window_defs );
        info_frame = XmCreateFrame( display_bbdialog, "frame", args, n );
        XtManageChild( info_frame );

	n = 0;
	C_Set_Color_Bboard( args, n, window_defs );
	bboard = XmCreateBulletinBoard( info_frame, "bboard", args, n );
	XtManageChild( bboard );

	y = 10;
	
	switch ( image->image_info.render_type )
	{
	    case C_PARC_RENDERING:
		sprintf(label_string, "Rendering Algorithm: PARC");
		break;
	
	    case C_PARC_RAYTRACE_RENDERING:
		sprintf(label_string,"Rendering Algorithm: PARC / Ray Tracing");
		break;
	
	    case C_RAYTRACE_RENDERING:
		sprintf(label_string, "Rendering Algorithm: Ray Tracing");
		break;
	
	    case C_RADIOSITY_RENDERING:
		sprintf(label_string, "Rendering Algorithm: Radiosity");
		break;
	
	    case C_NAVIGATOR_RENDERING:
		sprintf(label_string, "Rendering Algorithm: Navigator");
		break;
	}

	n = 0;
	XtSetArg( args[n], XmNx, 10 ); n++;
        XtSetArg( args[n], XmNy, y ); n++;
        label = XmCreateLabelGadget( bboard, label_string, args, n );
        XtManageChild( label );
	y += 20;

	switch (image->image_info.image_accuracy )
	{
	    case C_LOW_IMAGE_ACCURACY:
		sprintf(label_string, "Image Accuracy: Low Accuracy");
		break;

	    case C_MEDIUM_IMAGE_ACCURACY:
		sprintf(label_string, "Image Accuracy: Medium Accuracy");
		break;

	    case C_HIGH_IMAGE_ACCURACY:
		sprintf(label_string, "Image Accuracy: High Accuracy");
		break;

	}

	n = 0;
	XtSetArg( args[n], XmNx, 10 ); n++;
        XtSetArg( args[n], XmNy, y ); n++;
        label = XmCreateLabelGadget( bboard, label_string, args, n );
        XtManageChild( label );
 
        y += 20;

	sprintf(label_string, "Rendering Time: %f", 
				image->image_info.compute_time );
	n = 0;
	XtSetArg( args[n], XmNx, 10 ); n++;
        XtSetArg( args[n], XmNy, y ); n++;
	image_table.image_entry[image_num]->time_label =  
        	XmCreateLabelGadget( bboard, label_string, args, n );
        XtManageChild( image_table.image_entry[image_num]->time_label );
 
        y += 20;


	switch ( image->image_info.render_type )
	{
	    case C_PARC_RAYTRACE_RENDERING:
	    case C_RAYTRACE_RENDERING:

		if ( image->image_info.compute_shadows )
		  sprintf(label_string, "Shadows: On");
		else
		  sprintf(label_string, "Shadows: Off");

		n = 0;
		XtSetArg( args[n], XmNx, 10 ); n++;
		XtSetArg( args[n], XmNy, y ); n++;
		label = XmCreateLabelGadget( bboard, label_string, args, n );
		XtManageChild( label );
		y += 20;

		sprintf(label_string, "Levels Of Reflection: %d",
				image->image_info.levels_of_reflection );

		n = 0;
		XtSetArg( args[n], XmNx, 10 ); n++;
                XtSetArg( args[n], XmNy, y ); n++;
                label = XmCreateLabelGadget( bboard, label_string, args, n );
                XtManageChild( label );
 
                y += 20;

		sprintf(label_string, "Levels Of Transmission: %d",
                                image->image_info.levels_of_transmission );
 
		n = 0;
                XtSetArg( args[n], XmNx, 10 ); n++;
                XtSetArg( args[n], XmNy, y ); n++;
                label = XmCreateLabelGadget( bboard, label_string, args, n );
                XtManageChild( label );
 
                y += 20;

		sprintf(label_string, "Levels Of Indirect Light: %d",
                                image->image_info.levels_of_indirect_light );
 
		n = 0;
                XtSetArg( args[n], XmNx, 10 ); n++;
                XtSetArg( args[n], XmNy, y ); n++;
                label = XmCreateLabelGadget( bboard, label_string, args, n );
                XtManageChild( label );
 
                y += 20;
		break;
	
	}

        n = 0;
        XtSetArg( args[n], XmNx, 0 ); n++;
        XtSetArg( args[n], XmNy, image->height + y + 40 ); n++;
        C_Set_Color_Frame( args, n, window_defs );
        frame = XmCreateFrame( display_bbdialog, "frame", args, n );
        XtManageChild( frame );

	
        n = 0;
        C_Set_Color_RowColumn( args, n, window_defs );
	XtSetArg( args[n], XmNorientation, XmHORIZONTAL ); n++;
        rowcolumn =
                XmCreateRowColumn( frame, "rowcolumn", args, n );
        XtManageChild ( rowcolumn );
        
  
	n=0;
	C_Set_Color_Button( args, n, window_defs );
	button = XmCreatePushButton( rowcolumn, "Toggle Info", args, n );
	XtManageChild(button);

	toggle_info = C_New( C_IviToggleInfo );
	toggle_info->info_frame = info_frame;
	toggle_info->button_frame = frame;
	toggle_info->move_up_amount = y;

	XtAddCallback( button, XmNactivateCallback, 
			ivi_toggle_callback, toggle_info );

	/************************************************/
	/*     Create The Close Button			*/
	/************************************************/
	n=0;
	C_Set_Color_Button( args, n, window_defs );
	button = XmCreatePushButton( rowcolumn, "Close", args, n );
	XtManageChild(button);

	XtAddCallback( button, XmNactivateCallback, 
			close_callback, display_bbdialog );
	

	/************************************************/
	/*     Create The Help Button			*/
	/************************************************/
	n=0;
	C_Set_Color_Button( args, n, window_defs );
	button = XmCreatePushButton( rowcolumn, "Help", args, n );
	XtManageChild(button);


	XtManageChild( display_bbdialog );
	XtMoveWidget( XtParent( display_bbdialog ), 0, 0 );
	XmUpdateDisplay( display_bbdialog );



	ivi_setup_drawing_area( &drawing_area, draw_frame,
			        image->width, image->height, image_num );


	XtAddCallback( drawing_area, XmNexposeCallback, 
		       image_expose_callback, image_num );
	

	image_table.image_entry[image_num]->ui_win = drawing_area;
	image_table.image_entry[image_num]->parent_win = display_bbdialog; 
	

}

void ivi_toggle_callback( w, client_data, call_data )
Widget          w;
C_IviToggleInfo *client_data;
XtPointer       call_data;
{
	Arg		args[1];
	Dimension	y;

	if ( XtIsManaged( client_data->info_frame ) )
	{
	    XtUnmanageChild( client_data->info_frame );
	    XtSetArg( args[0], XmNy, &y );
	    XtGetValues( client_data->button_frame, args, 1 );
	    y -= client_data->move_up_amount;
	    XtUnmanageChild( client_data->button_frame );
	    XtSetArg( args[0], XmNy, y );
	    XtSetValues( client_data->button_frame, args, 1 );
	    XtManageChild( client_data->button_frame );
	}
	else
	{
	    XtManageChild( client_data->info_frame );
	    XtSetArg( args[0], XmNy, &y );
	    XtGetValues( client_data->button_frame, args, 1 );
	    y += client_data->move_up_amount;
	    XtUnmanageChild( client_data->button_frame );
	    XtSetArg( args[0], XmNy, y );
	    XtSetValues( client_data->button_frame, args, 1 );
	    XtManageChild( client_data->button_frame );
	}

}

void ivi_display_callback( w, client_data, call_data )
Widget          w;
caddr_t         client_data;
caddr_t         call_data;
{
	void create_ivi_display_window();

	if ( image_table.num_images == 0 )
	{
		C_error_message("There aren't any images to display!!!\n");
	}
	else if (image_table.image_entry[image_table.active_image]->parent_win)
	{
		if ( XtIsManaged( image_table.image_entry[
				image_table.active_image]->parent_win ) )
		{
			XtUnmanageChild( image_table.image_entry[
				image_table.active_image]->parent_win );
		}
		XtManageChild( image_table.image_entry[
				image_table.active_image]->parent_win );
	}
	else
	{
		create_ivi_display_window(image_table.active_image);
	}
}

void image_expose_callback(w, client_data, call_data)
Widget          w;
int             client_data;
caddr_t         call_data;
{
	extern void 	ivi_display_image();
	
	extern C_ImageTable	image_table;

	Arg		args[1];
	XmString	label_string;
	char		string[100];
 
        ivi_display_image( client_data );
 
	sprintf( string, "Rendering Time: %f", 
	  image_table.image_entry[client_data]->image->image_info.compute_time);
	label_string = XmStringCreate( string, XmSTRING_DEFAULT_CHARSET );
	XtSetArg( args[0], XmNlabelString, label_string ); 

	XtSetValues(image_table.image_entry[client_data]->time_label, args, 1);

        XmUpdateDisplay( w );
        XmUpdateDisplay( vv_toplevel );
 
}

