 /*
  * Khoros: $Id: gen_util.c,v 1.2 1992/03/20 22:45:50 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: gen_util.c,v 1.2 1992/03/20 22:45:50 dkhoros Exp $";
#endif

 /*
  * $Log: gen_util.c,v $
 * Revision 1.2  1992/03/20  22:45:50  dkhoros
 * VirtualPatch5
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 * 
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *----------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "xprism.h"
#include "colorspace.h"
#include "xvdisplay.h"


/******************************************************************
*                                                                  
*                                                                  
*     >>>>>>>> Khoros Plot Graphics Utility  Routines <<<<<<<<
*
*              Including:  get_a_plot
*                          find_min_max
*                          check_pt_int
*			   change_sampling
*			   change_marker_type
*			   change_plot_type
*			   change_line_type
*			   delete_plot
*			   hide_plot
*			   update_perspective
*                                                                  
********************************************************************/


/************************************************************
*
*  MODULE NAME: get_a_plot
*
*      PURPOSE: puts up a list widget and allows user to select
*		one plot. 
*
*        INPUT: label - label for the list widget
*		prompt - prompt for the list widget
*		append_flag - tells what to append (if anything) to the
*			      display list.
*		APPEND_NONE - don't append anything to "plot #"	
*		APPEND_COLOR - append color in parens after "plot #"
*		APPEND_PLOT_TYPE - append plot type in parens after "plot #"
*		APPEND_MARKER_TYPE - append marker type in parens after "plot #"
*		APPEND_LINE_TYPE    - append line type in parens after "plot #"
*
*       OUTPUT: plot - pointer to the plot selected from the list by user
*
*
*   WRITTEN BY: Danielle Argiro, Mark Young, Mike Lang
*
*
*************************************************************/


XPlot *get_a_plot(label, prompt, append_flag)
char *label, *prompt;
int  append_flag;
{
	char   *mesg, temp[512], *append_string; 
	int    i, plot_id, num_plots, dummy, plotindex[20]; 
	XawListReturnStruct *list_return;
	XPlot *plot;
	char  *display_list[20];

	/* error check if no workspace or plots */
	if (gwin == NULL) 
	{
    	   mesg = xvf_strcpy("\nNo plots present!\n");
    	   xvf_error_wait(mesg, "get_plot", NULL);
           free(mesg);
	   return(NULL);
	}

	
        plot = gwin->plist;
	num_plots = 1;

	if (gwin->disp_plotnum == 0)
        {
            mesg = xvf_strcpy("No plots displayed in workspace to give information on!");
            xvf_error_wait(mesg, "change_plot_type", NULL);
            free(mesg);
            return(false);
        }

        else if (gwin->disp_plotnum > 1)
        {
	     /* construct the list to be displayed by the list */
	     num_plots = 0;
	     for (i = 0; i < gwin->plotnum; i++) 
             {
		  if (plot->active == true)
		  {
		     if (append_flag == APPEND_COLOR)
			append_string = xvf_strcpy(plot->color);
		     else if (append_flag == APPEND_PLOT_TYPE)
			append_string = plot_type_string(plot);
		     else if (append_flag == APPEND_LINE_TYPE)
			append_string = line_type_string(plot);
		     else if (append_flag == APPEND_MARKER_TYPE)
			append_string = marker_type_string(plot);
		     else 
		     {
			mesg = xvf_strcpy("\nUnknown append flag\n");
          		xvf_error_wait(mesg, "get_plot", NULL);
           		free(mesg);
			append_string = xvf_strcpy(" ");
		     }
		     if (append_flag != APPEND_NONE)
		     {
			if (VStrlen(plot->legend_str) != 0)
	                  sprintf(temp,"%s (%s)", 
				plot->legend_str, append_string);
			else
	                  sprintf(temp," plot %1d (%s)",plot->id,append_string);
		     }
		     else
		     {
			if (VStrlen(plot->legend_str) != 0)
	                  sprintf(temp,"%s",plot->legend_str);
			else
			  sprintf(temp," plot %1d", plot->id);
		     }

                     display_list[num_plots] = xvf_strcpy(temp);
		     plotindex[num_plots++] = plot->id;
		  }
	          plot = plot->next;
	     }

	     if (num_plots > 1)
	     {
	        /* put up list widget & allow user to choose one plot */
                list_return = xvf_run_list_wait(display_list, num_plots, 1,
                                             prompt, label, &dummy, FALSE);
                if (list_return == NULL) return(NULL);
	     }
	}


	for (i = 0; i < num_plots; i++)
	{
	    /*find the plot selected */

	    plot = gwin->plist;

	    if (num_plots > 1)
            {
                plot_id = plotindex[list_return->list_index];
	        while ((plot->id != plot_id) && (plot->next != NULL))
                       plot = plot->next;

	        for (i = 0; i < num_plots; i++) free(display_list[i]);
	
                if (plot->id != plot_id)
                {
                   (void) sprintf(temp, "Cannot find plot %d\n", plot_id);
                    xvf_error_wait(temp, "get_plot", NULL);
                }
	    }
	    else while (plot->active == FALSE) plot= plot->next;
	}
   
      	return(plot);
}



/************************************************************
*
*  MODULE NAME:  find_min_max
*
*      PURPOSE:  This routine is used to the minimum and maximum
*		 points for a given array.
*
*        INPUT:  plot  --  
*		 plot_type  --  
*
*       OUTPUT:
*
*    CALLED BY:  many routines
*
*   WRITTEN BY:  Mark Young
*
*
*************************************************************/


find_min_max (plot, plot_type)

XPlot *plot;
int	     plot_type;
{
	register int i, j, m;
	Vector WCmin, WCmax;
	Coord *points;
	int begin, end, nr, nc;
	int begin_x, end_x, begin_y, end_y;

	points = plot->points;

	/*
	 *  check to see if this is a 3-D or 2-D plot.  If this is a 3-D plot
	 *  then we need to also find the min & max for the z array.
	 */
	if (PLOT_TYPE_3D(plot_type))
	{
	   nc = (int)plot->row_size;
           nr = (int)plot->size/plot->row_size;

	   if(plot->begin_point.x == 0.0)
	   {
		begin_x = 1;
		end_x = nc;
	   }
	   else
	   {
	 	begin_x = (int)plot->begin_point.x;

	        if(plot->end_point.x == 0.0)
                     end_x = nc;
                else
                     end_x = (int)plot->end_point.x;
	   }
		
	   if(plot->begin_point.y == 0.0)
	   {
		begin_y = 1;
                end_y = nr;
	   }
	   else
	   {
	 	begin_y = (int)plot->begin_point.y;

	        if(plot->end_point.y == 0.0 )
                     end_y = nr;
                else
                     end_y = (int)plot->end_point.y;
	   }

	   m = (begin_x - 1)  + ((begin_y -1) * nc);
	   WCmin.x = points[m].x;
	   WCmax.x = points[m].x;
	   WCmin.y = points[m].y;
	   WCmax.y = points[m].y;
	   WCmin.z = points[m].z;
	   WCmax.z = points[m].z;
	
           for (i = (begin_y-1); i < end_y; i += (int)plot->step_size.y)
           {
               for(j = (begin_x-1); j < end_x; j += (int)plot->step_size.x)
               {
		   m = i * nc +j;

	           /*
		    *  get minimum x value
		    */
	           if (points[m].x < WCmin.x)  
		      WCmin.x = points[m].x;
    
	           else if (points[m].x > WCmax.x)
		      WCmax.x = points[m].x;
    
	           /*
		    *  get minimum y value
		    */
	           if (points[m].y < WCmin.y)  
		      WCmin.y = points[m].y;
    
	           else if (points[m].y > WCmax.y)
		      WCmax.y = points[m].y;
    
	           /*
		    *  get minimum z value
		    */
	           if (points[m].z < WCmin.z)
		      WCmin.z = points[m].z;
    
	           else if (points[m].z > WCmax.z)
		      WCmax.z = points[m].z;

		}
	   }
	}
	else  /*  this is a 2-D plot, so we ignore the z values */
	{
	   if (plot->begin_point.x == 0.0)
	   {
		begin = 1;
                end = plot->size;
	   }
	   else
	   {
		begin = (int)plot->begin_point.x;
		
	        if (plot->end_point.x == 0.0)
                     end = plot->size;
                else
                     end = (int)plot->end_point.x;
	   }

	   WCmin.x = points[begin-1].x;
	   WCmax.x = points[begin-1].x;
	   WCmin.y = points[begin - 1].y;
	   WCmax.y = points[begin - 1].y;

	   begin = (begin - 1) + (int)plot->step_size.x;
		
	   for (i = begin; i < end; i += (int)plot->step_size.x)
	   {
	       /*
		*  get minimum x value
		*/
	       if (points[i].x < WCmin.x)
		  WCmin.x = points[i].x;

	       else if (points[i].x > WCmax.x)
		  WCmax.x = points[i].x;

	       /*
		*  get minimum y value
		*/
	       if (points[i].y < WCmin.y)  
		  WCmin.y = points[i].y;

	       else if (points[i].y > WCmax.y)
		  WCmax.y = points[i].y;
	   }
	   WCmax.z = WCmin.z = 0.0;
	}
	if (WCmin.x == WCmax.x)
	{
	  WCmin.x = WCmin.x - 0.5;
	  WCmax.x = WCmax.x + 0.5;
	}
	if (WCmin.y == WCmax.y)
	{
	  WCmin.y = WCmin.y - 0.5;
	  WCmax.y = WCmax.y + 0.5;
	}
	if (WCmin.z == WCmax.z)
	{
	  WCmin.z = WCmin.z - 0.5;
	  WCmax.z = WCmax.z + 0.5;
	}

	plot->WCmin.x = WCmin.x;
	plot->WCmin.y = WCmin.y;
	plot->WCmin.z = WCmin.z;
	plot->WCmax.x = WCmax.x;
	plot->WCmax.y = WCmax.y;
	plot->WCmax.z = WCmax.z;
}



/************************************************************
*
*  MODULE NAME: check_pt_intv
*
*      PURPOSE: When there are a very large number of points
*               plotted (~ over 5000) - the drawing procedure
*               may take longer than the user wishes to wait.
*               Therefore, in such a case, the user is given the
*               option to specify the "point interval".  For instance,
*               if one imagines the plot data as a 2 X 2 array of data
*               points, they may wish to plot, in every other row, 
*               the point in every third column of the row, or something
*               like that.  This routine gives them the prompt and
*               returns their response.
*
*        INPUT: size - size of the plot in question
*               out_num - number of outputs requested (1 or 2)
*                         { some calls do not want a col_intv -
*                           esp. those called with a plot that was
*                           created with random data points, since
*                           there is no "rows" and "cols", but only
*                           an unorganized linear set of data points. }
*
*       OUTPUT: row_intv - point interval between rows (or, in the
*                          above case, simply the point interval.
*               col_intv - point interval between columns (if needed)
*
*    CALLED BY: display_plots_2D,
*               display_plots_3D,
*               display_mesh_plot,
*               display_scatter_plot
*
*   WRITTEN BY: Danielle Argiro
*
*
*************************************************************/



check_pt_intv(size, out_num, row_intv, col_intv)

int	size, out_num;
int	*row_intv, *col_intv;
{
	char temp[MAX_STRLEN];
	int done;

	if (size > 5000)
	{
           printf("\n\nYou are about to plot %d data points.\n\n", size);
           printf("\nYou have the option to plot every other point,\n");
           printf("every third point, etc. => Please note, however\n");
           printf("that doing so may result in a significant loss\n");
           printf("of accuracy.\n\n");
           printf("Example: 1 - every point to be plotted\n");
           printf("         2 - every other point to be plotted\n");
           printf("         3 - every third point to be plotted\n");
           printf("           - and so on\n");
     
           done = FALSE;
           while (!done)
	   {
               printf("Please enter a number to indicate the point \n");
               printf("interval you would ");
               if (out_num > 1)
		  printf(" like between ROWS: ");
               else
		  printf(" like: ");

               do
	       {
                  (void) fgets(temp, MAX_STRLEN, stdin);
               } while (temp[0] == '\n');
               (void) sscanf(temp, "%d", row_intv);

               if (*row_intv > 0)
		  done = TRUE;
               else
	       {
                  fprintf(stderr, "\ncheck_pt_intv:\n");
                  fprintf(stderr, "\nRow Interval must be greater than zero\n");
               }
	   }
	   done = FALSE;

	   if (out_num > 1)
	   {
              while (!done)
	      {
                 printf("\nPlease enter a number to indicate the \n");
                 printf("interval you would like between COLS: ");
                 do
		 {
                    (void) fgets(temp, MAX_STRLEN, stdin);
                 } while (temp[0] == '\n');
                 (void) sscanf(temp, "%d", col_intv);

                 if (*col_intv > 0)
		    done = TRUE;
                 else
		 {
                    fprintf(stderr, "\ncheck_pt_intv:\n\nColumn ");
                    fprintf(stderr, "\nInterval must be greater than zero\n");
                 }
              }
          }
	}
	else
	{
          *row_intv = 1;
          *col_intv = 1;
	}
}
        

/************************************************************
*
*  MODULE NAME: change_marker_type
*
*
*      PURPOSE: allows the user to change the marker type of the
*	        two dimensional linemarker or polymarker
*		plots that are currently displayed
*
*       OUTPUT: Plot displayed in the graphics workspace
*		with their new marker types (if linemarker or polymarker).
*
*    CALLED BY: main
*
*   WRITTEN BY: Danielle Argiro and Mark Young
*
*
*************************************************************/

static char *plotnames[] = {
        "plot 1", "plot 2", "plot 3", "plot 4", "plot 5", 
	"plot 6", "plot 7", "plot 8", "plot 9", "plot 10", 
	"plot 11", "plot 12", "plot 13", "plot 14", "plot 15", 
	"plot 16", "plot 17", "plot 18", "plot 19", "plot 20"};

int change_marker_type(marker)
int marker;
{
	static char *display_stat[] = { " (square)", " (triangle)", " (cross)",
				        " (bow tie)", " (arc)", " (diamond)", 
					" (circle)", " (V)", " (hexagon)",
				        " (X)", " (dot)", " (carat)", 
					" (point)", " (dagger)", " (box)"};

	char *display_list[20];

	int  displayed_marker_plots[20];
	char *tmp_prompt = "Select plot(s) to have marker changed to ";
	char *label  = "Currently Displayed Plots";
	char prompt[100], *temp, *mesg;

	XPlot *plot;

	int  num_sels;
	int  col_num = 1;
        int  user_defined = FALSE;
        int  duplicate_entries = FALSE;
        int  i, displayed_plotnum = 0;
        int  done;

	XawListReturnStruct **plist_return;
	
	if (gwin == NULL)
        {
            mesg = xvf_strcpy("No plots in workspace to change!");
            xvf_error_wait(mesg, "change_marker_type", NULL);
	    free(mesg);
            return(false);
        }
	   
	/*  all this code simply to display the appropriate prompt ! */
	switch(marker)
	{
	    case MarkerSquare:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "square");
		 break;
	    case MarkerTriangle:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "triangle");
		 break;
	    case MarkerCross:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "cross");
		 break;
	    case MarkerBowTie:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "bow tie");
		 break;
	    case MarkerArc:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "arc");
		 break;
	    case MarkerDiamond:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "diamond");
		 break;
	    case MarkerCircle:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "circle");
		 break;
	    case MarkerV:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "V");
		 break;
	    case MarkerHexagon:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "hexagon");
		 break;
	    case MarkerX:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "X");
		 break;
	    case MarkerDot:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "dot");
		 break;
	    case MarkerCaret:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "caret");
		 break;
	    case MarkerPoint:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "point");
		 break;
	    case MarkerDagger:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "dagger");
		 break;
	    case MarkerBox:
		 (void) sprintf(prompt, "%s%s", tmp_prompt, "box");
		 break;
	}
	


	plot = gwin->plist;
	num_sels = 1;

	if (gwin->disp_plotnum == 0)
	{
            mesg = xvf_strcpy("No plots in displayed workspace to change the marker types of!");
            xvf_error_wait(mesg, "change_marker_type", NULL);
	    free(mesg);
            return(false);
	}

	else if (gwin->disp_plotnum > 1)
	{

	     /* construct the list to be displayed by the multi-choice list */
            for (i = 0; i < gwin->plotnum; i++)
            {

                 if ((plot->active == TRUE) &&
		     ((plot->plot_type == PLOT_SCATTER) ||
		      (plot->plot_type == PLOT_POLYMARKER) ||
		      (plot->plot_type == PLOT_LINEMARKER)) )
	         {
                    display_list[displayed_plotnum] = malloc (25 * sizeof(char));
		    displayed_marker_plots[displayed_plotnum] = plot->id;

	            switch (plot->marker)
		    {
	    		case MarkerSquare:
                		temp = xvf_strcpy(display_stat[0]);
				break;

	    		case MarkerTriangle:
                		temp = xvf_strcpy(display_stat[1]);
				break;
				
	    		case MarkerCross:
                		temp = xvf_strcpy(display_stat[2]);
				break;

	    		case MarkerBowTie:
                		temp = xvf_strcpy(display_stat[3]);
				break;

	    		case MarkerArc:
                		temp = xvf_strcpy(display_stat[4]);
				break;
			
	    		case MarkerDiamond:
                		temp = xvf_strcpy(display_stat[5]);
				break;

	    		case MarkerCircle:
                		temp = xvf_strcpy(display_stat[6]);
				break;
			
	    		case MarkerV:
                		temp = xvf_strcpy(display_stat[7]);
				break;
			
	    		case MarkerHexagon:
                		temp = xvf_strcpy(display_stat[8]);
				break;
			
	    		case MarkerX:
                		temp = xvf_strcpy(display_stat[9]);
				break;
			
	    		case MarkerDot:
                		temp = xvf_strcpy(display_stat[10]);
				break;
			
	    		case MarkerCaret:
                		temp = xvf_strcpy(display_stat[11]);
				break;
			
	    		case MarkerPoint:
                		temp = xvf_strcpy(display_stat[12]);
				break;
			
	    		case MarkerDagger:
                		temp = xvf_strcpy(display_stat[13]);
				break;
			
	    		case MarkerBox:
                		temp = xvf_strcpy(display_stat[14]);
				break;
			
		    }
	            if (VStrlen(plot->legend_str) != 0)
	               sprintf(display_list[displayed_plotnum], 
				"%s %s",plot->legend_str, temp);
	            else
	               sprintf(display_list[displayed_plotnum], "%s%s", 
			    plotnames[plot->id-1], temp);
		    displayed_plotnum++;
		    free (temp);
	       }
               plot = plot->next;
            }

	    /* no plots displayed as marker plots */
	    if (displayed_plotnum == 0)
	    {
                mesg = xvf_strcpy("No plots displayed with markers to change!");
                xvf_error_wait(mesg, "change_marker_type", NULL);
	        free(mesg);
                return(false);
            }

	    else if (displayed_plotnum > 1)
	    {
	         /* run the list to see which plots they want to change */
	         plist_return = xvf_run_list_multsel_wait(display_list, 
				displayed_plotnum, col_num, prompt, label, 
			        user_defined, duplicate_entries, &num_sels);
	         if (plist_return == NULL) return(false);
	    }

	}
	
	
	for (i = 0; i < num_sels; i++)
        {
	    /* find the plot selected */
            plot = gwin->plist;

	    if (displayed_plotnum > 1)
	    {
                while(((displayed_marker_plots[plist_return[i]->list_index]) 
			!= plot->id) && (plot != NULL))
                          plot = plot->next;

	        if (plot == NULL)
            	{
                    mesg = xvf_strcpy("Cannot find requested plot");
                    xvf_error_wait(mesg, "change_plot_type", NULL);
		    free(mesg);
                    return(false);
                }
	    }
	    else
	    {
		done = FALSE;
	        while ( (plot != NULL) && (!done) )
		{
	           if(plot->active == FALSE || 
		      (plot->plot_type != PLOT_SCATTER && 
		       plot->plot_type != PLOT_POLYMARKER &&
		       plot->plot_type != PLOT_LINEMARKER) )
		   {
		       plot= plot->next;
		   }
		   else
		       done = TRUE;
		   
		}
	   
	    }

	    if (plot != NULL)
		plot->marker = marker;
	    else
	    {
                mesg = xvf_strcpy("Can only change marker types of Scatter Plots, Polymarker and Linemarker");
                xvf_error_wait(mesg, "change_marker_type", NULL);
	        free(mesg);
                return(false);
            }


	}

	return(true);

}


/************************************************************
*
*  MODULE NAME: change_plot_type
*
*
*      PURPOSE: allows the user to change the plot type of the
*	        two dimensional plots that are currently displayed
*
*       OUTPUT: Plot displayed in the graphics workspace
*		with their new plot types.
*
*    CALLED BY: main
*
*   WRITTEN BY: Danielle Argiro and Mark Young
*
*
*************************************************************/

int change_plot_type(plot_type)

int plot_type;
{
	char *display_list[20];
	int  displayed_plots[20];

	char *tmp_prompt = "Select plot(s) to have type changed to ";
	char *label  = "Currently Displayed Plots";
	char prompt[100], *temp, *mesg;

	XPlot *plot;

	int  num_sels;
	int  col_num = 1;
        int  user_defined = FALSE;
        int  duplicate_entries = FALSE;
        int  i, displayed_plotnum = 0;

	XawListReturnStruct **plist_return;
	
	if (gwin == NULL)
        {
            mesg = xvf_strcpy("No plots in workspace to change!");
            xvf_error_wait(mesg, "change_plot_type", NULL);
	    free(mesg);
            return(false);
        }
	   
	switch(plot_type)
	{
	    case PLOT_2D:
		 (void) sprintf(prompt, "%s     (2D)    ", tmp_prompt);
		 break;

	    case PLOT_DISCRETE:
		 (void) sprintf(prompt, "%s  (discrete)  ", tmp_prompt); 
		 break;

	    case PLOT_HISTOGRAM:
		 (void) sprintf(prompt, "%s (histogram) ", tmp_prompt); 
		 break;

	    case PLOT_POLYMARKER:
		 (void) sprintf(prompt, "%s (polymarker)", tmp_prompt); 
		 break;

	    case PLOT_LINEMARKER:
		 (void) sprintf(prompt, "%s (linemarker)", tmp_prompt);
		 break;

	    case PLOT_3D:
		 (void) sprintf(prompt, "%s     (3D)    ", tmp_prompt);
                 break;

            case PLOT_MESH:
                 (void) sprintf(prompt, "%s     (mesh)  ", tmp_prompt);
  		 break;

            case PLOT_COLORMESH:
                 (void) sprintf(prompt, "%s     (color mesh)  ", tmp_prompt);
  		 break;

            case PLOT_SCATTER:
                 (void) sprintf(prompt, "%s    (scatter)", tmp_prompt);
                 break;

            case PLOT_CONTOUR_3D:
                 (void) sprintf(prompt, "%s (contour 3D)", tmp_prompt);
                 break;

            case PLOT_CONTOUR_2D:
                 (void) sprintf(prompt, "%s (contour 2D)", tmp_prompt);
                 break;

            case PLOT_SURFACE:
                 (void) sprintf(prompt, "%s (surface)", tmp_prompt);
                 break;

            case PLOT_HORIZON:
                 (void) sprintf(prompt, "%s (horizon)", tmp_prompt);
                 break;

            case PLOT_IMPULSE:
                 (void) sprintf(prompt, "%s (impulse)", tmp_prompt);
                 break;
	}


	plot = gwin->plist;
	num_sels = 1;

	if (gwin->disp_plotnum == 0)
	{
            mesg = xvf_strcpy("No plots in displayed workspace to change the plot type of!");
            xvf_error_wait(mesg, "change_plot_type", NULL);
	    free(mesg);
            return(false);
	}

	else if (gwin->disp_plotnum > 1)
	{

	     /* construct the list to be displayed by the multi-choice list */
            for (i = 0; i < gwin->plotnum; i++)
            {

                 if (plot->active == TRUE)
	         {
                    display_list[displayed_plotnum] = malloc (MaxLength * sizeof(char));
		    displayed_plots[displayed_plotnum] = plot->id;

	            switch (plot->plot_type)
		    {
			case PLOT_2D:
                		temp = xvf_strcpy("     (2D)      ");
				break;

			case PLOT_DISCRETE:
                		temp = xvf_strcpy("  (discrete)   ");
				break;
				
			case PLOT_HISTOGRAM:
                		temp = xvf_strcpy("  (histogram)  ");
				break;

			case PLOT_POLYMARKER:
                		temp = xvf_strcpy("  (polymarker) ");
				break;

			case PLOT_LINEMARKER:
                		temp = xvf_strcpy("  (linemarker) ");
				break;

			case PLOT_3D:
                		temp = xvf_strcpy("     (3D)      ");
                 		break;

            		case PLOT_MESH:
                		temp = xvf_strcpy("    (MESH)     ");
  		 		break;

            		case PLOT_COLORMESH:
                		temp = xvf_strcpy("    (COLOR MESH)     ");
  		 		break;

            		case PLOT_SCATTER:
                		temp = xvf_strcpy("   (SCATTER)   ");
                 		break;

            		case PLOT_CONTOUR_3D:
                		temp = xvf_strcpy(" (CONTOUR 3D)  ");
                 		break;

            		case PLOT_CONTOUR_2D:
                		temp = xvf_strcpy(" (CONTOUR 2D)  ");
                 		break;

            		case PLOT_SURFACE:
                		temp = xvf_strcpy(" (SURFACE)  ");
                 		break;

            		case PLOT_IMPULSE:
                		temp = xvf_strcpy(" (IMPULSE)  ");
                 		break;

            		case PLOT_HORIZON:
                		temp = xvf_strcpy(" (HORIZON)  ");
                 		break;
		    }
	            if (VStrlen(plot->legend_str) != 0)
	               sprintf(display_list[displayed_plotnum], "%s %s",plot->legend_str, temp);
	            else
	              sprintf(display_list[displayed_plotnum], "%s%s", 
			    plotnames[plot->id-1], temp);
		    displayed_plotnum++;
		    free (temp);
	       }
               plot = plot->next;
            }

	    /* run the list to see which plots they want to change */
	    plist_return = xvf_run_list_multsel_wait(display_list, 
						    displayed_plotnum,
                                                    col_num, prompt, label, 
						    user_defined,
                                                    duplicate_entries, 
						    &num_sels);
	    if (plist_return == NULL) return(false);

	}
	

	for (i=0; i < gwin->plotnum; i++)
	   free(display_list[i]);
	
	for (i = 0; i < num_sels; i++)
        {
	    /* find the plot selected */
            plot = gwin->plist;

	    if (displayed_plotnum > 1)
	    {
                while(((displayed_plots[plist_return[i]->list_index]) 
			!= plot->id) && (plot != NULL))
                          plot = plot->next;

	        if (plot == NULL)
            	{
                    mesg = xvf_strcpy("Cannot find requested plot");
                    xvf_error_wait(mesg, "change_plot_type", NULL);
		    free(mesg);
                    return(false);
                }
	    }
	    else
	        while (plot->active == FALSE) plot= plot->next;
	   
	   plot->plot_type = plot_type;
	   if ( (plot_type == PLOT_SCATTER) || 
		(plot_type == PLOT_POLYMARKER) ||
		(plot_type == PLOT_LINEMARKER) )
		plot->line_type = SOLID;
	    
	}
	return(true);

}

/************************************************************
*
*  MODULE NAME: change_line_type
*
*
*      PURPOSE: allows the user to change the plot type of the
*	        plots that are currently displayed
*
*       OUTPUT: Plot displayed in the graphics workspace
*		with their new plot types.
*
*    CALLED BY: main
*
*   WRITTEN BY: Danielle Argiro and Mark Young
*
*
*************************************************************/

int change_line_type(line_type)
int line_type;
{

	static char *display_stat[] = { "  (Solid)    ",
					" (Dotted) ", 
					"(Dot Dashed)", 
					"(Short Dashed)", 
					"(Long Dashed)" , 
					"(Odd Dashed)" };
	char *display_list[20];
	int   displayed_plots[20];

	char *tmp_prompt = "Select plot(s) to have type changed to ";
	char *label  = "Currently Displayed Plots";
	char prompt[100], *mesg;

	XPlot *plot;

	int  num_sels;
        int  user_defined = FALSE;
        int  duplicate_entries = FALSE;
        int  i, displayed_plotnum = 0;
        int  done;

	XawListReturnStruct **plist_return;
	
	if (gwin == NULL)
        {
            mesg = xvf_strcpy("No plots in workspace to change!");
            xvf_error_wait(mesg, "change_line_type", NULL);
	    free(mesg);
            return(false);
        }
	   
	(void) sprintf(prompt, "%s%s" ,tmp_prompt, display_stat[line_type -1]);
	plot = gwin->plist;
	num_sels = 1;

	if (gwin->disp_plotnum == 0)
	{
            mesg = xvf_strcpy("No plots in displayed workspace to change the plot type of!");
            xvf_error_wait(mesg, "change_line_type", NULL);
	    free(mesg);
            return(false);
	}

	else if (gwin->disp_plotnum > 1)
	{
	     /* construct the list to be displayed by the multi-choice list */
            for (i = 0; i < gwin->plotnum; i++)
            {

                 if ( (plot->active == TRUE) &&
		      (plot->plot_type != PLOT_POLYMARKER) &&
		      (plot->plot_type != PLOT_LINEMARKER) &&
		      (plot->plot_type != PLOT_SCATTER) ) 
	         {
                    display_list[displayed_plotnum] = malloc (25 * sizeof(char));
		    displayed_plots[displayed_plotnum] = plot->id;

	            if (VStrlen(plot->legend_str) != 0)
	               sprintf(display_list[displayed_plotnum], 
					"%s %s",plot->legend_str, 
			    display_stat[plot->line_type -1]);
	            else
	               sprintf(display_list[displayed_plotnum], "%s %s", 
			    plotnames[plot->id - 1], 
			    display_stat[plot->line_type -1]);
		    displayed_plotnum++;
	         }
               plot = plot->next;
            }

	    /* no plots displayed as solid-line type plots */
	    if (displayed_plotnum == 0)
	    {
                mesg = xvf_strcpy("Cannot change line types on Polymarker, Linemarker, or Scatter plots");
                xvf_error_wait(mesg, "change_line_type", NULL);
	        free(mesg);
                return(false);
            }


	    else if (displayed_plotnum > 1)
	    {
	         /* run the list to see which plots they want to change */
	         plist_return = xvf_run_list_multsel_wait(display_list, 
				displayed_plotnum, 1, prompt, label, 
				user_defined, duplicate_entries, &num_sels);
	         if (plist_return == NULL) return(false);
	     }
	}


	for (i = 0; i < num_sels; i++)
        {
	    /* find the plot selected */
            plot = gwin->plist;

	    if (displayed_plotnum > 1)
	    {
                while(((displayed_plots[plist_return[i]->list_index]) 
			!= plot->id) && (plot != NULL))
                          plot = plot->next;

	        if (plot == NULL)
                {
                    mesg = xvf_strcpy("Cannot find requested plot");
                    xvf_error_wait(mesg, "change_line_type", NULL);
		    free(mesg);
                    return(false);
                }
	        plot->line_type = line_type;
	    }
	    else
	    {
		done = FALSE;
	        while ( (plot != NULL) && (!done) )
		{
	           if (plot->active == FALSE || 
		      (plot->plot_type == PLOT_SCATTER  ||
		       plot->plot_type == PLOT_POLYMARKER ||
		       plot->plot_type == PLOT_LINEMARKER) )
		   {
		       plot= plot->next;
		   }
		   else
		       done = TRUE;
		}
	    }
		   
	    if (plot != NULL)
	      plot->line_type = line_type;
	
	    else
	    {
                mesg = xvf_strcpy("Cannot change line types on Polymarker, Linemarker, or Scatter plots");
                xvf_error_wait(mesg, "change_line_type", NULL);
	        free(mesg);
                return(false);
	    }
	}
	return(true);
}


/************************************************************
*
*  MODULE NAME: change_sampling
*
*
*      PURPOSE: allows the user to change the data sampling of the
*	        plots that are currently displayed
*
*       OUTPUT: Plot displayed in the graphics workspace
*		with their new data sampling
*
*    CALLED BY: main
*
*   WRITTEN BY: Tom Sauer
*
*
*************************************************************/

int change_sampling(step_size_x, begin_point_x, end_point_x,
		    step_size_y, begin_point_y, end_point_y, plot_type)
int step_size_x, step_size_y;
int begin_point_x, end_point_x, begin_point_y, end_point_y;
int plot_type;
{

	char *display_list[20];
	int   displayed_plots[20];

	char *prompt2d = "Select plot(s) to have sampling changed to:\n  plot # (begin point, end point , step size)";
	char *prompt3d = "Select plot(s) to have sampling changed to:\n  plot # X: (begin point, end point, step size) Y: (begin point, end point, step size)";
	char *label  = "Currently Displayed Plots";
	char *mesg;

	XPlot *plot;

	int  num_sels;
        int  user_defined = FALSE;
        int  duplicate_entries = FALSE;
        int  i, displayed_plotnum = 0;
        int  done, first = true;
	float nc, nr;
	Coord min, max;

	XawListReturnStruct **plist_return;
	

	if (gwin == NULL)
        {
            mesg = xvf_strcpy("No plots in workspace to change!");
            xvf_error_wait(mesg, "change_sampling", NULL);
	    free(mesg);
            return(false);
        }

	plot = gwin->plist;
	num_sels = 1;

	if (gwin->disp_plotnum == 0)
	{
            mesg = xvf_strcpy("No plots in displayed workspace to change data sampling for!");
            xvf_error_wait(mesg, "change_sampling", NULL);
	    free(mesg);
            return(false);
	}

	else if (gwin->disp_plotnum > 1)
	{
	     /* construct the list to be displayed by the multi-choice list */
            for (i = 0; i < gwin->plotnum; i++)
            {

                 if (plot->active == TRUE)
	         {
                    display_list[displayed_plotnum] = malloc (70 * sizeof(char));
		    displayed_plots[displayed_plotnum] = plot->id;


                    if  (PLOT_TYPE_2D(plot_type))
	               if (VStrlen(plot->legend_str) != 0)
	                  sprintf(display_list[displayed_plotnum], 
			    "%s  X: (%d, %d, %d)", 
			    plot->legend_str, (int) plot->begin_point.x,
			    (int) plot->end_point.x, (int) plot->step_size.x);
	               else
	                  sprintf(display_list[displayed_plotnum], 
			    "%s  X: (%d, %d, %d)", 
			    plotnames[plot->id - 1], (int) plot->begin_point.x,
			    (int) plot->end_point.x, (int) plot->step_size.x);
		    else
	                if (VStrlen(plot->legend_str) != 0)
	                   sprintf(display_list[displayed_plotnum], 
			    "%s   X: (%d, %d, %d) Y: (%d, %d, %d)", 
			    plot->legend_str, (int) plot->begin_point.x,
			    (int) plot->end_point.x, (int) plot->step_size.x,
			    (int) plot->begin_point.y, (int) plot->end_point.y, 
			    (int) plot->step_size.x);
	                else
	                   sprintf(display_list[displayed_plotnum], 
			    "%s   X: (%d, %d, %d) Y: (%d, %d, %d)", 
			    plotnames[plot->id - 1], (int) plot->begin_point.x,
			    (int) plot->end_point.x, (int) plot->step_size.x,
			    (int) plot->begin_point.y, (int) plot->end_point.y, 
			    (int) plot->step_size.x);
		    displayed_plotnum++;
	         }
               plot = plot->next;
            }

	    if (displayed_plotnum == 0)
	    {
                mesg = xvf_strcpy("No plots avaliable to change!");
                xvf_error_wait(mesg, "change_line_type", NULL);
	        free(mesg);
                return(false);
            }


	    else if (displayed_plotnum >= 1)
	    {
                 if  (PLOT_TYPE_2D(plot_type))
	            plist_return = xvf_run_list_multsel_wait(display_list, 
				   displayed_plotnum, 1, prompt2d, label, 
				   user_defined, duplicate_entries, &num_sels);
		 else
	            plist_return = xvf_run_list_multsel_wait(display_list, 
				   displayed_plotnum, 1, prompt3d, label, 
				   user_defined, duplicate_entries, &num_sels);
	         if (plist_return == NULL) return(false);
	     }
	}


	for (i = 0; i < num_sels; i++)
        {
	    /* find the plot selected */
            plot = gwin->plist;

	    if (displayed_plotnum > 1)
	    {
                while(((displayed_plots[plist_return[i]->list_index]) 
			!= plot->id) && (plot != NULL))
                          plot = plot->next;

	        if (plot == NULL)
                {
                    mesg = xvf_strcpy("Cannot find requested plot");
                    xvf_error_wait(mesg, "change_sampling", NULL);
		    free(mesg);
                    return(false);
                }
	    }
	    else /* only have one plot, so find it */
	    {
		done = FALSE;
	        while ( (plot != NULL) && (!done) )
		{
	           if (plot->active == FALSE)
		       plot= plot->next;
		   else
		       done = TRUE;
		}
	    }
            if  (PLOT_TYPE_3D(plot_type))
	    {
	       nc = plot->row_size;
	       nr = plot->size/plot->row_size;
	    }

	    if  (PLOT_TYPE_2D(plot_type))
	    {

                if( end_point_x > plot->size          ||
                    begin_point_x > plot->size        ||
                    step_size_x > plot->size          ||
	            (end_point_x < begin_point_x      && 
	             end_point_x > 0 	         &&
	             begin_point_x >0)                ||
                     step_size_x == 0)
	        {
                     mesg = xvf_strcpy("The Begin point, End point or Step Size was specified incorrectly.\n\nPlease check the Begin point, End point and Step Size.");
                      xvf_error_wait(mesg, "run_attributes", NULL);
                      free(mesg);
	              return(false);
	         }
	     }

	     else  /* must be 3D */
	     {
	        if( end_point_x > nc              ||
                    begin_point_x > nc            ||
                    step_size_x > nc              ||
                    (end_point_x < begin_point_x  &&
                     end_point_x > 0              &&
                     begin_point_x >0)            ||
                     step_size_x == 0)
                {
                     mesg = xvf_strcpy("The Begin point, End point or Step Size was specified incorrectly.\n\nPlease check the Begin point, End point and Step Size.");
                     xvf_error_wait(mesg, "run_attributes", NULL);
                     free(mesg);
                     return(false);
                 }

	     }	

	     plot->begin_point.x = (float) begin_point_x;
	     plot->end_point.x = (float) end_point_x;
	     plot->step_size.x = (float) step_size_x;
             if  (PLOT_TYPE_3D(plot_type))
	     {
                if( end_point_y > nr              ||
                    begin_point_y > nr            ||
                    step_size_y > nr              ||
	            (end_point_y < begin_point_y  && 
	             end_point_y > 0 	 	  &&
	             begin_point_y >0)            ||
                     step_size_y == 0.0)
	        {
                    mesg = xvf_strcpy("The Begin point, End point or Step Size was specified incorrectly.\n\nPlease check the Begin point, End point and Step Size.");
                    xvf_error_wait(mesg, "run_attributes", NULL);
                    free(mesg);
		    return(false);
	        }

	        plot->begin_point.y = (float) begin_point_y;
	        plot->end_point.y = (float) end_point_y;
	        plot->step_size.y = (float) step_size_y;
	     }

                  /* update the plot min and max accroding to the
		   * new display sampling
		   */
	     find_min_max(plot, gwin->plot_type);
	     if (first)
	     {
		  first = False;
		  max.x = plot->WCmax.x;
		  min.x = plot->WCmin.x;
		  max.y = plot->WCmax.y;
		  min.y = plot->WCmin.y;
                  if  (PLOT_TYPE_3D(plot_type))
	          {
		    max.z = plot->WCmax.z;
		    min.z = plot->WCmin.z;
		  }
	     }
	     else
	     {
	        if (plot->WCmax.x > max.x)
                     max.x = plot->WCmax.x;

                if (plot->WCmin.x < min.x)
                     min.x = plot->WCmin.x;

                if (plot->WCmax.y > max.y)
                     max.y = plot->WCmax.y;

                if (plot->WCmin.y < min.y)
                     min.y = plot->WCmin.y;

	        if (PLOT_TYPE_3D(gwin->plot_type))
                {
                   if (plot->WCmax.z > max.z)
                        max.z = plot->WCmax.z;

                   if (plot->WCmin.z < min.z)
                        min.z = plot->WCmin.z;
                }
	     }
	}
	if (PLOT_TYPE_2D(gwin->plot_type))
	{
	   mesg = xvf_strcpy("Do you want to RESET the axes to Reflect the new display sampling of the chosen plot(s)?\n\nNOTE: This will change the current axes min, max and interval.");
           if (xvf_warn_wait(mesg, "RESET AXES", "YES","NO"))
           {
	      gwin->num_tics.x = 6;
              gwin->num_tics.y = 6;
	      set_world_coordinates(min, max, gwin->num_tics);
           }
	}
	else /* must be 3D */
	{

/* CLIPPING: remove the following 3 lines when clipping is done */

	   mesg = xvf_strcpy("Do you want to RESET the axes?\n\nNOTE: \
This will reset the axes to the smallest minimum and largest maxium since \
3D clipping has not been implemented.");
           if (xvf_warn_wait(mesg, "RESET AXES", "YES","NO"))
           {
		find_wc_min_max();
                reset_world_coordinates();
	   }

/* CLIPPING: remove comment when clipping has been done 

	   mesg = xvf_strcpy("Do you want to RESET the axes to Reflect the new display sampling of the chosen plot(s)?\n\nNOTE: This will change the current axes min, max and interval.");
           if (xvf_warn_wait(mesg, "RESET AXES", "YES","NO"))
           {
	      gwin->num_tics.x = 3;
              gwin->num_tics.y = 3;
              gwin->num_tics.z = 4;
	      set_world_coordinates(min, max, gwin->num_tics);
           }
CLIPPING: remove comment when clipping has been done */

	   free(mesg);
	}

	return(true);
}


/************************************************************
*
*   MODULE NAME: delete_plots
*
*       PURPOSE: deletes one or more plots in the workspace
*
*	 OUTPUT: none
*
*     CALLED BY: run_options
*
*    WRITTEN BY: Mike Lang & Danielle Argiro & Mark Young
*
************************************************************/

delete_plots()
{
	XawListReturnStruct **list_return;
	char *temp, *mesg;
	XPlot *plot, *prev;

	int	plot_id, plotindex[20];
	char	*display_list[20];

	char *prompt = "Delete Plot(s)",
	     *label  = "Delete Options";

	static char *display_stat[] = {" (displayed)", " (hidden)"};
	int  user_defined = FALSE;
	int  duplicate_entries = FALSE;
	int  i, num_sels = 1;

	plot = gwin->plist;
	prev = plot;

	if (gwin == NULL)
	{
	    mesg = xvf_strcpy("No plots to delete!\n");
            xvf_error_wait(mesg, "options_delete_2D", NULL);
            free(mesg);
	}
	
	/* there is only one plot displayed */
	else if (gwin->plotnum == 1)
	{
	     freeplot(plot);
	     freegwin();
	     gwin = NULL;
	     return;
	}
	else
	{

	    for (i = 0; i < gwin->plotnum; i++)
	    {
	          display_list[i] = malloc (25 * sizeof(char));

	          if (plot->active == TRUE)
	              temp = xvf_strcpy(display_stat[0]);	
	          else 
		      temp = xvf_strcpy(display_stat[1]);

	          if (VStrlen(plot->legend_str) != 0)
	             sprintf(display_list[i], "%s %s",plot->legend_str, temp);
	          else
	             sprintf(display_list[i],"plot %1d%s",plot->id,temp);
		  plotindex[i] = plot->id;
	
	          plot = plot->next;
	    }
                           
	    list_return = xvf_run_list_multsel_wait(display_list, 
						     gwin->plotnum,
						     1, prompt, label, 
						     user_defined, 
						     duplicate_entries, 
						     &num_sels);
	    for (i = 0; i < gwin->plotnum; i++)
		free(display_list[i]);

	    for (i = 0; i < num_sels; i++)
	    {
	         plot = gwin->plist;
	         prev = plot;
		 plot_id = plotindex[list_return[i]->list_index];
	    
		 plot = gwin->plist;
		 while ((plot->id != plot_id) && (plot->next != NULL))
		 {
		    prev = plot;
		    plot = plot->next;
		 }

	        if (plot->id != plot_id)
		{
	           (void) sprintf(temp, "Cannot find plot %d\n", plot_id);
                   xvf_error_wait(temp, "options_delete2", NULL);
                   return;
	        }
	   
		if(prev == plot)
		    gwin->plist = plot->next;
		else
		    prev->next = plot->next;
		    
		if (plot->active == TRUE)
		   gwin->disp_plotnum--;

	        freeplot(plot);
		gwin->plotnum--;
	   }
	   free((char *) list_return);

	   if (gwin->plist == NULL)
	   {
	      freegwin();
	      gwin = NULL;
              return;
	   }
        }
}



/************************************************************
*
*   MODULE NAME: hide_plots
*
*       PURPOSE: Hides one or more plots in the workspace
*
*	 OUTPUT: none
*
*     CALLED BY: run_options
*
*    WRITTEN BY: Mike Lang & Danielle Argiro & Mark Young
*
************************************************************/

hide_plots(num_active)
int *num_active;
{
	XawListReturnStruct **list_return;
	char *temp, *mesg;
	XPlot *plot;

	int	plot_id, plotindex[20];
	char	*display_list[20];

	char *prompt = "Toggle Plots between Hidden & Displayed:",
	     *label  = "Hide Options";

	static char *display_stat[] = {" (displayed)", " (hidden)"};
	int  user_defined = FALSE;
	int  duplicate_entries = FALSE;
	int  i, num_sels;


	if (gwin == NULL)
	{
	    mesg = xvf_strcpy("No plots to hide/display!\n");
            xvf_error_wait(mesg, "options_hide_2D", NULL);
            free(mesg);
	    return;
	}
	plot = gwin->plist;
	

	/* construct the list to be displayed by the multi-selection list */
	for (i = 0; i < gwin->plotnum; i++)
	{
	     display_list[i] = malloc (25 * sizeof(char));

	     if (plot->active == TRUE)
	        temp = xvf_strcpy(display_stat[0]);	
	     else 
		temp = xvf_strcpy(display_stat[1]);

	     if (VStrlen(plot->legend_str) != 0)
	        sprintf(display_list[i], "%s %s",plot->legend_str, temp);
	     else
	        sprintf(display_list[i],"plot %1d%s",plot->id,temp);

	     plotindex[i] = plot->id;
	
	     plot = plot->next;
	}
                           

	list_return = xvf_run_list_multsel_wait(display_list, gwin->plotnum,
						1, prompt, label, user_defined, 
						duplicate_entries, &num_sels);
	if (list_return == NULL) return;

	for (i = 0; i < num_sels; i++)
	{
	    plot_id = plotindex[list_return[i]->list_index];
	    
	    plot = gwin->plist;
	    while ((plot->id != plot_id) && (plot->next != NULL))
	       plot = plot->next;

	    if (plot->id != plot_id)
	    {
	        (void) sprintf(temp, "Cannot find plot %d\n", plot_id);
                xvf_error_wait(temp, "options_hide2", NULL);
                return;
	    }
	    
	    if (plot->active == TRUE)   /* hide a displayed plot */
	    {
		plot->active = FALSE;
		gwin->disp_plotnum--;
	    }
	    else 			   /* display a hidden plot */
	    {
		plot->active = TRUE;
		gwin->disp_plotnum++;
	    }
	    
	}

	free((char *) list_return);

	for (i = 0; i < gwin->plotnum; i++)
	   free(display_list[i]); 

	 *num_active = 0;
	 plot = gwin->plist;
	 while (plot != NULL)
	 {
            if (plot->active == TRUE)
		*num_active += 1;
	     plot = plot->next;
	 }
}

