/****************************************************************************/
/*                                                                          */
/*  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_fio_load.c
 *		      Author: Jiang(John) Qian
 *			Date: 6/7/93
 *		 Description: Motif Windowing Routines Of VolVis
 *			      Creates the file load window, displays icon
 *			      representation of the data file.
 *	Modification History:
 *
 *		Who?		When?		Why?
 *	--------------------------------------------------------------------
 *
 */

#include <stdio.h>
#include <string.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 <sys/types.h>
#include <dirent.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <Xm/TextF.h>
#include <unistd.h>
#include <pwd.h>

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

#define	C_ICON_SPACING	    	10  	/* The space between two icons */
#define C_BITMAP_PAD 		32	/* Bitmap pad of the image */
#define C_OFFSET 		0	/* offset of the image */

/* set the font for the file names on the icons */
#define C_FONT "-adobe-helvetica-bold-r-normal--14-140-75-75-p-82-iso8859-1"

#include "bitmaps/fun_bitmap"		/* bitmap for the function icon */
#include "bitmaps/env_bitmap"		/* bitmap for the environment icon */
#include "bitmaps/error_bitmap"		/* bitmap for an error icon */

/* Global Variables For Motif Windowing */
extern Widget		vv_toplevel;	/* VolVis toplevel Shell Widget */
extern Widget		fio_bbdialog;	/* File I/O Bulletin Board Dialog */
extern Widget		fio_load_bbdialog;
extern C_WindowDefs	window_defs;	

C_FileIOInfo		fio_load_info;	/* Information containing load status*/
Icon_Info		load_icon_info[C_FIO_MAXFILES]; /*info for each icon */


/*
 *        Procedure Name: create_fio_load_window
 *          Return Value: none
 *       Input Variables: none
 *      Output Variables: none
 *      Update Variables: load_data->path_text  - The path text widget
 *			  load_data->file_text  - The file text widget
 *			  load_data->mssage   	- The message window to display 
 *						  header information
 *			  load_data->canvas   	- The area to display icons
 *      Global Variables: load_data
 *           Description: This function will create the file load window.
 *			  That includes a widget allowing the user to enter
 *			  the path name, a widget allowing the user to enter
 *			  the file name, a pull down menu allowing the user
 *			  to change file type, a scroll window containing 
 *			  all the iocons, a message window for displaying 
 * 			  header information of the data file, and some 
 * 			  buttons at the bottom of the window.
 */

void create_fio_load_window()
{
  extern   close_callback();
  void	fio_set_load_type();
  void	get_load_path();
  void	get_load_file();
  void	accept_load_callback();
  void	help_callback();
  void  load_canvas_expose_CB();
  void	load_scrolled();

  Widget	  accept_button,
		  close_button,
		  help_button,
		  path_label,
		  file_label,
		  scrollbar,
		  scrollwindow,
		  fio_load_pulld,
		  fio_load_options[5],
		  fio_load_menu,
		  rowcolumn,
		  frame;

  Arg		  args[30];
  XmString	  label_string;
  int		  n;
  char		  initial_path[C_MAX_STRING];	
  char		  error_msg[C_MAX_STRING];

	if ((fio_load_info.load_data = ( Fio_Dialog_Info * ) 
		malloc( sizeof( Fio_Dialog_Info))) == NULL)
 	{
	/* if not enough memory to malloc load_data, system exits */
    		sprintf(error_msg, 
       		"Out of Memory Starting The File Load Window\nSystem must exit !!!\n");
    		C_error_message(error_msg);
    		exit(0);
	}

	/************************************************/
	/*     Create The file load dialog window	*/
	/************************************************/
	n=0;
	XtSetArg( args[n], XmNx, 0 ); n++;
	XtSetArg( args[n], XmNy, 0 ); n++;
	XtSetArg( args[n], XmNautoUnmanage, False ); n++;
	label_string = XmStringCreate( "File Load", XmSTRING_DEFAULT_CHARSET);
	XtSetArg( args[n], XmNdialogTitle, label_string ); n++;
	C_Set_Color_Dialog( args, n, window_defs );
	
	fio_load_bbdialog = XmCreateBulletinBoardDialog( vv_toplevel,
						"Load File Window", args, n );
	XmStringFree(label_string);

	/************************************************/
	/*     Create The path label			*/
	/************************************************/
	n = 0;
	XtSetArg( args[ n ] , XmNx , 15 );			n++;
	XtSetArg( args[ n ] , XmNy , 25 );			n++;
	path_label = XmCreateLabelGadget( fio_load_bbdialog ,"Path:",args , n );
	XtManageChild( path_label );

	/************************************************/
	/*     Create The path text area		*/
	/************************************************/
	
	/* set the initial path on the path widget */
	sprintf(initial_path, "%s/data/SLC", getenv("VOLVIS_HOME"));
	n = 0 ;
	XtSetArg( args[ n ] , XmNx , 75 );			n++;
	XtSetArg( args[ n ] , XmNy , 15 );			n++;
	XtSetArg( args[ n ] , XmNcolumns , 40 ); 		n++;
	XtSetArg( args[ n ] , XmNvalue, initial_path );		n++;
	C_Set_Color_Text(args,n,window_defs);
	fio_load_info.load_data->path_text = 
		XmCreateTextField( fio_load_bbdialog , "Text1" , args , n );
	XtManageChild( fio_load_info.load_data->path_text );
	XtAddCallback( fio_load_info.load_data->path_text, XmNactivateCallback, 
			get_load_path , fio_load_info.load_data );

	/************************************************/
	/*     Create The file label			*/
	/************************************************/
	n = 0;
	XtSetArg( args[ n ] , XmNx , 15 );			n++;
	XtSetArg( args[ n ] , XmNy , 70 );			n++;
 	file_label= XmCreateLabelGadget( fio_load_bbdialog ,"File:", args , n );
	XtManageChild( file_label );

	/************************************************/
	/*     Create The file text area		*/
	/************************************************/
	n = 0 ;
	XtSetArg( args[ n ] , XmNx , 75 );	n++;
	XtSetArg( args[ n ] , XmNy , 60 );	n++;
	XtSetArg( args[ n ] , XmNcolumns , 15 ); n++;
	C_Set_Color_Text(args,n,window_defs);
	fio_load_info.load_data->file_text = 
			XmCreateTextField( fio_load_bbdialog ,"Text2",args, n);
	XtManageChild( fio_load_info.load_data->file_text );
	XtAddCallback( fio_load_info.load_data->file_text ,XmNactivateCallback, 
			get_load_file , fio_load_info.load_data );

	/************************************************/
	/*     Create The Load Type Pulldown		*/
	/************************************************/
	n=0;
	C_Set_Color_PullDown( args, n, window_defs );
	fio_load_pulld = XmCreatePulldownMenu( fio_load_bbdialog, 
			"fio_load_pulld", args, n );

	label_string = XmStringCreate( "Slice",  XmSTRING_DEFAULT_CHARSET);
	n=0;
	XtSetArg( args[n], XmNlabelString, label_string); n++;
	fio_load_options[0] = XmCreatePushButtonGadget( fio_load_pulld, 
			"Slice", args, n );
	XmStringFree( label_string );
	XtAddCallback( fio_load_options[0], XmNactivateCallback, 
		  	fio_set_load_type, C_SLICE_FILE );

	label_string = XmStringCreate( "Image",  XmSTRING_DEFAULT_CHARSET);
	n=0;
	XtSetArg( args[n], XmNlabelString, label_string); n++;
	fio_load_options[1] = XmCreatePushButtonGadget( fio_load_pulld,
			"Image", args, n );
	XmStringFree( label_string );
	XtAddCallback( fio_load_options[1], XmNactivateCallback, 
		  	fio_set_load_type, C_IMAGE_FILE );

	label_string = XmStringCreate( "Texture",  XmSTRING_DEFAULT_CHARSET);
	n=0;
	XtSetArg( args[n], XmNlabelString, label_string); n++;
	fio_load_options[2] = XmCreatePushButtonGadget( fio_load_pulld,
			"Texture", args, n );
	XmStringFree( label_string );
	XtAddCallback( fio_load_options[2], XmNactivateCallback, 
		  	fio_set_load_type, C_TEXTURE_FILE );

	label_string = XmStringCreate( "Function",  XmSTRING_DEFAULT_CHARSET);
	n=0;
	XtSetArg( args[n], XmNlabelString, label_string); n++;
	fio_load_options[3] = XmCreatePushButtonGadget( fio_load_pulld,
			"Function", args, n );
	XmStringFree( label_string );
	XtAddCallback( fio_load_options[3], XmNactivateCallback, 
		  	fio_set_load_type, C_FUNCTION_FILE );


        label_string = XmStringCreate( "Environment", XmSTRING_DEFAULT_CHARSET);
        n=0;
        XtSetArg( args[n], XmNlabelString, label_string); n++;
        fio_load_options[4] = XmCreatePushButtonGadget( fio_load_pulld,
                       	"Environment", args, n );
        XmStringFree( label_string );
        XtAddCallback( fio_load_options[4], XmNactivateCallback,
                  	fio_set_load_type, C_ENVIRONMENT_FILE );

	XtManageChildren( fio_load_options, 5 );

	label_string = XmStringCreate("Load Type:", XmSTRING_DEFAULT_CHARSET);
	n=0;
	XtSetArg( args[n], XmNx, 240 ); n++;
	XtSetArg( args[n], XmNy, 55 ); n++;
	XtSetArg( args[n], XmNlabelString, label_string ); n++;
	XtSetArg( args[n], XmNsubMenuId, fio_load_pulld ); n++;
	XtSetArg( args[n], XmNmenuHistory, fio_load_options[0] ); n++;
	fio_load_info.load_type = C_SLICE_FILE;
	C_Set_Color_OptionMenu( args, n, window_defs );
	fio_load_menu = XmCreateOptionMenu( fio_load_bbdialog, 
			"fio_load_menu", args, n );
	XtManageChild( fio_load_menu );

	XmStringFree( label_string );

	/****************************************************/
	/* Create A Scroll Window To Contain All The Icons  */
	/****************************************************/
	n = 0;
	XtSetArg( args[ n ], XmNx         , 15);		n++;
	XtSetArg( args[ n ], XmNy         , 105);		n++;
	XtSetArg( args[ n ], XtNheight    , 270);		n++;
	XtSetArg( args[ n ], XtNwidth     , 430);		n++;
	XtSetArg( args[ n ], XmNorientation, XmVERTICAL);	n++;
        XtSetArg( args[ n ], XmNscrollingPolicy, XmAPPLICATION_DEFINED);n++;
	XtSetArg( args[ n ], XmNvisualPolicy,XmVARIABLE);	n++;
	C_Set_Color_ScrollWindow(args,n,window_defs);
	scrollwindow = XmCreateScrolledWindow(fio_load_bbdialog, 
			"scroll", args,n);

	/****************************************************/
	/* Create A Drawing Area To Display All The Icons   */
	/****************************************************/
	n=0;
	XtSetArg(args[ n ], XmNresizePolicy,XmRESIZE_NONE);	n++;
	C_Set_Color_Canvas(args,n,window_defs);		
	fio_load_info.load_data->canvas = XtCreateManagedWidget("canvas",
			xmDrawingAreaWidgetClass, scrollwindow, args,n);

        XtAddCallback( fio_load_info.load_data->canvas, XmNexposeCallback,
                        load_canvas_expose_CB, fio_load_info.load_type);
	XtManageChild(fio_load_info.load_data->canvas);

	/**********************************************************/
	/* Create A Scroll Bar to Scroll Through The Drawing Area */
	/**********************************************************/
	n = 0;
	XtSetArg( args[n], XmNmaximum, 1);		n++;
	XtSetArg( args[n], XmNsliderSize, 1);		n++;
	XtSetArg( args[n], XmNpageIncrement, 1);	n++;
	C_Set_Color_ScrollBar(args,n,window_defs);
	fio_load_info.load_data->scrollbar = XtCreateManagedWidget("scroll_bar",
			xmScrollBarWidgetClass, scrollwindow,args,n);
	XtManageChild(fio_load_info.load_data->scrollbar);

	XtManageChild(scrollwindow);

	/* adds callback when value changes */
        XtAddCallback(fio_load_info.load_data->scrollbar, 
			XmNvalueChangedCallback, load_scrolled, XmVERTICAL);

	/* adds callback when the user is draging the middle of scrollbar */
	XtAddCallback(fio_load_info.load_data->scrollbar, XmNdragCallback, 
			load_scrolled, XmVERTICAL);

	/* manages the scrollbar, drawing area, and the scrollwindow */
	XmScrolledWindowSetAreas(scrollwindow, NULL, 
			fio_load_info.load_data->scrollbar, 
			fio_load_info.load_data->canvas);

	/********************************************************/
	/* Create A Message Area To Display Header Information  */
	/********************************************************/
        n=0;
        XtSetArg( args[ n ], XmNx         , 15);                n++;
        XtSetArg( args[ n ], XmNy         , 380);               n++;
        XtSetArg( args[ n ], XmNheight    , 110);               n++;
        XtSetArg( args[ n ], XmNwidth     , 430);               n++;
        XtSetArg( args[ n ], XmNeditMode, XmMULTI_LINE_EDIT); 	n++;
        XtSetArg( args[ n ], XmNeditable, False);             	n++;
        XtSetArg( args[ n ], XmNcursorPositionVisible, False);  n++;
        XtSetArg( args[ n ], XmNscrollVertical,   True);      	n++;
        XtSetArg( args[ n ], XmNscrollHorizontal, False);     	n++;
	XtSetArg( args[ n ], XmNwordWrap, True);		n++;

        C_Set_Color_Text( args, n, window_defs );
	fio_load_info.load_data->message = 
		XmCreateScrolledText(fio_load_bbdialog, "text_w", args, n);

	XtManageChild(fio_load_info.load_data->message);

	/************************************************/
	/*     Create A Frame To Hold The Buttons	*/
	/************************************************/
        n = 0;
        XtSetArg( args[n], XmNx, 15 ); n++;
        XtSetArg( args[n], XmNy, 500); n++;
        C_Set_Color_Frame( args, n, window_defs );
        frame = XmCreateFrame( fio_load_bbdialog, "frame", args, n );
        XtManageChild( frame );

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

	/************************************************/
	/*     Create The Accept Button			*/
	/************************************************/
	n = 0 ;
	C_Set_Color_Button(args,n,window_defs);
	accept_button = XmCreatePushButton( rowcolumn , "Accept", args, n );
	XtAddCallback( accept_button , XmNactivateCallback, 
				accept_load_callback ,  NULL);
	XtManageChild ( accept_button );

	/************************************************/
	/*     Create The Close Button			*/
	/************************************************/
	n = 0;
	C_Set_Color_Button(args,n,window_defs);
	close_button = XmCreatePushButton( rowcolumn , " Close " , args , n );
	XtAddCallback( close_button , XmNactivateCallback, 
					close_callback , fio_load_bbdialog);
	XtManageChild ( close_button );

	/************************************************/
	/*     Create The Help Button			*/
	/************************************************/
	n = 0;
	C_Set_Color_Button(args,n,window_defs);
	help_button = XmCreatePushButton( rowcolumn , "  Help  ", args , n );
	XtAddCallback( help_button , XmNactivateCallback, 
				help_callback , C_FIO_LOAD_HELP );	
	XtManageChild ( help_button );

	/* manage the file i/o load window */
 	XtManageChild(fio_load_bbdialog);
}

/*
 *        Procedure Name: load_canvas_expose_CB 
 *          Return Value: none
 *       Input Variables: w			- widget
 *			  client_data		- the file type 
 *			  call_data		- call data 
 *      Output Variables: none
 *      Update Variables: load_data->path_text  - The path text widget
 *			  load_data->file_text  - The file text widget
 *			  load_data->mssage   	- The message window to display 
 *						  header information
 *			  load_data->canvas   	- The area to display icons
 *      Global Variables: fio_load_info, load_icon_info
 *	Description	: This function is called the first time canvas is 
 *			  exposed, that means the first the first time file
 *			  load dialog is poped up.  This function creates
 *			  pixmaps for function and environment icons and
 *			  initilizes the data structions.  Then the icons
 *			  are display for the initial path. 
 */

void load_canvas_expose_CB( w, client_data, call_data )
Widget                  *w;
C_FileType              client_data;
XtPointer               call_data;
{
  void clear_load_icons();
  void get_load_path();
  extern void C_popup_choices();

  static int  initilize = TRUE;		/* make sure function is called once */
  XmAnyCallbackStruct   *cbs_temp = NULL; /* temp structure */
  int i;				/* index into load_icon_info */ 

        if (initilize == TRUE)
	/* the first time the canvas is expose */
        {
	    /* 
	       create a pixmap based on an external bitmap file 
	       for function file icons 
	    */
	    fio_load_info.fun_pixmap = 
		   XCreatePixmapFromBitmapData( XtDisplay( vv_toplevel ),
                	RootWindowOfScreen( XtScreen( vv_toplevel ) ),
                       	fun_bitmap_bits, fun_bitmap_width, fun_bitmap_height,
			window_defs.icon_foreground.pixel,
                	window_defs.button_background.pixel,window_defs.depth);

	    /* 
	       create a pixmap based on an external bitmap file 
	       for environment file icons 
	    */
	    fio_load_info.env_pixmap  = 
                   XCreatePixmapFromBitmapData( XtDisplay( vv_toplevel ),
                        RootWindowOfScreen( XtScreen( vv_toplevel ) ),
                        env_bitmap_bits, env_bitmap_width, env_bitmap_height,
			window_defs.icon_foreground.pixel,
                        window_defs.button_background.pixel,window_defs.depth);
		 
            /*
               create a pixmap based on an external bitmap file
               for error icons
            */
	    fio_load_info.error_pixmap  = 
                   XCreatePixmapFromBitmapData( XtDisplay( vv_toplevel ),
                        RootWindowOfScreen( XtScreen( vv_toplevel ) ),
                        error_bitmap_bits, error_bitmap_width, 
			error_bitmap_height, 
			window_defs.icon_foreground.pixel,
                        window_defs.button_background.pixel,window_defs.depth);

	    /* initilize the icon buttons  to NULL */
	    for ( i = 0; i < C_FIO_MAXFILES; ++i )
		load_icon_info[i].button = NULL;

	    /* print the icons using the initial path */
            get_load_path(fio_load_info.load_data->path_text, 
			fio_load_info.load_data, cbs_temp);

            initilize = FALSE;
        }
}


void fio_set_load_type( w, client_data, call_data )
Widget			*w;
C_FileType		client_data;
XtPointer		call_data;
{
  void 			get_load_path(); 
  Widget 		widget = NULL;
  XmAnyCallbackStruct	*temp_call_data= NULL;
  
	/* set the file type to load */
	fio_load_info.load_type = client_data;

	/* get current path and print the icons that's this new file type */
	get_load_path( widget , fio_load_info.load_data , temp_call_data );
}

/*
 *        Procedure Name: load_scrolled 
 *          Return Value: none
 *       Input Variables: scrollbar		- widget
 *			  orientation		- vertical or horizontal  
 *			  cbs			- scroll bar callback struct 
 *      Output Variables: none
 *      Global Variables: fio_load_info, load_icon_info
 *   	Description	: This function is called when the user clicks on the
 *			  Scroll bar.  It will reprint the icons on the 
 *			  canvas in order to make it seem to user that he/she
 *			  is actually scrolling the drawing area.
*/

void  load_scrolled(scrollbar, orientation, cbs)
Widget scrollbar;
int orientation;
XmScrollBarCallbackStruct *cbs;
{
  void	create_load_button();
  void  icon_load_click();
  void  draw_load_icon();

  int 		index,
		i,
		x=0,y=0,
		icon_x,icon_y, 
		n;
  Arg		args[20];
  Pixmap 	pixmap;

	for(i = fio_load_info.last_load_icon; 
	      i < fio_load_info.last_load_icon + C_MAX_ICON_PER_WINDOW; ++i)
	/* delete the icons that is on the canvas now */
	{

	    if (load_icon_info[i].button != NULL)
	    {
                if ((load_icon_info[i].file_type == C_FUNCTION_FILE) ||
                    (load_icon_info[i].file_type == C_ENVIRONMENT_FILE) ||
		    (load_icon_info[i].valid_file == FALSE) )

		/* free the pixmap that is on the icon */
                {
                        n=0;
                        XtSetArg( args[n], XmNlabelPixmap, &pixmap ); n++;
                        XtGetValues(load_icon_info[i].button, args, n);
                        XFreePixmap(XtDisplay(fio_load_info.load_data->canvas),
                	                pixmap);
                }
		else	
		{
			XtRemoveCallback(load_icon_info[i].button,
        	                        XmNexposeCallback,draw_load_icon,i);
		}

                XtRemoveCallback(load_icon_info[i].button, XmNactivateCallback,
                       		        icon_load_click, i);

		XtDestroyWidget(load_icon_info[i].button);
		load_icon_info[i].button = NULL;
	    }
	}

        for (i = 0; i < C_MAX_ICON_PER_WINDOW; ++i)
	/* print the new icons on the canvas */
        {
	    if ( x <= ((C_ICON_SPACING + C_ICON_WIDTH)*2) )
	    /* if its the first two icons per row */
	    {
		icon_x = x + C_ICON_SPACING;   		 
		x += C_ICON_WIDTH + C_ICON_SPACING;
		icon_y = y + C_ICON_SPACING;

		/* find the correct six icons to print */
		if (cbs->value != 0)
			index = i + cbs->value*3;
		else
			index = i;
		if (index < fio_load_info.num_load_icon)
		{
			/* 
			 *  create the load button with position x = icon_x,
			 *  y = icon_y
			 */
			create_load_button(index, icon_x, icon_y,
					load_icon_info[index].filename);
		}
	    }

	    if (x == ((C_ICON_SPACING + C_ICON_WIDTH) *3) ) 
	    /* there are three icons on one line, go to next line */
	    {
		x =  0;
		y += C_ICON_HEIGHT+C_ICON_SPACING;
	    }
	}

	/* since we are scrolling in row of threes, multiply by three to 
	   scrollbar value to update the first icon printed value.
	*/
	fio_load_info.last_load_icon = cbs->value*3;
}


/*
 *        Procedure Name: clear_load_icons 
 *          Return Value: none
 *       Input Variables: none 
 *      Output Variables: none
 *      Global Variables: fio_load_info, load_icon_info
 *	Description	: This function clear the canvas of any icons, memory
 *			  associated with the icons are freed accordingly
*/
void clear_load_icons()
{
  void draw_load_icon();
  void icon_load_click();

  int 		i,n;
  Pixmap 	pixmap;
  Arg		args[20];

	for(i = 0; i < C_FIO_MAXFILES; ++i)
	{
	    if (load_icon_info[i].button != NULL)
	    {
		free(load_icon_info[i].filename);
		free(load_icon_info[i].path);

		if (load_icon_info[i].used_bitmap != TRUE)
		/* 
		   if we did not use a bitmap for the icon, free the icon data
		   memory
		*/
		{ 
			if (machine_24_bit(load_icon_info[i].button))
				free(load_icon_info[i].icon_24_data);
			else
				free(load_icon_info[i].icon_8_data);
		}

		if (( load_icon_info[i].file_type == C_FUNCTION_FILE) ||
		    ( load_icon_info[i].file_type == C_ENVIRONMENT_FILE) ||
		    ( load_icon_info[i].valid_file == FALSE) )
		/* if we used a bitmap, free the bitmap */
		{
                	n=0;
       	        	XtSetArg( args[n], XmNlabelPixmap, &pixmap ); n++;
	        	XtGetValues(load_icon_info[i].button, args, n);
			XFreePixmap(XtDisplay(fio_load_info.load_data->canvas),
				pixmap);
		}
		else
		{
			XtRemoveCallback(load_icon_info[i].button,
        	                XmNexposeCallback,draw_load_icon,i);
		}

		XtRemoveCallback(load_icon_info[i].button, XmNactivateCallback,
				icon_load_click, i);
		XtDestroyWidget(load_icon_info[i].button);
		load_icon_info[i].button = NULL;
	    }
	}
}

/*
 *        Procedure Name: accept_load_callbak
 *          Return Value: none
 *       Input Variables: widget    - the accepth button
 *			  fio_load_info.load_data - fio_load_info.load_data
 *			  event	    - an X event
 *      Output Variables: none
 *      Update Variables: none
 *      Global Variables: none
 *           Description: This function is invoked when the user click on the
 *			  accept button in the load window.  It will get the 
 *			  full path name and load the file.
 */
void accept_load_callback( widget  , client_data, event)
Widget		widget;
Widget		client_data;
XEvent		event;
{
  extern int 	C_load_file();

  char  	file_name[C_MAX_STRING], 
		path_name[C_MAX_STRING], 
		fileload[C_MAX_STRING],
		temp_string[C_MAX_STRING],
		temp_msg[C_MAX_STRING];

  int		i;
  
	/* get the path name from the path widget */
	sprintf(temp_string, "%s",
			XmTextGetString( fio_load_info.load_data->path_text ) );
	
        if (get_full_path(temp_string, path_name) != TRUE)
	/* if the directory name was not correct */
        {
            sprintf(temp_msg, 
			" Can't get full directory name: %s  \n", temp_string);
            C_error_message( temp_msg);
        }
	else
	{
	    /* get the file name from the file widget */
	    sprintf(file_name , "%s",
			XmTextGetString(fio_load_info.load_data->file_text) );

	    sprintf(fileload, "%s/%s", path_name,file_name);

	    /* load the file */
	    C_load_file(fileload, fio_load_info.load_type);
	}
}
 

/*
 *        Procedure Name: get_load_path 
 *          Return Value: none
 *       Input Variables: widget    - A text area
 *			  load_data - load_data
 *			  call_data - any callback structure
 *      Output Variables: none	  
 *      Update Variables: load_data->pathname -	path name
 *			  load_data->filename -	file name
 *			  load_icon_info      -	information about icons
 *
 *      Global Variables: load_icon_info      -	information about icons
 *           Description: This function is invoked when the user hit return
 *			  in data->path_text widget.  It will read the path
 *			  name and complete it if it starts with '~'.  Then
 *			  the filename will be cleared since we are working
 *			  with a new directory.  The drawing area which 
 *			  displays the icons will be refreshed and new icons
 *			  will be printed.
 */
void	get_load_path( widget , client_data , call_data )
Widget			widget;
Fio_Dialog_Info		*client_data;
XmAnyCallbackStruct	*call_data;
{
  extern int 	get_full_path();
  void		print_load_icon();
  void  	clear_load_icons();

  char		temp_string[C_MAX_STRING], 
		temp_msg[C_MAX_STRING];
  int		i;

	/* get the path name from the path text widget */
	sprintf(temp_string , "%s",
			XmTextGetString( fio_load_info.load_data->path_text));

	/* clear since we are in a new directory */
	clear_load_icons();

	fio_load_info.last_load_icon = 0;

	sprintf(fio_load_info.load_data->pathname,"%s", temp_string);

	if (get_full_path(temp_string, fio_load_info.load_data->pathname)==TRUE)
 	{
	    /* clear the file name since we are in a new directory */
	    sprintf(fio_load_info.load_data->filename, "");
	    XmTextSetString(fio_load_info.load_data->file_text,"");
	    XmTextSetString(fio_load_info.load_data->message,"");

	    /* print icons for all the valid files */
	    print_load_icon();
	}
	else
	{
	    /* can't get full path name for the path beginning with ~ */
	    sprintf(temp_msg, "  Can't get full directory name: %s  \n",
					 temp_string);
	    C_error_message( temp_msg);
	}
}

/*
 *        Procedure Name: get_load_file 
 *          Return Value: none
 *       Input Variables: widget    			- a text area
 *			  fio_load_info.load_data 	- load data
 *			  call_data 			- callback structure
 *      Output Variables: none
 *      Update Variables: 
 *      Global Variables: fio_load_info.load_data - load data
 *           Description: This function is called when the user hit enter
 *			  on the data->file_text widget. User have just entered
 *			  the file name.  Full path name is found in this
 *			  function and the file is loaded.
 */

void	get_load_file( widget , clent_data , call_data )
Widget			widget;
Fio_Dialog_Info		*clent_data;
XmAnyCallbackStruct	*call_data;
{
  extern int C_load_file();
  char  file_name[C_MAX_STRING], 
	path_name[C_MAX_STRING],
	fileload[C_MAX_STRING], 
	temp_string[C_MAX_STRING],
	temp_msg[C_MAX_STRING];
  int	i;

	/* get the path name from path widget */
	sprintf(temp_string,"%s",
			XmTextGetString(fio_load_info.load_data->path_text));
        if (get_full_path(temp_string, path_name) != TRUE)
        {
            /* can't get full path name for the path beginning with ~ */
            sprintf(temp_msg, "  Can't get full directory name: %s  \n",
                                                              temp_string);
            C_error_message( temp_msg);
        }
        else
        {
            /* get the file name to load */
	    sprintf(file_name,"%s", XmTextGetString(widget) );

	    /* get the full path name */
	    sprintf(fileload, "%s/%s",path_name,file_name);

	    /* load the file */
	    C_load_file(fileload, fio_load_info.load_type);
	}
}


/*
 *        Procedure Name: create_load_button 
 *          Return Value: none
 *       Input Variables: i		- index indicating with icon to create 
 *			  icon_x	- the x position of the icon
 *			  icon_y	- the y position of the icon
 *			  filename	- the filename which icon represents
 *      Output Variables: none
 *      Update Variables: load_icon_info 
 *      Global Variables: fio_load_info.load_data - load data
 *           Description: This function will create a button which is actually
 *			  the icon according to the x y positions passed in.
 *			  The filename that the icon represents will be 
 *			  displayed at the bottom of the icon.  For function
 *			  and environment files, a standard pixmap is put on
 *			  the button.  But for others, expose callback is 
 *			  defined so that the icon image could be drawn.
*/

void create_load_button(i,icon_x,icon_y,filename)
int i;
int icon_x;
int icon_y;
char  *filename;
{
  extern 		void set_colormap();
  void			icon_load_click();
  void  		draw_load_icon();

  int 			n;
  Arg 			args[20];
  XGCValues 		values;		/* values for graphic context */
  Pixmap 		pixmap;
  GC  			gc;
  Font			font;
  XmAnyCallbackStruct   *call_data;
  
	/************************************/
	/* Create A Drawn Button As A Icon  */    
	/************************************/
	n=0;
	XtSetArg(args[n], XmNx, icon_x);		n++;
	XtSetArg(args[n], XmNy, icon_y);		n++;
	XtSetArg(args[n], XmNwidth, C_ICON_WIDTH);	n++;
	XtSetArg(args[n], XmNheight,C_ICON_HEIGHT);	n++;
	XtSetArg(args[n], XmNborderWidth,0);		n++;
	XtSetArg(args[n], XmNshadowThickness,0);	n++;
	C_Set_Color_DrawnButton(args,n,window_defs);
	/* create a drawn button so we could put the icon image on top */
	load_icon_info[i].button = 
			XmCreateDrawnButton(fio_load_info.load_data->canvas,
			filename, args,n);
	XtManageChild(load_icon_info[i].button);

	/* adds callback when the user clicks on the button */
	XtAddCallback(load_icon_info[i].button, XmNactivateCallback,
		      	icon_load_click, i);
 

  	if ( (fio_load_info.load_type == C_ENVIRONMENT_FILE) ||
	     (fio_load_info.load_type == C_FUNCTION_FILE)    ||
	     (load_icon_info[i].valid_file == FALSE) ) 
 	{
		/* use a bitmap for icon image */
	        load_icon_info[i].used_bitmap = TRUE;
	
		/* create a gc with foreground and background color same as
		   the drawn button.
		*/
                gc = XCreateGC(XtDisplay( fio_load_info.load_data->canvas ) ,
				XtWindow(  fio_load_info.load_data->canvas ),
				NULL, NULL);

		/* set the font for the filename on the icon */
		font = XLoadFont( XtDisplay( fio_load_info.load_data->canvas),
				C_FONT);
		XSetFont( XtDisplay( fio_load_info.load_data->canvas ),
				gc, font);
		XSetForeground (XtDisplay(fio_load_info.load_data->canvas),
				gc, window_defs.icon_foreground);
		XSetBackground (XtDisplay(fio_load_info.load_data->canvas),
				gc, window_defs.button_background);

		/* create a temp pixmap  to be put on the button */
		pixmap = XCreatePixmap(
				XtDisplay( fio_load_info.load_data->canvas ) , 
				XtWindow(  fio_load_info.load_data->canvas ),
				C_ICON_WIDTH, C_ICON_HEIGHT, window_defs.depth); 
		if (fio_load_info.load_type == C_ENVIRONMENT_FILE)
			XCopyArea(XtDisplay( fio_load_info.load_data->canvas),
				fio_load_info.env_pixmap, pixmap, gc, 
				0,0,C_ICON_WIDTH, C_ICON_HEIGHT, 0,0);
		else if (fio_load_info.load_type == C_FUNCTION_FILE)
                        XCopyArea(XtDisplay( fio_load_info.load_data->canvas),
				fio_load_info.fun_pixmap, pixmap, gc, 
				0,0,C_ICON_WIDTH, C_ICON_HEIGHT, 0,0);
		else
		{
			XCopyArea(XtDisplay( fio_load_info.load_data->canvas),
				fio_load_info.error_pixmap, pixmap, gc,
				0,0,C_ICON_WIDTH, C_ICON_HEIGHT, 0,0);
		}	

		/* draw the file name on the icon */
	        XDrawImageString( XtDisplay( fio_load_info.load_data->canvas),
				pixmap,gc,10,113, filename, strlen(filename));
		
		/* set the label of the button to the pixmap */
                n=0;
       	        XtSetArg( args[n], XmNlabelType, XmPIXMAP ); n++;
       	        XtSetArg( args[n], XmNlabelPixmap, pixmap ); n++;
	        XtSetValues(load_icon_info[i].button, args, n);

	        XFreeGC(XtDisplay( fio_load_info.load_data->canvas ), gc);
		XUnloadFont(XtDisplay(fio_load_info.load_data->canvas), font);
	}
	else
	{
		/* didn't use a bitmap for icon */
		load_icon_info[i].used_bitmap = FALSE;
		/* draw the icon image on the button */
		XtAddCallback(load_icon_info[i].button,
                                XmNexposeCallback,draw_load_icon,i);
	}
}

/*
 *        Procedure Name: print_load_icon
 *          Return Value: none
 *       Input Variables: none
 *      Output Variables: none
 *      Update Variables: load_icon_info  - information about icons
 *      Global Variables: load_icon_info  - information about icons
 *			  fio_load_info.load_data	  - load data
 *           Description: This function will print the icons on the drawing
 *			  area already set up.  If the path name is valid,
 *			  then it updates load_icon_info, a button is created
 *			  for each file and a image is put on the button. 
 *			  The file name is drawn on to the button.  There
 *			  are three buttons on each row and they are called
 *			  icons.  If the directory name is not valid, then
 *			  an error message is display and nothing happens.
 */

void print_load_icon()
{

  extern void 	create_load_icon();
  extern int  	valid_file_name();
  extern void 	get_function_header();
  void 		create_load_button();
  void 		draw_load_icon();


  char	    	temp_msg[C_MAX_STRING];
  Arg	    	args[20];
  int	    	x = 0, y = 0,
		icon_x,icon_y,		/* set the icon position */
		i = 0,
		n;
  XmString  	str;
  DIR	    	*dirp;
  struct dirent	*dp;
	
	if ((dirp = opendir(fio_load_info.load_data->pathname)) != NULL)
	/* if we were able to open the directory */
	{
	    while ((dp = readdir(dirp)) != NULL) 
	    /* while there are still file in the directory to read */
	    {
		if ( valid_file_name(fio_load_info.load_data->pathname, 
			dp->d_name, fio_load_info.load_type,
			&(load_icon_info[i])) )
		/* if its a valid file name, extension matchs the file type */
		{
		    /* if the file name has a valid extension */
		    if ((load_icon_info[i].filename = (char *) 
				malloc(C_MAX_STRING * sizeof(char))) == NULL)
		    {
			sprintf(temp_msg,
			"Out Of Memory When Storing File Name\nSystem must exit!!!\n");
			C_error_message(temp_msg);
			exit(0);
		    }
		    if ((load_icon_info[i].path = (char *)  
				malloc(C_MAX_STRING * sizeof(char))) == NULL)
		    {
                        sprintf(temp_msg,
                        "Out Of Memory When Storing File Name\nSystem must exit!!!\n");
                        C_error_message(temp_msg);
			exit(0);
		    }
		    sprintf(load_icon_info[i].filename,"%s",dp->d_name);
		    sprintf(load_icon_info[i].path,"%s",
					fio_load_info.load_data->pathname);
		    load_icon_info[i].file_type = fio_load_info.load_type;
 
		    if ( x <= ((C_ICON_SPACING + C_ICON_WIDTH)*2) )
		    {
		    /* if its the first two icon in the row */
			icon_x = x + C_ICON_SPACING;
		      
			x += C_ICON_WIDTH + C_ICON_SPACING;
			icon_y = y + C_ICON_SPACING;

			if ( i < C_MAX_ICON_PER_WINDOW )
			/* create six button for icons */
			    create_load_button(i,icon_x,icon_y,dp->d_name);

			if (fio_load_info.load_type == C_FUNCTION_FILE)
			{
			    /* get the file header */
			    get_function_header(&(load_icon_info[i]),
					fio_load_info.load_data->pathname);
			}
			else if (fio_load_info.load_type != C_ENVIRONMENT_FILE) 
			{
			    /* create the image for the icon */
			    create_load_icon(&(load_icon_info[i]),
					fio_load_info.load_data->pathname,i);
			}
		 
			if (x == ((C_ICON_SPACING + C_ICON_WIDTH) *3) ) 
			/* there are three icons on one line, go to next line */
			{
			    x = 0;
			    y +=C_ICON_HEIGHT+C_ICON_SPACING;
			}
		    }
		    i++;    /* create the next icon */
		}
	    }

	    /* update the total number  of icons */
	    fio_load_info.num_load_icon = i;

	    /* updating the scrollbar's values */        	
	    n = 0;
	    XtSetArg( args[n], XmNvalue, 0);  n++;
	    if (fio_load_info.num_load_icon/3 != 0)
	    /* if number of icon is greater than 3 */
		if (( fio_load_info.num_load_icon % 3 == 0) && 
					(fio_load_info.num_load_icon != 3))
		/* 
		   if the number is not 3 but multiples of 3, set the max
		   value of the scrollbar to num_load_icon/3 -1
 		*/
		    XtSetArg( args[n], XmNmaximum, 
					fio_load_info.num_load_icon / 3 -1);
		else
		    XtSetArg( args[n], XmNmaximum, 
					fio_load_info.num_load_icon / 3);
	    else
		    XtSetArg( args[n], XmNmaximum, 1);		
	    n++;
	}
	else
	{
	/* not a valid directory */
	    sprintf(temp_msg, "Can't open directory: %s", 
				fio_load_info.load_data->pathname);
	    C_error_message( temp_msg);

	    /* there are zero icons */
	    fio_load_info.num_load_icon = 0;

	    /* set the max value of the scrollbar to zero */
	    n = 0;
	    XtSetArg( args[n], XmNvalue, 0);		n++;
	    XtSetArg( args[n], XmNmaximum, 1);		n++;
	}

	XtSetArg( args[n], XmNsliderSize, 1);		n++;
	XtSetArg( args[n], XmNpageIncrement, 2);	n++;
	XtSetValues(fio_load_info.load_data->scrollbar, args, n);

	if (dirp != NULL)
		(void) closedir(dirp);
}

/*
 *        Procedure Name: icon_load_click
 *          Return Value: none
 *       Input Variables: widget  - a button
 *			  index	  - index into load_icon_info
 *			  cbs	  - drawn button callback structure
 *      Output Variables: none
 *      Update Variables: 
 *      Global Variables: load_icon_info  - information about icons
 *			  fio_load_info.load_data	  - load data
 *           Description: This function is invoked when the user presses
 *			  on a icon.  If the user only clicked once, then
 *			  data->file_text widget is set to the file name just
 *			  clicked, and the header information of this file 
 *			  is displayed in the data->message widget.  If the
 *			  user double clicked, we load the file.
 */

void
icon_load_click(w,index, cbs)
Widget	w;
int   index;
XmDrawnButtonCallbackStruct *cbs;
{
  extern int  	C_load_file();
  extern int  	get_full_path();
  void	  	print_load_header();

  char 		fileload[C_MAX_STRING],
   		file_name[C_MAX_STRING], 
		path_name[C_MAX_STRING],
       		temp_msg[C_MAX_STRING], 
		temp_string[C_MAX_STRING];
  int 		i;

	/* set the file widget to the current filename */
	XmTextSetString(fio_load_info.load_data->file_text, 
					load_icon_info[index].filename);

	/* print the header of the file selected */
	print_load_header(load_icon_info[index],
					fio_load_info.load_data->message);

	if(cbs->click_count == 2)
	/* if user double clicked on the icon, then load the file */
	{
	    sprintf(temp_string, "%s",
			XmTextGetString(fio_load_info.load_data->path_text));
	    sprintf(path_name,"%s", temp_string);
            if (get_full_path(temp_string, path_name) != TRUE)
            {
                /* can't get full path name for the path beginning with ~ */
                sprintf(temp_msg, 
			"Can't get full directory name: %s  \n", temp_string);
                C_error_message( temp_msg);
            }
            else
            {
	        sprintf(fileload,"%s/%s",path_name,
		  		  load_icon_info[index].filename);

		/* load the file */
	        C_load_file(fileload, fio_load_info.load_type);
	    }
	}
}

/*
 *        Procedure Name: print_load_header
 *          Return Value: none
 *       Input Variables: icon	      -	the icon that was clicked
 *			  text_window -	widget to display header information
 *      Output Variables: none
 *      Update Variables: none
 *      Global Variables: fio_load_info.load_data   - load data
 *			  load_icon_info  	    - information about icons
 *           Description: print the header information of the current file.
 *			  The header format  differs according to the 
 *			  file type.
 */
void print_load_header(icon,text_window)
Icon_Info icon;
Widget  text_window;
{
  extern char 	*get_extension();

  int   	file_id;
  int   	x_voxels , y_voxels , z_voxels ,
        	image_width, image_height, image_depth;
  float 	x_units ,  y_units ,  z_units ;
  char 		*temp_msg, *extension, *full_name, 
		unit_type[C_MAX_STRING],
 		data_modif[C_MAX_STRING],
		data_compression[C_MAX_STRING],
		bits_per_voxel[C_MAX_STRING],
		data_origin[C_MAX_STRING], 
		render_type[C_MAX_STRING],
		image_accuracy[C_MAX_STRING],
		compute_time[C_MAX_STRING],
		compute_shadows[C_MAX_STRING],
		transmission[C_MAX_STRING],
		level_of_reflection[C_MAX_STRING],
		image_info[C_MAX_STRING],
		line[C_MAX_STRING];

  XmTextPosition   position;

	/* get the file extension */
        extension = get_extension(icon.filename);

	/* clear the header window */
        XmTextSetString(text_window, "");

        if (strcmp(extension,"slc")==0)
	/* if the file has a slc extension */
        {
	    if (icon.valid_file == TRUE)
	    {
		if (icon.slice_info.data_origin == C_BIORAD_CONFOCAL_DATA)
			sprintf(data_origin, "Data Origin: Biorad Confocal");
		else if (icon.slice_info.data_origin == 
						C_MAGNETIC_RESONANCE_DATA)
			sprintf(data_origin, "Data Origin: Magnetic Resonance");
		else if (icon.slice_info.data_origin ==  
						C_COMPUTED_TOMOGRAPHY_DATA)
			sprintf(data_origin,"Data Origin: Computed Tomography");
		else if (icon.slice_info.data_origin == C_SIMULATION_DATA)
			sprintf(data_origin, "Data Origin: Simulation");
		else if (icon.slice_info.data_origin == C_BINARY_VOXELIZED_DATA)
			sprintf(data_origin, "Data Origin: Binary Voxelized");
		else if (icon.slice_info.data_origin == C_FUZZY_VOXELIZED_DATA)
			sprintf(data_origin, "Data Origin: Fuzzy Voxelized");
		else if (icon.slice_info.data_origin == C_FUN_VOXELIZED_DATA)
			sprintf(data_origin,"Data Origin: Function Voxelized");
		else if (icon.slice_info.data_origin == C_OTHER_DATA_ORIGIN)
			sprintf(data_origin, "Data Origin: Other");
		else
			sprintf(data_origin, "Data Origin: Unknown");
		sprintf(line,"%s\n", data_origin);

                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);

                if (icon.slice_info.unit_type == C_METER_UNIT)
                        sprintf(unit_type, "Unit: Meter");
		else if (icon.slice_info.unit_type == C_MILLIMETER_UNIT)
                        sprintf(unit_type, "Unit: Millimeter");
		else if (icon.slice_info.unit_type ==  C_MICRON_UNIT)
                        sprintf(unit_type, "Unit: Micron");
                else if (icon.slice_info.unit_type == C_FOOT_UNIT)
                        sprintf(unit_type, "Unit: Foot");
                else if (icon.slice_info.unit_type == C_INCH_UNIT)
                        sprintf(unit_type, "Unit:Inch");
		else  
			sprintf(unit_type, "Unit Type: Unknown");

		if (icon.slice_info.data_modification == C_ORIGINAL_DATA)
			sprintf(data_modif, "Data Modification: Original");
		else if (icon.slice_info.data_modification == C_RESAMPLED_DATA)
			sprintf(data_modif, "Data Modification: Resampled");
		else if (icon.slice_info.data_modification
						== C_RESAMPLED_FILTERED_DATA)
			sprintf(data_modif,
				"Data Modification: Resampled Filtered");
		else if (icon.slice_info.data_modification == C_FILTERED_DATA)
			sprintf(data_modif, "Data Modification: Filtered");
		else if (icon.slice_info.data_modification 
						== C_OTHER_DATA_MODIFICATION)
			sprintf(data_modif, "Data Modification: Other");
		else
			sprintf(data_modif, "Data Modification: Unknown");
		sprintf(line,"%-22s\t%-30s\n", unit_type, data_modif);

       		position = XmTextGetLastPosition(text_window);
         	XmTextInsert(text_window,position,line);

		if (icon.slice_info.data_compression == C_NO_COMPRESSION)
			sprintf(data_compression, "Data Compression:  None");
		else if (icon.slice_info.data_compression 
						== C_RUN_LENGTH_ENCODE)
			sprintf(data_compression, "Data Compression: RLE");
		else
			sprintf(data_compression,"Data Compression: Unknown");

		sprintf(bits_per_voxel, "Bits Per Voxel: %d", 
			icon.slice_info.bits_per_voxel);

		sprintf(line, "%-21s\t%-30s\n", 
			bits_per_voxel, data_compression);

                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);

                sprintf(line, 
		"X Voxels: %d\tY Voxels: %d\tZ Voxels: %d\n",
			icon.slice_info.x_voxels, icon.slice_info.y_voxels, 
			icon.slice_info.z_voxels);  
		position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);

                sprintf(line, "X Units: %5.2f\tY Units: %5.2f\tZ Units: %5.2f",
                        icon.slice_info.x_units,icon.slice_info.y_units,
			icon.slice_info.z_units);
		position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);
	    }
	    else
	    {
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window, position, icon.error_msg);
	    }
	}
        else if(strcmp(extension,"img")==0)
	/* if the file has an img extension */
        {
	    if (icon.valid_file == TRUE)
	    {
		if (icon.image_info.image_accuracy == C_LOW_IMAGE_ACCURACY)
			sprintf(line, "Image Accuracy: Low\n");
		else if (icon.image_info.image_accuracy 
						== C_MEDIUM_IMAGE_ACCURACY)
			sprintf(line, "Image Accuracy: Medium\n");
		else if (icon.image_info.image_accuracy==C_HIGH_IMAGE_ACCURACY)
			sprintf(line, "Image Accuracy: High\n");
		else
			sprintf(line, "Image Accuracy: Unknown");
	
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);
	
		if (icon.image_info.render_type == C_PARC_RENDERING)
			sprintf(render_type, "Render Type: Parc");
		else if (icon.image_info.render_type == C_RAYTRACE_RENDERING)
			sprintf(render_type, "Render Type: Raytrace");
		else if (icon.image_info.render_type 
						== C_PARC_RAYTRACE_RENDERING)
			sprintf(render_type, "Render Type: Parc Raytrace");
		else if (icon.image_info.render_type == C_NAVIGATOR_RENDERING)
			sprintf(render_type, "Render Type: Navigator");
		else if (icon.image_info.render_type == C_RADIOSITY_RENDERING)
			sprintf(render_type, "Render Type: Radiosity");
		else
			sprintf(render_type, "Render Type: Unknown");

		sprintf(compute_time, "Compute Time: %5.2f", 
			icon.image_info.compute_time);

		sprintf(line, "%s\t%s\n", render_type, compute_time);
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);

		sprintf(compute_shadows, "Compute Shadows %5.2f", 
			icon.image_info.compute_shadows);
		sprintf(level_of_reflection, " Level Of Reflection: %d",
			icon.image_info.levels_of_reflection);

		sprintf(line, "%s\t%s\n", compute_shadows, 
			level_of_reflection);
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);

		sprintf(transmission, "Leval Of Transmission: %d", 
			icon.image_info.levels_of_transmission);

		sprintf(line, "%-25s\tIndirect Light: %d\n",
			      transmission, 
			      icon.image_info.levels_of_indirect_light);

                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);

		sprintf(line," Width: %d\tHeight: %d\tDepth: %d",
			      icon.image_info.width,
			      icon.image_info.height, 
			      icon.image_info.depth);

                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);
	    }
            else
            {
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window, position, icon.error_msg);
	    }
	}
        else if(strcmp(extension, "tex")==0)
	/* if the file has a tex extension */
        {
	    if (icon.valid_file == TRUE)
	    {
		sprintf(line, 
		"\n\tX Voxels: %d\n\tY Voxels: %d \n\tZ Voxels: %d\n", 
			icon.texture_info.xres, icon.texture_info.yres,
			icon.texture_info.zres);

                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);

		sprintf(line,"\tReferences: %d", 
			icon.texture_info.references);

                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);
	    }
            else
            {
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window, position, icon.error_msg);
	    }

	}
	else if(strcmp(extension, "fun") == 0)
	{
	    if( icon.valid_file == TRUE )
	    {
                if (icon.function_info.unit_type == C_METER_UNIT)
                        sprintf(line, " Unit Type: Meter\n");
                else if (icon.function_info.unit_type == C_MILLIMETER_UNIT)
                        sprintf(line, " Unit Type: Millimeter\n");
                else if (icon.function_info.unit_type ==  C_MICRON_UNIT)
                        sprintf(line, " Unit Type: Micorn\n");
                else if (icon.function_info.unit_type == C_FOOT_UNIT)
                        sprintf(line, " Unit Type: Foot\n");
                else if (icon.function_info.unit_type == C_INCH_UNIT)
                        sprintf(line, " Unit Type: Inch\n");
                else
                        sprintf(line, "Unit Type: Unknown\n");
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);

		sprintf(line," X Voxels: %d\tY Voxels: %d\tZ Voxels %d\n",
			icon.function_info.x_voxels,
			icon.function_info.y_voxels,
			icon.function_info.z_voxels);
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);

		sprintf(line," X Units: %4.1f\tY Units: %4.1f\tZ Units: %4.1f\n",
			icon.function_info.x_unit, icon.function_info.y_unit,
			icon.function_info.z_unit);
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);
		
		sprintf(line,
		" X Min: %5.2f\tY Min: %5.2f\tZ Min: %5.2f\n",
			icon.function_info.fun_x_min, 
			icon.function_info.fun_y_min, 
			icon.function_info.fun_z_min);
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);

		sprintf(line,
		" X Max: %5.2f\tY Max: %5.2f\tZ Max: %5.2f\n",
			icon.function_info.fun_x_max, 
                        icon.function_info.fun_y_max, 
                        icon.function_info.fun_z_max);
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);

		sprintf(line,
		" Segment At: %5.2f\tMap 0: %5.2f\tMap 255: %5.2f\n",
			icon.function_info.segment_at,
			icon.function_info.map_to_0,
			icon.function_info.map_to_255);
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window,position,line);

		sprintf(line," Function is:\n   %s\n", 
			icon.function_info.function);

		position = XmTextGetLastPosition(text_window);
		XmTextInsert(text_window, position, line);
	    }
	    else
	    {
                position = XmTextGetLastPosition(text_window);
                XmTextInsert(text_window, position, icon.error_msg);
	    }
	}
}

/*
 *        Procedure Name: draw_load_icon
 *          Return Value: none
 *       Input Variables: widget  - a button 
 *			  index	  - index into load_icon_info
 *			  cbs	  - any callback structure
 *      Output Variables: none
 *      Update Variables: none
 *      Global Variables: load_icon_info
 *           Description: This function will put an ximage on a button.  It 
 *			  will first determine which type of machine the user
 *			  is working with.  It could either be 24 bit, or 8.
 */
void draw_load_icon(w,index,cbs)
Widget  w;
int     index;
XmAnyCallbackStruct *cbs;
{
  extern void 	set_color_slc_8_bit();
  extern char 	*get_extension();

  XImage 	*image;
  unsigned int  *iptr,
		*temp_ptr;
  unsigned char *optr,
	 	*image_ptr;
  char 		*extension;
  int 		i=0, 
		scan_unit,
             	mask = GCForeground | GCBackground,
   		n = 0;
  Arg		args[20];
  char 		temp_msg[C_MAX_STRING];
  GC   		gc;
  XGCValues     gcv;
  Font          font;

	image_ptr = NULL;

	extension = get_extension(load_icon_info[index].filename);

	if(machine_24_bit(load_icon_info[index].button))
	/* if we are working with a 24 bit machine */
	{
		/* malloc space for a 24 bit image */
		if ((iptr =(unsigned int *)
			malloc(C_ICON_IMAGE_WIDTH * C_ICON_IMAGE_HEIGHT * 
			sizeof(unsigned int))) == NULL)
 		{
			sprintf(temp_msg,  
			"Out Of Memory When Creating Icon\nSystem Must Exit !");
			C_error_message(temp_msg);
			exit(0);
		}
		/* bytes per line in multiples of 4*/
		scan_unit = 4;
		temp_ptr = iptr;

		while (i < C_ICON_IMAGE_WIDTH * C_ICON_IMAGE_HEIGHT)
		{
			/* shift the bits, conversion of unsigned 
			   char to unsigned int 
			*/
			if ( (load_icon_info[index].icon_24_data[i] == 0) ||
			     (load_icon_info[index].icon_24_data[i] == 65793) )
			/* 
			   The HP window manager works incorrectly with those
			   two values, it uses the background color instead,
			   so we will just set the value to 3, which is very
			   close to zero angway 
			*/
 
				*(temp_ptr++) = (3 << 16) + (3 << 8) + 3;
			else
				*(temp_ptr++) = 
				    load_icon_info[index].icon_24_data[i];
			i++;
		}
		image_ptr = (unsigned char *) iptr;
	}
	else
	/* if we are working with a eight bit machine, this might have to be
	   changed if we are working with non 8 bit  machines
	*/
	{
		if ((image_ptr =(unsigned char *)
			malloc(C_ICON_IMAGE_WIDTH * C_ICON_IMAGE_HEIGHT * 
			sizeof(unsigned char))) == NULL)
		{
                        sprintf(temp_msg,  
                        "Out Of Memory When Creating Icon\nSystem Must Exit!!");
                        C_error_message(temp_msg);
			exit(0);
		}
		scan_unit = 1;
		optr = image_ptr;

		while (i < C_ICON_IMAGE_WIDTH * C_ICON_IMAGE_HEIGHT)
		{
			*(optr++) = load_icon_info[index].icon_8_data[i];
			i++;
 		}
		if (strcmp(extension, "slc") ==0)
		/* map values to the gray scale in the color map */
			set_color_slc_8_bit(
				load_icon_info[index].filename, image_ptr);
	}

	/* create an image with image_ptr defining the image */
	image = XCreateImage(XtDisplay(load_icon_info[index].button),
			     	window_defs.visual, window_defs.depth,
			     	ZPixmap,C_OFFSET,image_ptr,
			     	C_ICON_IMAGE_WIDTH,C_ICON_IMAGE_HEIGHT,
			     	C_BITMAP_PAD,C_ICON_IMAGE_WIDTH*scan_unit);

	gc = XCreateGC(XtDisplay(load_icon_info[index].button),
				XtWindow(load_icon_info[index].button),
				NULL, NULL);

	/* set the font of the file name */
	font = XLoadFont( XtDisplay(load_icon_info[index].button), C_FONT);
	XSetFont( XtDisplay(load_icon_info[index].button)  , gc, font);
        XSetForeground (XtDisplay(fio_load_info.load_data->canvas),
                                gc, window_defs.icon_foreground);
        XSetBackground (XtDisplay(fio_load_info.load_data->canvas),
                                gc, window_defs.button_background);

	/* put the x image on the button */
	XPutImage(XtDisplay(load_icon_info[index].button),
		  		XtWindow(load_icon_info[index].button),
		  		gc, image, 0, 0, 10, 0, C_ICON_IMAGE_WIDTH,
				C_ICON_IMAGE_HEIGHT);
	
	/* draw the file name on to the button */
	XDrawString(XtDisplay(load_icon_info[index].button),
		    		XtWindow(load_icon_info[index].button),
		    		gc, 10,113, 
		    		load_icon_info[index].filename, 
		    		strlen(load_icon_info[index].filename));
	XDestroyImage(image);
	free(image_ptr);
	XUnloadFont(XtDisplay(load_icon_info[index].button), font);
	XFreeGC(XtDisplay(load_icon_info[index].button), gc);
}
