/*
 * National Center for SuperComputing Applications, University of Illinois
 *
 * This NCSA software product is public domain software.  Permission
 * is hereby granted to do whatever you like with it. Should you wish
 * to make a contribution towards the production of this software, please
 * send us your comments about your experience with the software,  why
 * you liked or disliked it, how you use it, and most importantly, how it
 * helps your work. We will receive your comments at softdev@ncsa.uiuc.edu.
 *
 * Please send bug reports to bugs@ncsa.uiuc.edu
 *
 * Author: Eng-Whatt Toh, National Center for Supercomputing Applications
 *         ewtoh@ncsa.uiuc.edu
 */

/*
 *	File:		gr_dsplev.c
 *	Contents:	Dspl level window functions for graphics module
 */

#include "gr_com.h"

/* min image sizes for HDF and Miriad (=300, dues to length of labels) */
#define	MINDSPLXSIZE	300
#define	MINDSPLXSIZE1	100

#define	MINDSPLYSIZE	350

#define	MAXDSPLXSIZE	600
#define	MAXDSPLYSIZE	780
#define	LEEWAY			3
#define MIRBOXHT        50 /* height of box for Miriad labels */

/* #ifdef XIMAGE_PALETTE  now dynamically choose (gr_Data.paletteEditor).
   gbourhis Feb 93 */
/* Stuff for Ximage changes. */
extern void PaletteBox();
extern void CBPalSave();
static A_Palette_t PalData = { &gr_color, NULL, gr_LoadPAL, CBPalSave};
/* #endif   XIMAGE_PALETTE */

/*
 *	Return a Cartesian Single plane window with data spreadsheet
 */
A_DsplWind_t
*gr_InitDsplLevel(header,shellName,parent,orient,scale,width,tparent)
A_DsplWind_t	*header;
char   			*shellName;
Widget 			parent;
A_Axes_t		orient;
int				scale,width;
A_CubeWind_t	*tparent;
{
	A_BossWind_t	*bossWin=tparent->parent;
	A_Data_t		*hdf=bossWin->data;
	A_DsplWind_t	*tmp;
	Widget		boxWind;
	char		label[80],axes[80];
	int			numCols,numRows,ncols,nrows;
	int			minxsize,winxsize,winysize,xsize,ysize,xaxis,yaxis;
	XImage 		*palImage;
	extern void gr_Dsplbegintrace(); 	/* jng oct24 */
	extern void gr_Dsplendtrace();   	/* jng oct24 */
	extern void gr_printimage();     	/* jng oct 2 */
	extern void gr_Dsplcontourdialog(); 	/* jng feb10 */
	extern void gr_DsplGauss(); 	 		/* jng feb-26-91 */
	extern void gr_SDSHardcopy (); 		/* jng feb-27-91 */

	gr_WidgetCursor(tparent->shell,XC_watch);

	if (hdf->format == MIRIAD)
		minxsize = MINDSPLXSIZE;
	else
		minxsize = MINDSPLXSIZE1;

	if ((tmp = (A_DsplWind_t *)td_Malloc(sizeof(A_DsplWind_t),
			   "A_DsplWind_t")) == NULL)
		return(NULL);

	tmp->scale = hdf->scale = scale;
	tmp->cull  = tparent->cull;

	tmp->width = width;
	ncols = numCols = tmp->xdim = td_HdfgetDim(hdf,orient.col);
	nrows = numRows = tmp->ydim = td_HdfgetDim(hdf,orient.row);
	tmp->zdim = td_HdfgetDim(hdf,orient.axis);


	sprintf(label,"%s: Plane %d along %s-axis",bossWin->filename,
			orient.plane,axesLabels[orient.axis -1]);

	if (orient.col < 0) xaxis = -orient.col;
	else xaxis = orient.col;
	if (orient.row < 0) yaxis = -orient.row;
	else yaxis = orient.row;

	sprintf(axes,"%s %s",axesLabels[yaxis-1],axesLabels[xaxis-1]);

	if ((tparent->interp == TRUE) && (tparent->cull == FALSE))
	{
		ncols--; nrows--;
	}



	if ((tmp->hScaleData = 
		 td_HdfgetHScale(hdf,orient.col,tparent->cull)) == NULL)
		return(NULL);
	if ((tmp->vScaleData = 
		 td_HdfgetVScale(hdf,orient.row,tparent->cull)) == NULL)
		return(NULL);
	if ((tmp->listData = td_HdfgetPlaneData(hdf,tparent->cull,
				orient.row,orient.col,orient.axis,orient.plane)) == NULL)
		return(NULL);

	if ((tmp->data = td_HdfgetPixData(hdf,
					orient.row,orient.col,orient.axis,orient.plane,
					tparent->interp,tparent->cull,
					(unsigned char)gr_color.nColors )) == NULL)
		return(NULL);

  	if((tmp->fdata = (float32*)  myGetPlaneData (hdf, tparent->cull,
      orient.row, orient.col, orient.axis, orient.plane)) ==NULL)
		return(NULL);


	if (tparent->cull == FALSE)
	{
		xsize = tmp->imagexsize	= ncols*scale;
		ysize = tmp->imageysize	= nrows*scale;
	}
	else
	{
		numCols = numCols/scale;
		if (numCols*scale<tmp->xdim) numCols++;
		tmp->xdim = numCols;
		numRows = numRows/scale;
		if (numRows*scale<tmp->ydim) numRows++;
		tmp->ydim = numRows;
		xsize = ncols/scale;
		if (xsize*scale < ncols) xsize++;
		tmp->imagexsize = xsize;
		ysize = nrows/scale;
		if (ysize*scale < nrows) ysize++;
		tmp->imageysize = ysize;
	}

    if (xsize > minxsize)
        if (xsize > MAXDSPLXSIZE)
            winxsize = MAXDSPLXSIZE;
        else
            winxsize = xsize+LEEWAY;
    else
        winxsize = minxsize;

    if (ysize > MINDSPLYSIZE)
        if (ysize > MAXDSPLYSIZE)
            winysize = MAXDSPLYSIZE;
        else
            winysize = ysize+LEEWAY;
    else
        winysize = MINDSPLYSIZE;

#ifdef MIRIADFMT
	if (hdf->format == MIRIAD) winysize += MIRBOXHT;
#endif

/* Bug in m88k compiler */
#ifdef MOTOROLA
	tmp->shell = gr_MakeWindow("XDS Cartesian Spread Sheet",gr_topLevel,
		&(tmp->win),(XtCallbackProc)gr_CloseDsplLevel,
		DSPLWIND,label,"Close",(caddr_t)tmp,110,10,winxsize+414,winysize+60);
#else
	tmp->shell = gr_MakeWindow("XDS Cartesian Spread Sheet",parent,&(tmp->win),
					(XtCallbackProc)gr_CloseDsplLevel,
					DSPLWIND,label,"Close",(caddr_t)tmp,
					110,10,winxsize+414,winysize+60);
#endif


	gr_MakeTitleBar("XDSlabel",tmp->win,axes,1,1,47,20);
	tmp->hScaleWin = 
		gr_MakeListStatic("XDSstaticlist",tmp->win,&(tmp->hScaleVPort),
					numCols,NULL,tmp->hScaleData,(caddr_t)tmp,
					51,1,319,20);
	tmp->vScaleWin = 
		gr_MakeListStatic("XDSstaticlist",tmp->win,&(tmp->vScaleVPort),
					1,NULL,tmp->vScaleData,(caddr_t)tmp,
					1,26,45,245);
	tmp->listWin =
		gr_MakeList("XDSlist",tmp->win,&(tmp->listVPort),
					VERTHORIZ,numCols,5,
					(XtCallbackProc)gr_DsplListVScroll,
					(XtCallbackProc)gr_DsplListHScroll,
					(XtCallbackProc)gr_DsplListSelect,
					tmp->listData,(caddr_t)tmp,
					51, 26, 345, 272);

	gr_ImageSetCMap(tmp->shell);

#ifdef MIRIADFMT
	if (hdf->format == MIRIAD)
	{
	boxWind = gr_MakeBulletin("XDSbulletin",tmp->win,400,1,winxsize,MIRBOXHT);
   /* initialize dialog with MIRIAD values from header. jng nov 23  */ 
	tmp->xDialog =
	  gr_MakeDialog("XDSdialog",boxWind,hdf->label[0],"0.00000",7,
			1,1,90,48);
	
	tmp->yDialog =
	  gr_MakeDialog("XDSdialog",boxWind,hdf->label[1],"0.00000",7,
			92,1,90,48);
	tmp->zDialog =
	  gr_MakeDialog("XDSdialog",boxWind,hdf->label[2],"0.00000",7,
			184,1,90,48);

	tmp->imageVPort = gr_MakeVPort("XDSvport",tmp->win,NOSCROLL,HP,
						NULL,NULL,5,(caddr_t)tmp,
					 400,53,winxsize,winysize - MIRBOXHT); /* decr winysize */ 
	}
	else
#endif
	tmp->imageVPort = gr_MakeVPort("XDSvport",tmp->win,NOSCROLL,HP,
						NULL,NULL,5,(caddr_t)tmp,
						400,1,winxsize,winysize);

	tmp->image = gr_ImageCreate(tmp->imageVPort,xsize,ysize,
						tmp->data);

	tmp->imageWin = gr_MakeImageStatic("XDSstaticimage",
					   tmp->imageVPort,tmp->image,
					   (XtCallbackProc)gr_DsplImageSelect,(caddr_t)tmp,
					   0,0,xsize,ysize);

	boxWind = gr_MakeBulletin("XDSbulletin",tmp->win,2,304,265,50);
	palImage = gr_ImageCreate(boxWind,gr_color.maxColors,30,gr_palData);
	gr_MakeImageStatic("XDSstaticimage",boxWind,palImage,
						NULL,(caddr_t)NULL,
					   1,10,256,30);


	boxWind = gr_MakeBulletin("XDSbulletin",tmp->win,270,304,122,66);

	gr_MakeToggle("XDStoggle",boxWind,"Sync",SQUARE,
		      FALSE,(XtCallbackProc)gr_DsplSetSynch,
		      (XtCallbackProc)gr_DsplUnSetSynch,(caddr_t)tmp,
		      2,2,50,14);
	
	gr_MakeToggle("XDStoggle",boxWind,"Trace",SQUARE,
		      FALSE,(XtCallbackProc)gr_Dsplbegintrace,
		      (XtCallbackProc)gr_Dsplendtrace,(caddr_t)tmp,
		      2,17,60,14);
	
	
	gr_MakeButton("XDSbutton",boxWind,"Contour",
		      (XtCallbackProc) gr_Dsplcontourdialog , (caddr_t)tmp,
		      2,32,50,16);
	
#ifdef MIRIADFMT
	gr_MakeButton("XDSbutton",boxWind,"Gauss",
		      (XtCallbackProc) gr_DsplGauss, (caddr_t)tmp,
		      2,47,50,16);
#endif
	
	
	gr_MakeButton("XDSbutton",boxWind,"Profile",
		      (XtCallbackProc)gr_DsplHistogram,(caddr_t)tmp,
		      65,2,50,16);

/* #ifdef XIMAGE_PALETTE */
	if (gr_Data.paletteEditor) /* gbourhis Feb 93 */
	  {
	    PalData.client_data = (caddr_t) tmp->shell;
	    gr_MakeButton("XDSbutton",boxWind,"Palette",
			  (XtCallbackProc)PaletteBox, (caddr_t) &PalData,
			  65,17,50,16);
	  }
	else			/* #else before */
	  gr_MakeButton("XDSbutton",boxWind,"Palette",
			(XtCallbackProc)gr_LoadPAL,(caddr_t)tmp->shell,
			65,17,50,16);
/* #endif */
	gr_MakeButton("XDSbutton",boxWind,"Save",
		      (XtCallbackProc)gr_SaveDspl,(caddr_t)tmp,
		      65,32,50,16);

	gr_MakeButton("XDSbutton",boxWind,"Print",
		      (XtCallbackProc) gr_SDSHardcopy ,(caddr_t)tmp,
		      65,47,50,16);

	tmp->numHistWins = 0;
	tmp->histWin = NULL;
	tmp->oldInd = -1;
	tmp->selX = tmp->selY = 0;
	tmp->oldX = tmp->oldY = 0;
	tmp->oldPix = (Pixel)0;
	tmp->axesOrient = orient;
	tmp->synchronize = FALSE;

	tmp->parent = tparent;
	tmp->prev = NULL;
	tmp->next = header;
	if (header != NULL)
		header->prev = tmp;

	/* init - no contour window */
	tmp->contourWin = NULL;

	/* more initiations  - for trace feature. jng dec 90  */

	tmp->traceon = 0;	/* default is no-trace */
	tmp->nselected = 0;	/* no points selected */
	tmp->ntraced = 0;	/* no points traced on image yet */
	tmp->traceX = tmp->traceY =  NULL;  

	gr_WidgetCursor(tmp->shell,XC_draped_box);
	gr_WidgetCursor(tparent->shell,XC_draped_box);
	/* gr_ImageSetCMap(tmp->shell); Has been called. gbourhis Jan 93 */

/* kludge - try forcing it to display initial Miriad display vals */
#ifdef MIRIADFMT
	
	tmp->selX = (long) hdf->crpix[0];
	tmp->selY = (long) hdf->crpix[1];
	tmp->oldX = tmp->oldY = (long) 0;
	if (hdf->format == MIRIAD)  gr_DsplMiriadValues (tmp);
#endif

	return(tmp);
}


/*
 * Close a Cartesian Single plane window
 */
void
gr_CloseDsplLevel(w, client_data, call_data)
Widget	w;
caddr_t	client_data;
caddr_t	call_data;
{
	A_DsplWind_t	*dsplWin=(A_DsplWind_t *)client_data;

	if (dsplWin != NULL)
	{
		while (dsplWin->numHistWins > 0)
			gr_CloseHistLevel(dsplWin->histWin->shell,
				(caddr_t)dsplWin->histWin,(caddr_t)NULL);

		if (dsplWin->prev != NULL)
			dsplWin->prev->next = dsplWin->next;
		else
			dsplWin->parent->dsplWin = dsplWin->next;
		
		if (dsplWin->next != NULL)
			dsplWin->next->prev = dsplWin->prev;

		dsplWin->parent->numDsplWins--;


		/* free contour window if necc */
			if (dsplWin->contourWin != NULL) { 
					gr_DsplClosecontourdialog (NULL, dsplWin->contourWin, NULL);
					dsplWin->contourWin = NULL;
					}

		/* NO NEED to free traceX and traceY - belongs to histWin */
		/* td_Free(dsplWin->traceX); td_Free(dsplWin->traceY); */

		XDestroyImage(dsplWin->image);
		td_Free((char *)dsplWin->image);
		td_Free((char *)dsplWin->data);
		td_Free(dsplWin->fdata);
		td_Free2d((char **)dsplWin->listData);
		td_Free2d((char **)dsplWin->vScaleData);
		td_Free2d((char **)dsplWin->hScaleData);

		XtDestroyWidget(dsplWin->shell);
		td_Free((char *)dsplWin);
	}
}
