 /*
  * Khoros: $Id$
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id$";
#endif

 /*
  * $Log$
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1991, 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 to 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 1991 by UNM */

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 >>>>
 >>>>  		        Display Creation Routines
 >>>>
 >>>>			create_class_display()
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/

#include "spectrum.h"


/********************************************************
*
*  Routine Name:  create_class_display
*
*       Purpose:  creates the display for the "Print Class" feature
*
*         Input:  parent -  the workspace on which the print class
*			     window will be created
*        Output:  none
*
*   Written  By:  conductor -i spectrum.form -l 3 -b
*
********************************************************/

#define ClassWidth 250
#define ClassHeight 70

create_class_display(parent)
Widget parent;
{
	unsigned long pixel;
	int i, j;
  	Arg arg[MaxArgs];
	char temp[MaxLength], temp2[MaxLength];
	Widget RGBlabel, clusterlabel;
	static int count = 0;

	if (count++ > 0) return;

	spc_printclass = (printclass_struct *) 
			 calloc(1, sizeof(printclass_struct));


	/*
	 *  create backplane
	 */
        i = 0;
        XtSetArg(arg[i],XtNborderWidth,1);      i++;
        XtSetArg(arg[i],XtNwidth,ClassWidth);    i++;
        XtSetArg(arg[i],XtNheight,ClassHeight);  i++;
        XtSetArg(arg[i],XtNdefaultDistance,4);  i++;
        XtSetArg(arg[i],XtNresizable, True);    i++;
        class_workspace = XtCreateManagedWidget("spc_class_workspace",
                                                formWidgetClass, parent,arg,i);
	if (xvdisplay != NULL)
	    xvd_set_colormap(class_workspace, xvdisplay->colormap);

	/*
	 *  create the box which will display current color
	 */
	i = 0;
	XtSetArg(arg[i], XtNfromVert,  NULL);				i++;
	XtSetArg(arg[i], XtNfromHoriz, NULL);				i++;
	XtSetArg(arg[i], XtNwidth, (Dimension) 30);			i++;
	XtSetArg(arg[i], XtNheight, (Dimension) 30);			i++;
	spc_printclass->colorbox = XtCreateManagedWidget("spc_pc_colorbox", 
				   simpleWidgetClass, class_workspace, arg, i);

	/*
	 *  create the label which will display current RGB values
	 */
	i = 0;
        XtSetArg(arg[i], XtNlabel, "RGB Values:");			i++;
        XtSetArg(arg[i], XtNfromVert, NULL);				i++;
	XtSetArg(arg[i], XtNfromHoriz, spc_printclass->colorbox);	i++;
	XtSetArg(arg[i], XtNborderWidth, 0);				i++;
	XtSetArg(arg[i], XtNresizable, True);				i++;
	if (xvf_font != NULL)
	{
            XtSetArg(arg[i],XtNfont, xvf_font);                         i++;
        }
	RGBlabel = XtCreateManagedWidget("spc_pc_rgblab", labelWidgetClass, 
					class_workspace,arg,i);

	i = 0;
	if (spc_legend_list != NULL)
	{
	    sprintf(temp, "%d %d %d", spc_legend_list->red,
				      spc_legend_list->green,
				      spc_legend_list->blue);
	    XtSetArg(arg[i], XtNlabel, temp);				i++;
        }
	else
	{
	    XtSetArg(arg[i], XtNlabel, "  ");                           i++;
 	}
        XtSetArg(arg[i], XtNfromVert, NULL);				i++;
        XtSetArg(arg[i], XtNfromHoriz, RGBlabel);			i++;
	XtSetArg(arg[i], XtNborderWidth, 0);				i++;
	XtSetArg(arg[i], XtNresizable, True);				i++;
	if (xvf_font != NULL)
	{
            XtSetArg(arg[i],XtNfont, xvf_font);                         i++;
        }
	spc_printclass->RGBwid = XtCreateManagedWidget("spc_pc_rgb", 
				 labelWidgetClass, class_workspace,arg,i);

	/*
	 *  create the label which will display current text
	 */
	i = 0;
        if (spc_legend_list != NULL)
        {
	    XtSetArg(arg[i], XtNlabel, spc_legend_list->text);		i++;
	}
	else
        {
            XtSetArg(arg[i], XtNlabel, "  ");                           i++;
        }
        XtSetArg(arg[i], XtNfromVert, spc_printclass->RGBwid);		i++;
	XtSetArg(arg[i], XtNfromHoriz, spc_printclass->colorbox);	i++;
	XtSetArg(arg[i], XtNwidth, 300);				i++; 
	XtSetArg(arg[i], XtNborderWidth, 0);				i++;
	XtSetArg(arg[i], XtNresizable, True);				i++;
	if (xvf_font != NULL)
	{
            XtSetArg(arg[i],XtNfont, xvf_font);                         i++;
        }
	spc_printclass->labelwid = XtCreateManagedWidget("spc_pc_text", 
				   labelWidgetClass, class_workspace,arg,i);

	/*
	 *  create the label which will display current cluster numbers 
	 */
	i = 0;
        XtSetArg(arg[i], XtNlabel, "Cluster #'s:");			i++;
        XtSetArg(arg[i], XtNfromVert, spc_printclass->colorbox);	i++;
	XtSetArg(arg[i], XtNfromHoriz, NULL);				i++;
	XtSetArg(arg[i], XtNborderWidth, 0);				i++;
	XtSetArg(arg[i], XtNresizable, True);				i++;
	if (xvf_font != NULL)
	{
            XtSetArg(arg[i],XtNfont, xvf_font);                         i++;
        }
	clusterlabel = XtCreateManagedWidget("spc_pc_rgblab", labelWidgetClass, 
					class_workspace,arg,i);
	i = 0;
        if (spc_legend_list != NULL)
	{
	    bzero(temp2, MaxLength);
	    for (j = 0; j <  spc_legend_list->clusternum; j++)
	    {
	        sprintf(temp, "%d ", spc_legend_list->clusters[j]);
	        strcat(temp2, temp);
	    }
	    XtSetArg(arg[i], XtNlabel, temp2);				i++;
	}
	else
        {
            XtSetArg(arg[i], XtNlabel, "  ");                           i++;
        }
        XtSetArg(arg[i], XtNfromVert, spc_printclass->colorbox);	i++;
	XtSetArg(arg[i], XtNfromHoriz, clusterlabel);			i++;
	XtSetArg(arg[i], XtNborderWidth, 0);				i++;
	XtSetArg(arg[i], XtNresizable, True);				i++;
	if (xvf_font != NULL)
	{
            XtSetArg(arg[i],XtNfont, xvf_font);                         i++;
        }
	spc_printclass->clusterwid = XtCreateManagedWidget("spc_pc_rgb", 
				     labelWidgetClass, class_workspace,arg,i);

	/*
	 *  create the canvas which will have little plot of map values
	 */
	i = 0;
	pixel = BlackPixel(display, DefaultScreen(display));
	XtSetArg(arg[i], XtNwidth, (Dimension) xvf_font_width*55); 	i++;
	XtSetArg(arg[i], XtNheight, (Dimension) xvf_font_height*10);  	i++;
	XtSetArg(arg[i], XtNfromVert, spc_printclass->clusterwid);    	i++;
	XtSetArg(arg[i],XtNbackground, pixel);                  	i++;
	spc_printclass->canvas =  XtCreateManagedWidget("spc_pc_canvas",
				  formWidgetClass, class_workspace, arg, i);

	XtInsertEventHandler(class_workspace, ExposureMask, FALSE, 
			     update_printclass, NULL, XtListHead);
	init_pc_graphics();

	if (spc_legend_list != NULL)
	{
	    if (spc_legend_list->clusters != NULL)
	    {
	        pixel = xvdisplay->xcolors[spc_legend_list->clusters[0]].pixel;
	        i = 0;
                XtSetArg(arg[i], XtNforeground, pixel);     i++;
                XtSetArg(arg[i], XtNbackground, pixel);     i++;
                XtSetValues(spc_printclass->colorbox, arg, i);
	    }
	}
	if (xvdisplay != NULL)
	{
	    XtInsertEventHandler(xvdisplay->raster, 
			     ExposureMask | PointerMotionMask | 
			     PointerMotionHintMask, FALSE, 
			     update_printclass, NULL, XtListHead);
	}
}

/********************************************************
*
*  Routine Name:  update_printclass
*
*       Purpose:  updates the display for the "Print Class" feature
*         Input:  widget     -  the widget for the event
*                 clientData -  not used
*                 event      -  the event
*        Output:  none
*   Written  By:  Danielle Argiro & Mark Young
*
********************************************************/

void update_printclass(widget, clientData, event)

Widget  widget;
caddr_t clientData;
XEvent  *event;
{
	char   temp[MaxLength], temp2[MaxLength];
        int    i, index, listsize;
	static int last_index = -1;
	Arg    arg[MaxArgs];
	legend_list *legend_ptr = NULL;
	static legend_list *last = NULL;
	unsigned long pixel;
	XEvent next;

	if (xvdisplay == NULL) return;

	if (event->type == Expose)
	{
	    while (XCheckWindowEvent(display, XtWindow(widget), 
		   ExposureMask, &next))
              ;
	   index = last_index;
	}
	else
	{
	   index = get_cluster(widget, -1, -1);
	   if (index == last_index) return;
	}
	if (index == -1) return;

	if (spc_legend_lookup != NULL)
	    legend_ptr = spc_legend_lookup[index];

	if (legend_ptr != NULL)
	{

	     /* update color assoc. with class */
	     pixel = xvdisplay->xcolors[legend_ptr->clusters[0]].pixel;
	     i = 0;
             XtSetArg(arg[i], XtNforeground, pixel);     i++;
             XtSetArg(arg[i], XtNbackground, pixel);     i++;
             XtSetValues(spc_printclass->colorbox, arg, i);
	      
	     /* update RGB values defining color */
	     i = 0;
	     bzero(temp, MaxLength);
	    /* sprintf(temp, "%d %d %d", legend_ptr->red,
                     legend_ptr->green, legend_ptr->blue); */
	     sprintf(temp, "%g, %g, %g", current_red_col[index],
                     current_green_col[index], current_blue_col[index]); 
             XtSetArg(arg[i], XtNlabel, temp); 			i++;
             XtSetValues(spc_printclass->RGBwid, arg, i);

	     /* update text assoc. with class */
	     i = 0;
	     XtSetArg(arg[i], XtNlabel, legend_ptr->text); 	i++;
	     XtSetArg(arg[i], XtNwidth, 300);			i++; 
	     XtSetValues(spc_printclass->labelwid, arg, i);

	     /* update cluster #'s with class */
	     bzero(temp2, MaxLength);
	     if (legend_ptr->clusternum < 10)
	        listsize  = legend_ptr->clusternum;
	     else listsize = 10;
             for (i = 0; i <  listsize; i++)
             {
            	sprintf(temp, "%d ", legend_ptr->clusters[i]);
            	strcat(temp2, temp);
             }
	     if (listsize < legend_ptr->clusternum) strcat(temp2, "...");
             i = 0;
             XtSetArg(arg[i], XtNlabel, temp2);      i++;
             XtSetValues(spc_printclass->clusterwid, arg, i);

	     last = legend_ptr;
	}
	else
	{
	     /* update color currently displayed under mouse */
	     pixel = xvdisplay->xcolors[index].pixel;
	     i = 0;
             XtSetArg(arg[i], XtNforeground, pixel);     i++;
             XtSetArg(arg[i], XtNbackground, pixel);     i++;
             XtSetValues(spc_printclass->colorbox, arg, i);

	     /* print RGB values of color currently displayed under mouse */
	     i = 0;
             XtSetArg(arg[i], XtNlabel, temp); 			i++;
	     /*
	     sprintf(temp, "%d %d %d", xvdisplay->xcolors[index].red >> 8,
		    xvdisplay->xcolors[index].green >> 8, 
		    xvdisplay->xcolors[index].blue >> 8);		
	      */
	     sprintf(temp, "%g, %g, %g", current_red_col[index],
                     current_green_col[index], current_blue_col[index]); 
             XtSetArg(arg[i], XtNlabel, temp); 			i++;
             XtSetValues(spc_printclass->RGBwid, arg, i);
	     
	     /* indicate no current class assoc. with color */
	     i = 0;
	     XtSetArg(arg[i], XtNlabel, "No Associated Class in Legend"); i++;
	     XtSetArg(arg[i], XtNwidth, 300);			i++; 
	     XtSetValues(spc_printclass->labelwid, arg, i);

	     /* cluster #'s not applicable - show current pixel value */
             i = 0;
	     sprintf(temp, "%d ", index);
             XtSetArg(arg[i], XtNlabel, temp);      i++;
             XtSetValues(spc_printclass->clusterwid, arg, i);

	}

	/*
	 *  update little plot of map values for index (cluster)
	 */
	update_pc_plot(index);
	last_index = index;
}

/********************************************************
*
*  Routine Name:  init_pc_graphics
*
*       Purpose:  makes the calls to the xvgraphics library
*		  in preparation for displaying plot of map values
*         Input:  none
*        Output:  none
*   Written  By:  Danielle Argiro
*
********************************************************/
init_pc_graphics()
{
	int  i, fontnum;
	char **fontnames, **X3D_inquire_fonts();

	X3D_init_graphics (SpcPCid, X2D);
	X2D_set_viewport(SpcPCid, 0.1, 0.9, 0.1, 0.9);
        X3D_set_X11(SpcPCid, display, NULL, spc_printclass->canvas);

	fontnames = X3D_inquire_fonts(&fontnum);
	for (i = 0; i < fontnum; i++)
	   X3D_set_font(SpcPCid, fontnames[i]);
	
	
}

/********************************************************
*
*  Routine Name:  update_pc_plot
*
*       Purpose:  updates little plot of map values for index (cluster)
*         Input:  cluster - cluster for which plot applies
*        Output:  draws the plot
*   Written  By:  Danielle Argiro
*
********************************************************/
update_pc_plot(cluster)
int cluster;
{
	int   i, x, y;
	float *row;
	Coord wcmin, wcmax;
	Coord *coords;
	Window  rootwin;
	unsigned int width, height, border_width, depth;


	/* get the row of information */
	row = (float *) malloc(spc_map_colnum * sizeof(float));
	for (i = 0; i < spc_map_colnum; i++)
	    row[i] = spc_map[i][cluster];

	/* set the world coordinate min's & max's */
	wcmin.x = 0.0;  wcmax.x = (float) spc_map_colnum-1;
	wcmin.y = 0.0;  wcmax.y = 255.0;
	X2D_set_wc_min_max(SpcPCid, wcmin, wcmax);


	coords = (Coord *) malloc(spc_map_colnum * sizeof(Coord));
	for (i = 0; i < spc_map_colnum; i++)
	{
	    coords[i].x = i;
	    coords[i].y = row[i];
	}

	X2D_clear_window(SpcPCid);
	XGetGeometry(display, XtWindow(spc_printclass->canvas), 
		     &rootwin, &x, &y, &width, &height,  &border_width, &depth);
        X2D_set_window(SpcPCid, 0, 0, (short) width, (short) height);
	draw_pc_axes(wcmin, wcmax);
	X2D_draw_linemarker(SpcPCid, coords, i, MarkerDiamond, &PlotColors[1]);
}


/****************************************************************
*
* Routine Name: draw_pc_axes
*      Purpose: draws simple axes on the scatter plot 
*	 Input: wcmin - world coordinate minimum
*		wcmax - world coordinate maximum
*       Output: none
*   Written By: Danielle Argiro
*
****************************************************************/
draw_pc_axes(wcmin, wcmax)
Coord wcmin, wcmax;
{
	int  i;
	float width, height;
	char temp[MaxLength];
	Coord  axesmin, axesmax, point1, point2; 
	Vector direction;

	axesmin.x = 0; axesmax.x = 1;
        axesmin.y = 0; axesmax.y = 1;
	X2D_set_wc_min_max(SpcPCid, axesmin, axesmax);

	/* horizontal X axis */
	X2D_set_viewport(SpcPCid, 0.0, 1.0, 0.0, 1.0);
	point1.x = 0.08; point1.y = 0.1;
	point2.x = 0.95; point2.y = 0.1;
	X2D_draw_line(SpcPCid, point1, point2, &PlotColors[0]);
	
	/* vertical Y axis */
	point1.x = 0.1; point1.y = 0.05;
	point2.x = 0.1; point2.y = 0.95;
	X2D_draw_line(SpcPCid, point1, point2, &PlotColors[0]);


	/* draw labels on X axis */
	X2D_set_viewport(SpcPCid, 0.1, 0.9, 0.0, 1.0);
	axesmin.x = 0.0; axesmax.x = (float) spc_map_colnum-1;
	axesmin.y = 0.0; axesmax.y = 1.0;
	X2D_set_wc_min_max(SpcPCid, axesmin, axesmax);

	direction.x = 1.0; direction.y = 0.0;
	width = (axesmax.x - axesmin.x)/40.0;
	height = 0.09;

	for (i = 0; i < spc_map_colnum; i++)
	{
	    /* label tic */
	    sprintf(temp, "%d", i);
	    point1.x = (float) i;
	    point1.y = 0.03;
            X2D_draw_text(SpcPCid, point1, direction, width,
                          height, temp, VStrlen(temp), &PlotColors[0]);
	}

	/* draw tic marks & labels on Y axis */
	X2D_set_viewport(SpcPCid, 0.0, 1.0, 0.1, 0.9);
        axesmin.x = 0.0; axesmax.x = 1.0;
	axesmax.y = 255.0;
        axesmin.y = 0.0; 
	width = 0.02; 
	height = (wcmax.y-wcmin.y)/11;
        X2D_set_wc_min_max(SpcPCid, axesmin, axesmax);

	point1.x = 0.08;
	point2.x = 0.1;
	point1.y = wcmin.y;
	point2.y = wcmin.y;
	X2D_draw_line(SpcPCid, point1, point2, &PlotColors[0]);

	sprintf(temp, "%d", (int) wcmin.y);
	point1.x = 0.03;
	point1.y = wcmin.y;
	X2D_draw_text(SpcPCid, point1, direction, width,
                      height, temp, VStrlen(temp), &PlotColors[0]);

	point1.x = 0.08;
        point2.x = 0.1;
        point1.y = wcmax.y;
        point2.y = wcmax.y;
	X2D_draw_line(SpcPCid, point1, point2, &PlotColors[0]);

	sprintf(temp, "%d", (int) wcmax.y);
	point1.x = 0.03;
	point1.y = wcmax.y;
	X2D_draw_text(SpcPCid, point1, direction, width,
                      height, temp, VStrlen(temp), &PlotColors[0]);

	X2D_set_viewport(SpcPCid, 0.1, 0.9, 0.1, 0.9);
	X2D_set_wc_min_max(SpcPCid, wcmin, wcmax);
}

