/*
 * 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
 */
#if ! defined(lint) && ! defined(LINT)
static char rcs_id[] = "$Id: td_axes.c,v 1.2 1993/10/28 20:43:39 gbourhis Exp $";
#endif

/*
 *	File:		td_axes.c
 *	Contents:	Axes Planes Data calls
 *	$Log: td_axes.c,v $
 * Revision 1.2  1993/10/28  20:43:39  gbourhis
 * Display the floating point values using format %#9.3g instead of %6.2f
 *
 */

#include "td_com.h"

extern	void	td_HdfsetPixel();
extern	void	td_HdfInterpPixel();


/*
 *	Return dimension of SDS along axis
 */
int
td_HdfgetDim(hdf,axis)
A_Data_t	*hdf;
int axis;
{
	if (axis < 0)
		axis = -axis;

	return(hdf->dims[axis-1]);
}


/*
 *	Check if plane exists along axis
 */
int32
td_HdfCheckPlane(hdf,axis,planeID)
A_Data_t	*hdf;
int	axis;
int	planeID;
{
	int32 max,plane=0;

	if (planeID < 0)
		plane = 0;
	else
	{
		max = (int32)td_HdfgetDim(hdf,axis);
		if ((int32)planeID >= max)
			plane = max-1;
		else
			plane = planeID;
	}

	return(plane);
}


/*
 *	Convert numeric data to pixel data
 */
char
*td_HdfgetPixData(hdf,ys,xs,axis,planeID,interp,cull,nColors)
A_Data_t *hdf;
int 	ys,xs,axis,planeID;
Boolean	interp,cull;
unsigned char nColors;
{
	char	*data;
	short	xpos,ypos;
	int32	c=0,k=0,baseline=0,linesize,singleline;
	int32	xincr,yincr;
	int32	xstart,ystart,xend,yend,xsize,ysize;
	int32	x,y,xdim,ydim;
	int32	plane;
	int32	scale=hdf->scale;
	float32	min=hdf->min,max=hdf->max,frac=hdf->rangeFrac;
	float32	***hdfdata=hdf->data;

	plane = td_HdfCheckPlane(hdf,axis,planeID);
	xdim = td_HdfgetDim(hdf,xs);
	ydim = td_HdfgetDim(hdf,ys);
	if ((cull == FALSE) && (interp == TRUE))
	{
		xdim--; ydim--;
	}
	if (cull == FALSE)
	{
		xsize = xdim*scale; ysize = ydim*scale;
	}
	else
	{
		xsize = xdim/scale;
		if (xsize*scale < xdim) xsize++;
		ysize = ydim/scale;
		if (ysize*scale < ydim) ysize++;
	}
	data = td_Malloc1D(xsize,ysize,
			(long)(sizeof(unsigned char)),"td_Malloc1D");
	if (data == NULL)
		return((char *)NULL);

	if (xs > 0)
	{
		if (cull == FALSE)
			xincr = 1;
		else
			xincr = scale;
		xstart = 0; xend = xdim;
		xpos = 1;
	}
	else
	{
		if (cull == FALSE)
			xincr = -1;
		else
			xincr = -scale;
		if ((interp == TRUE) && (cull == FALSE))
		{
			xstart = xdim; xend = 0;
		}
		else
		{
			xstart = xdim-1; 
/*         fprintf(stderr,"kkk: **** xstart fixed here\n"); */
        /*** kkk
			xstart = xstart - (xstart % scale);
        ***/
			xend = -1;
		}
		xpos = 0;
	}
	if (ys > 0)
	{
		if (cull == FALSE)
			yincr = -1;
		else
			yincr = -scale;
		if ((interp == TRUE) && (cull == FALSE))
		{
			ystart = ydim; yend = 0;
		}
		else
		{
			ystart = ydim-1;
/*          fprintf(stderr,"kkk: **** ystart fixed here\n"); */
        /*** kkk
			ystart = ystart - (ystart % scale);
        ***/
			yend = -1;
		}
		ypos = 0;
	}
	else
	{
		if (cull == FALSE)
			yincr = 1;
		else
			yincr = scale;
		ystart = 0; yend = ydim;
		ypos = 1;
	}

	singleline = xdim*scale;
	linesize = singleline*scale;
	c = 0;

	switch(axis)
	{
		case 1: /* axis=X */
			y = ystart;
			if ((xs == 2) || (xs == -2))
			{
				while ( (ypos && (y < yend)) ||
						((!ypos) && (y > yend)) )
				{
					x = xstart;
					k = 0;
					while ( (xpos && (x < xend)) ||
							((!xpos) && (x > xend)) )
					{
						if (cull == FALSE)
						{
							if (interp == TRUE)
							td_HdfInterpPixel(scale,min,max,nColors,frac,data,
							hdfdata[plane][x][y],
							hdfdata[plane][x+xincr][y],
							hdfdata[plane][x+xincr][y+yincr],
							hdfdata[plane][x][y+yincr],
							k,baseline,singleline);
							else
							td_HdfsetPixel(scale,data,
							XDS_CNV2PIX(hdfdata[plane][x][y],
							min,max,frac,nColors),
							k,baseline,singleline);
							k += scale;
						}
						else
						{
							data[c] = XDS_CNV2PIX(hdfdata[plane][x][y],
							min,max,frac,nColors);
							c++;
						}
						x += xincr;
					}	
					baseline += linesize;
					y += yincr;
				}
			}
			else
			{
				while ( (ypos && (y < yend)) ||
						((!ypos) && (y > yend)) )
				{
					x = xstart;
					k = 0;
					while ( (xpos && (x < xend)) ||
							((!xpos) && (x > xend)) )
					{
						if (cull == FALSE)
						{
							if (interp == TRUE)
							td_HdfInterpPixel(scale,min,max,nColors,frac,data,
							hdfdata[plane][y][x],
							hdfdata[plane][y][x+xincr],
							hdfdata[plane][y+yincr][x+xincr],
							hdfdata[plane][y+yincr][x],
							k,baseline,singleline);
							else
							td_HdfsetPixel(scale,data,
							XDS_CNV2PIX(hdfdata[plane][y][x],
							min,max,frac,nColors),
							k,baseline,singleline);
							k += scale;
						}
						else
						{
							data[c] = XDS_CNV2PIX(hdfdata[plane][y][x],
							min,max,frac,nColors);
							c++;
						}
						x += xincr;
					}	
					baseline += linesize;
					y += yincr;
				}
			}
			break;
		case 2: /* axis=Y */
			y = ystart;
			if ((xs == 1) || (xs == -1))
			{
				while ( (ypos && (y < yend)) ||
						((!ypos) && (y > yend)) )
				{
					x = xstart;
					k = 0;
					while ( (xpos && (x < xend)) ||
							((!xpos) && (x > xend)) )
					{
						if (cull == FALSE)
						{
							if (interp == TRUE)
							td_HdfInterpPixel(scale,min,max,nColors,frac,data,
							hdfdata[x][plane][y],
							hdfdata[x+xincr][plane][y],
							hdfdata[x+xincr][plane][y+yincr],
							hdfdata[x][plane][y+yincr],
							k,baseline,singleline);
							else
							td_HdfsetPixel(scale,data,
							XDS_CNV2PIX(hdfdata[x][plane][y],
							min,max,frac,nColors),
							k,baseline,singleline);
							k += scale;
						}
						else
						{
							data[c] = XDS_CNV2PIX(hdfdata[x][plane][y],
							min,max,frac,nColors);
							c++;
						}
						x += xincr;
					}
					baseline += linesize;
					y += yincr;
				}
			}
			else
			{
				while ( (ypos && (y < yend)) ||
						((!ypos) && (y > yend)) )
				{
					x = xstart;
					k = 0;
					while ( (xpos && (x < xend)) ||
							((!xpos) && (x > xend)) )
					{
						if (cull == FALSE)
						{
							if (interp == TRUE)
							td_HdfInterpPixel(scale,min,max,nColors,frac,data,
							hdfdata[y][plane][x],
							hdfdata[y][plane][x+xincr],
							hdfdata[y+yincr][plane][x+xincr],
							hdfdata[y+yincr][plane][x],
							k,baseline,singleline);
							else
							td_HdfsetPixel(scale,data,
							XDS_CNV2PIX(hdfdata[y][plane][x],
							min,max,frac,nColors),
							k,baseline,singleline);
							k += scale;
						}
						else
						{
							data[c] = XDS_CNV2PIX(hdfdata[y][plane][x],
							min,max,frac,nColors);
							c++;
						}

						x += xincr;
					}	
					baseline += linesize;
					y += yincr;
				}
			}
			break;
		case 3: /* Axis=Z */
 
			y = ystart;
			if ((xs == 1) || (xs == -1))
			{
				while ( (ypos && (y < yend)) ||
						((!ypos) && (y > yend)) )
				{
					x = xstart;
					k = 0;
					while ( (xpos && (x < xend)) ||
							((!xpos) && (x > xend)) )
					{
						if (cull == FALSE)
						{

							if (interp == TRUE)
							td_HdfInterpPixel(scale,min,max,nColors,frac,data,
							hdfdata[x][y][plane],
							hdfdata[x+xincr][y][plane],
							hdfdata[x+xincr][y+yincr][plane],
							hdfdata[x][y+yincr][plane],
							k,baseline,singleline);
							else
							td_HdfsetPixel(scale,data,
							XDS_CNV2PIX(hdfdata[x][y][plane],
							min,max,frac,nColors),
							k,baseline,singleline);
							k += scale;
						}
						else
						{
							data[c] = XDS_CNV2PIX(hdfdata[x][y][plane],
							min,max,frac,nColors);
							c++;
						}

						x += xincr;
					}	
					baseline += linesize;
					y += yincr;
				}
			}
			else
			{
				while ( (ypos && (y < yend)) ||
						((!ypos) && (y > yend)) )
				{
					x = xstart;
					k=0;
					while ( (xpos && (x < xend)) ||
							((!xpos) && (x > xend)) )
					{
						if (cull == FALSE)
						{
							if (interp == TRUE)
							td_HdfInterpPixel(scale,min,max,nColors,frac,data,
							hdfdata[y][x][plane],
							hdfdata[y][x+xincr][plane],
							hdfdata[y+yincr][x+xincr][plane],
							hdfdata[y+yincr][x][plane],
							k,baseline,singleline);
							else
							td_HdfsetPixel(scale,data,
							XDS_CNV2PIX(hdfdata[y][x][plane],
							min,max,frac,nColors),
							k,baseline,singleline);
							k += scale;
						}
						else
						{
							data[c] = XDS_CNV2PIX(hdfdata[y][x][plane],
							min,max,frac,nColors);
							c++;
						}

						x += xincr;
					}	
					baseline += linesize;
					y +=  yincr;
				}
			}
			break;
	}

	return(data);
}


/*
 *	Get numeric data for spreadsheet display
 */
char
**td_HdfgetPlaneData(hdf,cull,ys,xs,axis,planeID)
A_Data_t	*hdf;
Boolean		cull;
int ys,xs,axis,planeID;
{
	char	**strngs;
	char	value[20];
	int		i=0,xpos,ypos;
	int32	xincr,yincr;
	int32	xstart,ystart;
	int32	xend,yend;
	int32	x,y;
	int32	xdim,ydim;
	int32	plane;
	float32	***hdfdata=hdf->data;

	plane = td_HdfCheckPlane(hdf,axis,planeID);

	xdim = td_HdfgetDim(hdf,xs);
	ydim = td_HdfgetDim(hdf,ys);
	strngs = td_Malloc2D((int)xdim,(int)ydim,(long)sizeof(char *),
				"td_Malloc2D");

	if (xs > 0)
	{
		xpos=1; 
		if (cull == FALSE)
			xincr = 1;
		else
			xincr = hdf->scale;
		xstart = 0;
		xend = xdim;
	}
	else
	{
		xpos=0;
		if (cull == FALSE)
		{
			xincr = -1;
			xstart = xdim-1;
		}
		else
		{
			xincr = -hdf->scale;
			xstart = xstart - (xstart % hdf->scale);
		}
		xend = -1;
	}

	if (ys > 0)
	{
		ypos=0;
		if (cull == FALSE)
		{
			yincr = -1;
			ystart = ydim-1;
		}
		else
		{
			yincr = -hdf->scale;
			ystart = ystart - (ystart % hdf->scale);
		}
		yend = -1;
	}
	else
	{
		ypos=1;
		if (cull == FALSE)
			yincr = 1;
		else
			yincr = hdf->scale;
		ystart = 0;
		yend = ydim;
	}

	switch(axis)
	{
		case 1: /* axis=X */
			y = ystart;
			while ( (ypos && (y < yend)) ||
					((!ypos) && (y > yend)) )
			{
				x = xstart;
				while ( (xpos && (x < xend)) ||
						((!xpos) && (x > xend)) )
				{
					if (xs == 2)
						sprintf(value,"%#9.3g",hdfdata[plane][x][y]);
					else
						sprintf(value,"%#9.3g",hdfdata[plane][y][x]);
					strngs[i] = td_Malloc1D(strlen(value)+1,1,(long)sizeof(char),
								"Malloc1D:string");
#ifdef RIOS
					Strcpy(strngs[i],value);
#else
					strcpy(strngs[i],value);
#endif
					i++;
					x = x + xincr;
				}	
				y = y + yincr;
			}
			break;
		case 2: /* axis=Y */
			y = ystart;
			while ( (ypos && (y < yend)) ||
					((!ypos) && (y > yend)) )
			{
				x = xstart;
				while ( (xpos && (x < xend)) ||
						((!xpos) && (x > xend)) )
				{
					if (xs == 1)
						sprintf(value,"%#9.3g",hdfdata[x][plane][y]);
					else
						sprintf(value,"%#9.3g",hdfdata[y][plane][x]);
					strngs[i] = td_Malloc1D(strlen(value)+1,1,(long)sizeof(char),
								"Malloc1D:string");
#ifdef RIOS
					Strcpy(strngs[i],value);
#else
					strcpy(strngs[i],value);
#endif
					i++;
					x = x + xincr;
				}	
				y = y + yincr;
			}
			break;
		case 3: /* Axis=Z */
			y = ystart;
			while ( (ypos && (y < yend)) ||
					((!ypos) && (y > yend)) )
			{
				x = xstart;
				while ( (xpos && (x < xend)) ||
						((!xpos) && (x > xend)) )
				{
					if (xs == 1)
						sprintf(value,"%#9.3g",hdfdata[x][y][plane]);
					else
						sprintf(value,"%#9.3g",hdfdata[y][x][plane]);
					strngs[i] = td_Malloc1D(strlen(value)+1,1,(long)sizeof(char),
								"Malloc1D:string");
#ifdef RIOS
					Strcpy(strngs[i],value);
#else
					strcpy(strngs[i],value);
#endif
					i++;
					x = x + xincr;
				}	
				y = y + yincr;
			}
			break;
	}

	strngs[i] = NULL;

	return (strngs);
}


/*
 *	Get horizontal scale values for spreadsheet display
 */
char
**td_HdfgetHScale(hdf,xs,cull)
A_Data_t	*hdf;
int xs;
Boolean cull;
{
	char	value[20];
	int		i=0;
	int		x;
	int		xdim,xpos,xsize;
	int		xincr,xstart,xend;
	char	**strngs;

	xdim = xsize = td_HdfgetDim(hdf,xs);
	if (cull == TRUE)
	{
		xsize = xsize/hdf->scale;
		if (xsize*hdf->scale < xdim)
			xsize++;
	}
	strngs = td_Malloc2D((int)xsize,(int)1,(long)sizeof(char *),
				"td_Malloc2D");

	if (xs > 0)
	{
		xpos = 1;
		if (cull == FALSE)
			xincr = 1;
		else
			xincr = hdf->scale;
		xstart = 0;
		xend = xdim;
	}
	else
	{
		xpos = 0;
		if (cull == FALSE)
		{
			xincr = -1;
			xstart = xdim-1;
		}
		else
		{
			xincr = -hdf->scale;
			xstart = xstart - (xstart % hdf->scale);
		}
		xend = -1;
	}

	x = xstart;
	while ( (xpos && (x < xend)) ||
			((!xpos) && (x > xend)) )
	{
		sprintf(value,"%9d",x);
		strngs[i] = td_Malloc1D(strlen(value)+1,1,(long)sizeof(char),
					"Malloc1D:string");
#ifdef RIOS
		Strcpy(strngs[i],value);
#else
		strcpy(strngs[i],value);
#endif
		x = x + xincr;
		i++;
	}	
	strngs[i] = NULL;

	return(strngs);
}


/*
 *	Get vertical scale values for spreadsheet display
 */
char
**td_HdfgetVScale(hdf,ys,cull)
A_Data_t	*hdf;
int ys;
Boolean	cull;
{
	char	value[20];
	int		i=0;
	int		ypos,y;
	int		ydim,ysize;
	int		yincr,ystart,yend;
	char	**strngs;

	ydim = ysize = td_HdfgetDim(hdf,ys);
	if (cull == TRUE)
	{
		ysize = ysize/hdf->scale;
		if (ysize*hdf->scale < ydim)
			ysize++;
	}
	strngs = td_Malloc2D((int)1,(int)ysize,(long)sizeof(char *),
				"td_Malloc2D");

	if (ys < 0)
	{
		ypos = 1;
		if (cull == FALSE)
			yincr = 1;
		else
			yincr = hdf->scale;
		ystart = 0;
		yend = ydim;
	}
	else
	{
		ypos = 0;
		if (cull == FALSE)
		{
			yincr = -1;
			ystart = ydim-1;
		}
		else
		{
			yincr = -hdf->scale;
			ystart = ystart - (ystart % hdf->scale);
		}
		yend = -1;
	}

	y = ystart;
	while ( (ypos && (y < yend)) ||
			((!ypos) && (y > yend)) )
	{
		sprintf(value,"%5d",y);
		strngs[i] = td_Malloc1D(strlen(value)+1,1,(long)sizeof(char),
					"Malloc1D:string");
#ifdef RIOS
		Strcpy(strngs[i],value);
#else
		strcpy(strngs[i],value);
#endif
		y = y + yincr;
		i++;
	}	
	strngs[i] = NULL;

	return(strngs);
}
