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

#include <stdio.h>
#include <math.h>
#include <Xm/Xm.h>
#include <Xm/RowColumn.h>
#include <X11/StringDefs.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 <Xm/Scale.h>

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

/* Global Variables For Motif Windowing */
extern Widget			vv_toplevel;	/* Bulletin Board Dialog */
extern C_WindowDefs		window_defs;
extern C_View			view;
extern C_ObjectControlInfo	oco_info;



void oco_create_view_display()
{
	extern void	close_callback();
	extern void	help_callback();
	void		oco_update_view_display();
	void		update_oco_view_type();
	void		oco_set_view_params();
	void		oco_reset_view_params();


	Arg		args[20];
	int		n;

	Widget		label;
	Widget		slider;
	Widget		frame;
	Widget		pulldown;
	Widget		rowcolumn;
	Widget		button;
	Widget		bboard;
	Widget		option_menu;
	XmString	label_string;
	char		string[10];


	n=0;
        XtSetArg( args[n], XmNautoUnmanage, False ); n++;
        C_Set_Color_Dialog( args, n, window_defs );
        oco_info.view_info.view_displayed = 
		XmCreateBulletinBoardDialog( vv_toplevel,
                       "View", args, n );

	n = 0;
	XtSetArg( args[n], XmNx, 0 ); n++;
	XtSetArg( args[n], XmNy, 0 ); n++;
	C_Set_Color_Frame( args, n, window_defs );
	frame = XmCreateFrame( oco_info.view_info.view_displayed, 
			"frame", args, n );
	XtManageChild( frame );


	n=0;
	XtSetArg( args[n], XmNeditable, FALSE ); n++;
	XtSetArg( args[n], XmNeditMode, XmMULTI_LINE_EDIT ); n++;
	XtSetArg( args[n], XmNsensitive, FALSE ); n++;
	XtSetArg( args[n], XmNcursorPositionVisible, FALSE ); n++;
	XtSetArg( args[n], XmNrows, 7 ); n++;
	XtSetArg( args[n], XmNcolumns, 51 ); n++;
	C_Set_Color_Bboard( args, n, window_defs );

	oco_info.view_info.view_text = XmCreateText(frame,
			"View Text", args, n );

	XtManageChild( oco_info.view_info.view_text );

	
	n = 0;
	XtSetArg( args[n], XmNx, 0 ); n++;
	XtSetArg( args[n], XmNy, 150 ); n++;
	XtSetArg( args[n], XmNwidth, 600 ); n++; 
	C_Set_Color_Frame( args, n, window_defs );
	frame = XmCreateFrame( oco_info.view_info.view_displayed, 
			"frame", args, n );
	XtManageChild( frame );

        n = 0;
	C_Set_Color_Bboard( args, n, window_defs );
        bboard = 
		XmCreateBulletinBoard(frame, "bboard", args, n);
        XtManageChild (bboard);
	
	label_string = XmStringCreate("Width (pixels): ", 
					XmSTRING_DEFAULT_CHARSET );
        n=0;
        XtSetArg( args[n], XmNx, 110 ); n++;
        XtSetArg( args[n], XmNy, 15 ); n++;
        XtSetArg( args[n], XmNlabelString, label_string ); n++;
        label = XmCreateLabelGadget( bboard, "width", args, n );
        XtManageChild( label );
        XmStringFree( label_string );

	sprintf( string, "%d", view.width_pixels );
	n=0;
        XtSetArg( args[n], XmNx, 220 ); n++;
        XtSetArg( args[n], XmNy, 10 ); n++;
        XtSetArg( args[n], XmNcolumns, 10 ); n++;
        XtSetArg( args[n], XmNvalue, string ); n++;
        C_Set_Color_Text( args, n, window_defs );
        oco_info.view_info.view_width_pixels = 
			XmCreateTextField( bboard, "width", args, n );
        XtManageChild( oco_info.view_info.view_width_pixels );

	label_string = XmStringCreate("Height (pixels): ", 
					XmSTRING_DEFAULT_CHARSET );
        n=0;
        XtSetArg( args[n], XmNx, 110 ); n++;
        XtSetArg( args[n], XmNy, 60 ); n++;
        XtSetArg( args[n], XmNlabelString, label_string ); n++;
        label = XmCreateLabelGadget( bboard, "height", args, n );
        XtManageChild( label );
        XmStringFree( label_string );

	sprintf( string, "%d", view.height_pixels );
	n=0;
        XtSetArg( args[n], XmNx, 220 ); n++;
        XtSetArg( args[n], XmNy, 55 ); n++;
        XtSetArg( args[n], XmNcolumns, 10 ); n++;
        XtSetArg( args[n], XmNvalue, string ); n++;
        C_Set_Color_Text( args, n, window_defs );
        oco_info.view_info.view_height_pixels = 
			XmCreateTextField( bboard, "height", args, n );
        XtManageChild( oco_info.view_info.view_height_pixels );

        n = 0;
        C_Set_Color_PullDown( args, n, window_defs );
        pulldown =
                XmCreatePulldownMenu(bboard, "pulldown", args, n);

        n = 0;
        label_string = XmStringCreate ("Parallel", XmSTRING_DEFAULT_CHARSET);
        XtSetArg (args[n], XmNlabelString, label_string); n++;
        oco_info.view_info.view_type[0] =
                XmCreatePushButtonGadget(pulldown, "Parallel", args, n);
        XmStringFree (label_string);
        XtAddCallback (oco_info.view_info.view_type[0], XmNactivateCallback,
                       update_oco_view_type, C_PARALLEL_VIEW);

        n = 0;
        label_string = XmStringCreate ("Perspective", XmSTRING_DEFAULT_CHARSET);
        XtSetArg (args[n], XmNlabelString, label_string); n++;
        oco_info.view_info.view_type[1] =
                XmCreatePushButtonGadget(pulldown, "Perspective", args, n);
        XmStringFree (label_string);
        XtAddCallback (oco_info.view_info.view_type[1], XmNactivateCallback,
                       update_oco_view_type, C_PERSPECTIVE_VIEW);

	XtManageChildren( oco_info.view_info.view_type, 2 );

        n = 0;
        label_string = XmStringCreate ("View Type:",
                                      XmSTRING_DEFAULT_CHARSET);
        XtSetArg (args[n], XmNlabelString, label_string); n++;
        XtSetArg (args[n], XmNsubMenuId, pulldown); n++;
        XtSetArg( args[n], XmNx, 110 ); n++;
        XtSetArg( args[n], XmNy, 100 ); n++;
        C_Set_Color_OptionMenu( args, n, window_defs );

	if ( view.fov == C_PARALLEL_FOV )
	{
		XtSetArg (args[n], XmNmenuHistory, 
				oco_info.view_info.view_type[0]); n++;
	}
	else
	{
		XtSetArg (args[n], XmNmenuHistory, 
				oco_info.view_info.view_type[1]); n++;
	}

        option_menu = XmCreateOptionMenu(bboard,
                                "option_menu", args, n);

        XtManageChild(option_menu);

	label_string = XmStringCreate("Width (units): ", 
					XmSTRING_DEFAULT_CHARSET );
        n=0;
        XtSetArg( args[n], XmNx, 10 ); n++;
        XtSetArg( args[n], XmNy, 150 ); n++;
        XtSetArg( args[n], XmNlabelString, label_string ); n++;
	if (view.fov != C_PARALLEL_FOV)
	{
		XtSetArg( args[n], XmNsensitive, FALSE ); n++;
	}
	else	
	{
		XtSetArg( args[n], XmNsensitive, TRUE ); n++;
	}
        oco_info.view_info.view_width_label = XmCreateLabelGadget( bboard, 
						"width", args, n );
        XtManageChild( oco_info.view_info.view_width_label );
        XmStringFree( label_string );

	sprintf( string, "%f", view.width_units );
	n=0;
        XtSetArg( args[n], XmNx, 120 ); n++;
        XtSetArg( args[n], XmNy, 145 ); n++;
        XtSetArg( args[n], XmNcolumns, 10 ); n++;
        XtSetArg( args[n], XmNvalue, string ); n++;
	if (view.fov != C_PARALLEL_FOV)
	{
		XtSetArg( args[n], XmNsensitive, FALSE ); n++;
	}
	else	
	{
		XtSetArg( args[n], XmNsensitive, TRUE ); n++;
	}
        C_Set_Color_Text( args, n, window_defs );
        oco_info.view_info.view_width_units = 
			XmCreateTextField( bboard, "width", args, n );
        XtManageChild( oco_info.view_info.view_width_units );

	label_string = XmStringCreate("Height (units): ", 
					XmSTRING_DEFAULT_CHARSET );
        n=0;
        XtSetArg( args[n], XmNx, 10 ); n++;
        XtSetArg( args[n], XmNy, 195 ); n++;
        XtSetArg( args[n], XmNlabelString, label_string ); n++;
	if (view.fov != C_PARALLEL_FOV)
	{	
		XtSetArg( args[n], XmNsensitive, FALSE ); n++;
	}
	else	
	{
		XtSetArg( args[n], XmNsensitive, TRUE ); n++;
	}
        oco_info.view_info.view_height_label = XmCreateLabelGadget( bboard, 
							"height", args, n );
        XtManageChild( oco_info.view_info.view_height_label );
        XmStringFree( label_string );

	sprintf( string, "%f", view.height_units );
	n=0;
        XtSetArg( args[n], XmNx, 120 ); n++;
        XtSetArg( args[n], XmNy, 195 ); n++;
        XtSetArg( args[n], XmNcolumns, 10 ); n++;
        XtSetArg( args[n], XmNvalue, string ); n++;
	if (view.fov != C_PARALLEL_FOV)
	{
		XtSetArg( args[n], XmNsensitive, FALSE ); n++;
	}
	else	
	{
		XtSetArg( args[n], XmNsensitive, TRUE ); n++;
	}
        C_Set_Color_Text( args, n, window_defs );
        oco_info.view_info.view_height_units = 
			XmCreateTextField( bboard, "height", args, n );
        XtManageChild( oco_info.view_info.view_height_units );


	label_string = XmStringCreate("Field Of View:", 
					XmSTRING_DEFAULT_CHARSET );
        n=0;
        XtSetArg( args[n], XmNx, 250 ); n++;
        XtSetArg( args[n], XmNy, 150 ); n++;
        XtSetArg( args[n], XmNlabelString, label_string ); n++;
	if (view.fov == C_PARALLEL_FOV)
	{
		XtSetArg( args[n], XmNsensitive, FALSE ); n++;
	}
	else	
	{
		XtSetArg( args[n], XmNsensitive, TRUE ); n++;
	}
        oco_info.view_info.view_fov_label1 = XmCreateLabelGadget( bboard, 
						"fov", args, n );
        XtManageChild( oco_info.view_info.view_fov_label1);
        XmStringFree( label_string );

	label_string = XmStringCreate("  (degrees)  ", 
					XmSTRING_DEFAULT_CHARSET );
        n=0;
        XtSetArg( args[n], XmNx, 250 ); n++;
        XtSetArg( args[n], XmNy, 165 ); n++;
        XtSetArg( args[n], XmNlabelString, label_string ); n++;
	if (view.fov == C_PARALLEL_FOV)
	{
		XtSetArg( args[n], XmNsensitive, FALSE ); n++;
	}
	else	
	{
		XtSetArg( args[n], XmNsensitive, TRUE ); n++;
	}
        oco_info.view_info.view_fov_label2 = XmCreateLabelGadget( bboard, 
						"fov", args, n );
        XtManageChild( oco_info.view_info.view_fov_label2);
        XmStringFree( label_string );

	sprintf( string, "%f", C_Rad_To_Deg(view.fov) );
	n=0;
        XtSetArg( args[n], XmNx, 360 ); n++;
        XtSetArg( args[n], XmNy, 145 ); n++;
        XtSetArg( args[n], XmNcolumns, 10 ); n++;
        XtSetArg( args[n], XmNvalue, string ); n++;
	if (view.fov == C_PARALLEL_FOV)
	{
		XtSetArg( args[n], XmNsensitive, FALSE ); n++;
	}
	else	
	{
		XtSetArg( args[n], XmNsensitive, TRUE ); n++;
	}
        C_Set_Color_Text( args, n, window_defs );
        oco_info.view_info.view_fov = 
			XmCreateTextField( bboard, "fov", args, n );
        XtManageChild( oco_info.view_info.view_fov );

	n = 0;
	XtSetArg( args[n], XmNx, 0 ); n++;
	XtSetArg( args[n], XmNy, 600 ); n++;
	C_Set_Color_Frame( args, n, window_defs );
	frame = XmCreateFrame( oco_info.view_info.view_displayed,
			"frame", args, n );
	XtManageChild( frame );

	/********************************************************/		
	/*	Create a RowColumn for Buttons   		*/
	/********************************************************/		
        n = 0;
	XtSetArg( args[n], XmNorientation, XmHORIZONTAL ); n++;
	C_Set_Color_RowColumn( args, n, window_defs );
        rowcolumn = 
		XmCreateRowColumn(frame, "rowcolumn", args, n);
        XtManageChild (rowcolumn);

	n = 0;
	C_Set_Color_Button( args, n, window_defs );
	button = XtCreateManagedWidget("Accept", 
			xmPushButtonWidgetClass, rowcolumn, args, n );

	XtAddCallback( button, XmNactivateCallback, 
		       oco_set_view_params, option_menu );

	n = 0;
	C_Set_Color_Button( args, n, window_defs );
	button = XtCreateManagedWidget("Cancel", 
			xmPushButtonWidgetClass, rowcolumn, args, n );

	XtAddCallback( button, XmNactivateCallback, 
		       oco_reset_view_params, option_menu );

	n = 0;
	C_Set_Color_Button( args, n, window_defs );
	button = XtCreateManagedWidget("Close", 
			xmPushButtonWidgetClass, rowcolumn, args, n );

	XtAddCallback( button, XmNactivateCallback, 
		       oco_reset_view_params, option_menu );
	XtAddCallback( button, XmNactivateCallback, 
		       close_callback, oco_info.view_info.view_displayed );

	n = 0;
	C_Set_Color_Button( args, n, window_defs );
	button = XtCreateManagedWidget("Help", 
			xmPushButtonWidgetClass, rowcolumn, args, n );
	XtAddCallback( button, XmNactivateCallback, 
		       help_callback, C_OCO_MODIFY_VIEW_HELP );

	XtManageChild( oco_info.view_info.view_displayed );

	oco_update_view_display();

}

void oco_set_view_params( w, client_data, call_data )
Widget		w;
Widget		client_data;
XtPointer	call_data;
{
	extern C_create_view_matrices();
	extern void C_update_system();

	Arg	args[10];
	char	*string;
	Widget	tmp_widget;

	string = (char *) 
		XmTextGetString( oco_info.view_info.view_width_pixels );
	view.width_pixels = atoi( string );
 

	string = (char *) 
		XmTextGetString( oco_info.view_info.view_height_pixels );
	view.height_pixels = atoi( string );


	XtSetArg( args[0], XmNmenuHistory, &tmp_widget );
	XtGetValues( client_data, args, 1 );
	
	if ( tmp_widget == oco_info.view_info.view_type[0] )
	{
		view.fov = C_PARALLEL_FOV;

	  	string = (char *) 
			XmTextGetString( oco_info.view_info.view_width_units );
	  	view.width_units = atof( string );

	  	string = (char *) 
			XmTextGetString( oco_info.view_info.view_height_units );
	  	view.height_units = atof( string );
	}
	else
	{
	  	string = (char *) 
			XmTextGetString( oco_info.view_info.view_fov );
	  	view.fov = C_Deg_To_Rad( (atof( string )) );

	}

	C_create_view_matrices( &(view) );

	C_update_system( C_VIEW_MODIFIED );

}

void oco_reset_view_params( w, client_data, call_data )
Widget		w;
Widget	client_data;
XtPointer	call_data;
{
	Arg	args[10];
	char	string[20];

	sprintf( string, "%d", view.width_pixels );
	XtSetArg( args[0], XmNvalue, string );
	XtSetValues( oco_info.view_info.view_width_pixels, args, 1 );

	sprintf( string, "%d", view.height_pixels );
	XtSetArg( args[0], XmNvalue, string );
	XtSetValues( oco_info.view_info.view_height_pixels, args, 1 );

	if ( view.fov == C_PARALLEL_FOV )
	{
		XtSetArg (args[0], XmNmenuHistory, 
				oco_info.view_info.view_type[0]);
	}
	else
	{
		XtSetArg (args[0], XmNmenuHistory, 
				oco_info.view_info.view_type[1]); 
	}

	XtSetValues( client_data, args, 1 ); 


	if ( view.fov == C_PARALLEL_FOV )
	{
		sprintf(string, "%f", view.fov );
		XtSetArg( args[0], XmNvalue, string );
		
		XtSetValues( oco_info.view_info.view_fov, args, 1 );
		
		XtSetArg( args[0], XmNsensitive, FALSE );
		
		XtSetValues( oco_info.view_info.view_fov_label1, args, 1 );
		XtSetValues( oco_info.view_info.view_fov_label2, args, 1 );
		XtSetValues( oco_info.view_info.view_fov,        args, 1 );

		XtSetArg( args[0], XmNsensitive, TRUE );

		XtSetValues( oco_info.view_info.view_width_units,  args, 1 );
		XtSetValues( oco_info.view_info.view_height_units, args, 1 );
		XtSetValues( oco_info.view_info.view_width_label,  args, 1 );
		XtSetValues( oco_info.view_info.view_height_label, args, 1 );
		

	}
	else
	{
		
		sprintf(string, "%f", C_Rad_To_Deg( view.fov ) );
		XtSetArg( args[0], XmNvalue, string );
		
		XtSetValues( oco_info.view_info.view_fov, args, 1 );
		
		XtSetArg( args[0], XmNsensitive, TRUE );
		
		XtSetValues( oco_info.view_info.view_fov_label1, args, 1 );
		XtSetValues( oco_info.view_info.view_fov_label2, args, 1 );
		XtSetValues( oco_info.view_info.view_fov,        args, 1 );

		XtSetArg( args[0], XmNsensitive, FALSE );

		XtSetValues( oco_info.view_info.view_width_units,  args, 1 );
		XtSetValues( oco_info.view_info.view_height_units, args, 1 );
		XtSetValues( oco_info.view_info.view_width_label,  args, 1 );
		XtSetValues( oco_info.view_info.view_height_label, args, 1 );
		

	}

}


void update_oco_view_type( w, client_data, call_data )
Widget		w;
C_ViewType	client_data;
XtPointer	call_data;
{
	Arg	args[10];
	char	string[10];

	switch ( client_data )
	{
	  case C_PARALLEL_VIEW:
		
		sprintf(string, "%f", C_PARALLEL_FOV );
		XtSetArg( args[0], XmNvalue, string );
		
		XtSetValues( oco_info.view_info.view_fov, args, 1 );
		
		XtSetArg( args[0], XmNsensitive, FALSE );
		
		XtSetValues( oco_info.view_info.view_fov_label1, args, 1 );
		XtSetValues( oco_info.view_info.view_fov_label2, args, 1 );
		XtSetValues( oco_info.view_info.view_fov,        args, 1 );

		XtSetArg( args[0], XmNsensitive, TRUE );

		XtSetValues( oco_info.view_info.view_width_units,  args, 1 );
		XtSetValues( oco_info.view_info.view_height_units, args, 1 );
		XtSetValues( oco_info.view_info.view_width_label,  args, 1 );
		XtSetValues( oco_info.view_info.view_height_label, args, 1 );
		
		break;

	  case C_PERSPECTIVE_VIEW:
		
		sprintf(string, "%f", C_PERSPECTIVE_FOV );
		XtSetArg( args[0], XmNvalue, string );
		
		XtSetValues( oco_info.view_info.view_fov, args, 1 );
		
		XtSetArg( args[0], XmNsensitive, TRUE );
		
		XtSetValues( oco_info.view_info.view_fov_label1, args, 1 );
		XtSetValues( oco_info.view_info.view_fov_label2, args, 1 );
		XtSetValues( oco_info.view_info.view_fov,        args, 1 );

		XtSetArg( args[0], XmNsensitive, FALSE );

		XtSetValues( oco_info.view_info.view_width_units,  args, 1 );
		XtSetValues( oco_info.view_info.view_height_units, args, 1 );
		XtSetValues( oco_info.view_info.view_width_label,  args, 1 );
		XtSetValues( oco_info.view_info.view_height_label, args, 1 );
		
		break;

	}

}

void oco_update_view_display() 
{
	XmTextPosition	last;
	char		string[100];
	Arg		args[1];

	if (!oco_info.view_info.view_text) return;

	XtSetArg( args[0], XmNvalue, "" );
	XtSetValues( oco_info.view_info.view_text, args, 1 );

	last = XmTextGetLastPosition( oco_info.view_info.view_text );

	sprintf( string, "Coordinate System:\n\n" );

	XmTextInsert( oco_info.view_info.view_text, last, string );	

	last = XmTextGetLastPosition( oco_info.view_info.view_text );

	sprintf( string, "     Origin: (%3.2f, %3.2f, %3.2f)\n",
		view.c_sys.origin.x,
		view.c_sys.origin.y,
		view.c_sys.origin.z );

	XmTextInsert( oco_info.view_info.view_text, last, string );	

	last = XmTextGetLastPosition( oco_info.view_info.view_text );

	sprintf( string, "     X Axis: (%3.2f, %3.2f, %3.2f)\n", 
		view.c_sys.x_axis.x,
		view.c_sys.x_axis.y,
		view.c_sys.x_axis.z );

	XmTextInsert( oco_info.view_info.view_text, last, string );	

	last = XmTextGetLastPosition( oco_info.view_info.view_text );

	sprintf( string, "     Y Axis: (%3.2f, %3.2f, %3.2f)\n", 
		view.c_sys.y_axis.x,
		view.c_sys.y_axis.y,
		view.c_sys.y_axis.z );

	XmTextInsert( oco_info.view_info.view_text, last, string );	

	last = XmTextGetLastPosition( oco_info.view_info.view_text );

	sprintf( string, "     Z Axis: (%3.2f, %3.2f, %3.2f)\n\n", 
		view.c_sys.z_axis.x,
		view.c_sys.z_axis.y,
		view.c_sys.z_axis.z );

	XmTextInsert( oco_info.view_info.view_text, last, string );	

}

