/*
*	parse.c
*
*    This set of routines takes care of the image and palette manipulations
*  after an image has been read in and displayed.
*
*  National Center for Supercomputing Applications, University of Illinois
*  153 Computing Applications Building
*  605 E. Springfield Ave.
*  Champaign, IL  61820     (217)244-0072
*
*  Quincey Koziol			August 1988
*
*/

#include "showext.h"

/**********************************************************************
*  Function	:	parse
*  Purpose	:	parse the commands that options() receives and perform the actions
*  Parameters	:
*				c -	the character command to parse
*  Returns	:	none
*  Calls	:	nopal(), textmode(), grafmode(), showpic(), showpal(),
*			findpal(), putpal(), printdir(), vgaon(), vgaoff(), DFsetfind(),
*			DFfind(), DFdup(), DFaccess(), DFputelement(),
*			squishpal(), mousefunc(), updatescrn()
*  Called by	:	options()
**********************************************************************/
void parse(c)
unsigned char c;
{
	switch (c){				/* check for each command possible */
		case 'w':		/* switch preference between expanding and interpolating */
			expandit=!expandit;
			break;

		case 'Q':		/* get out of the program entirely */
			getout=1;
			break;

		case '/':		/* slow down the animation speed */
			anispeed+=100;
			break;

		case '*':		/* speed up the animation speed */
			anispeed-=100;
			if(anispeed<0)
				anispeed=0;
			break;

		case ',':		/* expand a portion of the screen to fill the screen */
			if(mouse && mode==NO9)
				makecur9(mx,my);
			textmode();
			printf("Type Position Of The Upper Left Hand Corner Of The Square to Magnify:\n");
			printf("Input X-coordinate for upper left hand corner:");
			scanf("%d",&i);
			printf("\n\nInput Y-coordinate for upper left hand corner:");
			scanf("%d",&j);
			printf("\n\nType Position Of The Lower Right Hand Corner Of The Square to Magnify:\n");
			printf("Input X-coordinate for lower right hand corner:");
			scanf("%d",&k);
			printf("\n\nInput Y-coordinate for lower right hand corner:");
			scanf("%d",&l);
			grafmode();									/* clear the screen */
			if(expandit) {				/* if preference is to expand the image */
				if(expand(i+xoff,j+yoff,k+xoff,l+yoff)==1)			/* expand chosen area to fill screen */
					waitq();	/* wait for keypress */
			  }	/* end if */
			else {						/* if preference is to interpolate the image */
				if(interpolate(i+xoff,j+yoff,k+xoff,l+yoff)==1)			/* expand and smooth the chosen area to fill the screen */
					waitq();	/* wait for keypress */
			  }	/* end else */
			grafmode();
			updatescrn();
			break;

#ifdef QAK
		case '&':		/* bounce ball on screen, undocumented feature */
			bounce();
			break;
#endif

		case 'p':		/* move the color bar on the screen */
			if(mouse && mode==NO9)
				makecur9(mx,my);
			textmode();
			printf("Type Position To Move Upper Left Hand Corner Of The Color Bar To:\n");
			printf("Input X-coordinate for upper left hand corner:");
			scanf("%d",&i);
			printf("\n\nInput Y-coordinate for upper left hand corner:");
			scanf("%d",&j);
			if(i<0)	/* move color bar to those coor. */
				pal_xoff=0;
			else
				if(i>(maxx-256))
					pal_xoff=maxx-256;
				else
					pal_xoff=i;
			if(j<0)
				pal_yoff=0;
			else
				if(j>(maxy-8))
					pal_yoff=maxy-8;
				else
					pal_yoff=j;
			grafmode();
			updatescrn();
			break;

		case 'm':		/* attempt to activate the mouse */
#ifdef MOUSE
			if(!mouse) {	/* if the mouse is not activated then do so */
				if(before) {	/* if the mouse has been activated before, then just show cursor */
					if(mode==NO9)
						makecur9(mx,my);
					else {
						m1=1;			/* show mouse cursor */
						mousecl(&m1,&m2,&m3,&m4);
					  }	/* end else */
					mouse=1;
				  }	/* end if */
				else {			/* if the mouse has never been activated */
					m1=0;			/* reset mouse */
					m2=0;
					m3=0;
					m4=0;
					mousecl(&m1,&m2,&m3,&m4);
					if(!m1)		/* mouse not there */
						displayerr("PC Mouse not installed");
					else {	/* mouse is there */
						m1=7;				/* set min/max horizontal position */
						m3=0;
						switch(mode) {		/* get different sizes for different screens */
							case NO9:
								m4=4095;
								break;

							case VGA:
							case EGA:
							default:
								m4=639;
								break;
						  }	/* end switch */
						mousecl(&m1,&m2,&m3,&m4);
						m1=8;				/* set min/max vertical position */
						m3=0;
						switch(mode) {		/* get different sizes for different screens */
							case NO9:
								m4=4095;
								break;

							case VGA:
								m4=199;
								break;

							case EGA:
							default:
								m4=349;
								break;
						  }	/* end switch */
						mousecl(&m1,&m2,&m3,&m4);
						m1=4;				/* set mouse cursor position */
						switch(mode) {		/* get different sizes for different screens */
							case NO9:
								m3=2048;
								m4=2048;
								break;

							case VGA:
								m3=320;
								m4=100;
								break;

							case EGA:
							default:
								m3=320;
								m4=175;
								break;
						  }	/* end switch */
						mousecl(&m1,&m2,&m3,&m4);
						switch(mode) {		/* decide the inital mouse positions */
							case VGA:
								mx=160;				/* set old mouse positions */
								my=100;
								break;

							case NO9:
								mx=my=256;
								break;

							case EGA:
							default:
								mx=160;
								my=175;
								break;
						  }	/* end switch */
						mouse=1;
						before=1;
						if(mode==NO9)			/* put the mouse cursor on the no9 screen */
							makecur9(mx,my);
						else
							makemouse();		/* routine to make the mouse cursor into a cross hair */
					  }	/* end else if */
				  }	/* end else */
			  }	/* end if */
			else {
				if(mode==NO9)
					makecur9(mx,my);
				else {
					m1=2;		/* function to remove the cursor */
					mousecl(&m1,&m2,&m3,&m4);
				  }	/* end if */
				mouse=0;	/* deactivate the mouse */
			  }	/* end else */
#endif
			break;
	
		case 'k':		/* end animation mode */
			animate=0;
			break;

		case 'i':		/* show information about screen */
			if(mouse && mode==NO9)
				makecur9(mx,my);
			textmode();
			printf("Information Screen\n\n");
			printf("Coor. Of Upper Left Hand Corner = %d,%d\n\n",xoff,yoff);
			printf("X & Y Dimensions of the Image = %d,%d\n\n",xdim,ydim);
			if(expandit)
				printf("Expand Image Preference Set\n\n");
			else
				printf("Interpolate Image Preference Set\n\n");
			if(animate)
				printf("Animation Mode Active\n\n");
			else
				printf("Animation Mode Not Active\n\n");
			if(mouse)
				printf("Mouse Activated\n\n");
			else
				printf("Mouse Not Activated\n\n");
			printf("Hit <enter> To Continue\n");
			waitq();	/* wait for keypress */
			grafmode();
			updatescrn();
			break;

		case 'h':		/* enter fiddle mode */
			c=' ';
			if (kbhit()) {
				c=getch();
				if(c==0)		/* check for extended character code */
					c=getch()|(unsigned char)128;	/* set high bit to indicate extended code */
			  }	/* end if */
			offset=0;
			slope=10;
			while(c!=13) {
				switch(c) {		/* check for proper fiddle commands */
					case '?':		/* help on fiddle commands */
						if(mouse && mode==NO9)
							makecur9(mx,my);
						textmode();
						printf("Fiddle Help Screen\n\n");
						printf("<left arrow>\t - Shift Palette To The Left\n");
						printf("<right arrow>\t - Shift Palette To The Right\n");
						printf("<up arrow>\t - Compress Palette\n");
						printf("<down arrow>\t - Expand Palette\n");
						printf("<enter>\t\t - Exit Fiddle Mode\n");
						printf("?\t\t - Show Help Screen\n\n");
						printf("Hit <enter> To Resume Fiddling\n");
						waitq();	/* wait for keypress */
						grafmode();
						updatescrn();
						break;

					case SCRLLEFT:		/* shift palette left */
						offset--;
						squishpal(slope,offset);
						putpal();
						break;

					case SCRLUP:		/* compress palette together */
						slope++;
						squishpal(slope,offset);
						putpal();
						break;

					case SCRLDOWN:		/* expand palette */
						slope--;
						squishpal(slope,offset);
						putpal();
						break;

					case SCRLRIGHT:		/* shift palette right */
						offset++;
						squishpal(slope,offset);
						putpal();
						break;
				  } /* end switch */
				c=getch();		/* get the next command */
				if(c==0)
					c=getch()|(unsigned char)128;	/* set high bit to indicate extended code */
			  } /* end while */
			break;

		case 'g':		/* invert the palette bitwise */
			for(j=0; j<256; j++) {
				rmap[j]=~(int)rmap[j];
				gmap[j]=~(int)gmap[j];
				bmap[j]=~(int)bmap[j];
			  }	/* end for j */
			putpal();
			break;

		case 't':		/* transpose palette */
			for(j=0; j<128; j++) {
				swap(&rmap[j],&rmap[255-j]);
				swap(&gmap[j],&gmap[255-j]);
				swap(&bmap[j],&bmap[255-j]);
			  }	/* end for j */
			putpal();
			break;

		case 'd':		/* make the current pallete into the default palette */
			if(mode!=EGA) {
				memcpy(rpal[palnum],rmap,256);
				memcpy(gpal[palnum],gmap,256);
				memcpy(bpal[palnum],bmap,256);
			  } /* end if */
			else 
				memcpy(egapals[palnum],regrs,16);
			break;

		case '+':		/* speed up the palettes rotation */
			if(mode!=EGA)
				palspeed+=100;
			else
				palspeed+=20;
			break;

		case '-':		/* slow down the palettes rotation */
			if(mode!=EGA)
				palspeed-=100;
			else
				palspeed-=20;
			if(palspeed<0)
				palspeed=0;
			break;

		case 'u':		/* swap the red, green, and blue palettes */
			memcpy(trans1,rmap,256);
			memcpy(rmap,gmap,256);
			memcpy(gmap,bmap,256);
			memcpy(bmap,trans1,256);
			putpal();
			break;

		case 's':		/* save palette to disk */
			if(filetype==HDF) { /* save the HDF palette */
				DFsetfind(dff, DFTG_IP8, DFREF_WILDCARD);	/* set the HDF file to a palette */
				while(!DFfind( dff, &ddstr)){ /* step through all the palettes */
					lasttag=ddstr.tag;
					lastref=ddstr.ref;
				  } /* end while */
				newref=lastref+1;		/* make a new reference number */
				if(DFdup(dff,imtag,newref,imtag,imref))		/* try to make a new palette space */
					displayerr("Error On DFdup");
				else { /* ok DFdup call */
					for(i=0; i<256; i++) {	/* put individual palettes into the big one */
						pal[i*3]=rmap[i];
						pal[i*3+1]=gmap[i];
						pal[i*3+2]=bmap[i];
					  } /* end for */
					i=DFaccess(dff,DFTG_IP8,newref,"w");	/* tell HDF to start writing */
					if(i<0) {
						printf("return code from DFaccess = %d\n",i);
						i=getchar();
					  } /* end if */
					if((i=DFputelement(dff,DFTG_IP8,newref,pal,(long) 768))<=0)
						displayerr("Error On DFputelement In Save Palette Subroutine");
					else
						DFupdate(dff);
					DFaccess( dff, lasttag, newref, "r");	/* tell HDF to start reading */
				  } /* end else */
			  }	/* end if */
			else{		/* save a binary palette */
				if(mouse && mode==NO9)
					makecur9(mx,my);
				textmode();
				printf("Input Name Of Palette File (or <return> to exit) ");
				readstr(&palfile[0]);
				printf("\n");
				if(*palfile!=0) {	/* if its not a null name attempt to write out file */
					if (NULL == (pfp = fopen(palfile,"wb"))) {	/* open the palette file */
				        printf("Error on palette file open\n");
						printf("Hit Any Key To Continue\n");
						waitq();
				      } /* end if */
					else {	/* write out the palette */
						fwrite(rmap,1,256,pfp);
						fwrite(gmap,1,256,pfp);
						fwrite(bmap,1,256,pfp);
						fclose(pfp);
					  } /* end else */
				  }	/* end if */
				grafmode();
				updatescrn();
			  }	/* end else */
			break;

		case 'l':		/* load in a new palette */
			if(filetype==HDF) {	/* load in a new HDF palette */
				findpal();
				putpal();
			  } /* end if */
			else {	/* load in a new binary palette */
				if(mouse && mode==NO9)
					makecur9(mx,my);
				textmode();
				*palfile='?';
				while(*palfile=='?') {
					printf("Input Name Of Palette File (or ? to display palettes): ");
					readstr(&palfile[0]);
					printf("\n");
					if(*palfile=='?')	/* print directory of palettes */
						printdir();
					else	/* just load in the palette */
						if(*palfile!=0)
							newpal(palfile);
				  } /* end while */
				grafmode();
				updatescrn();
			  } /* end else */
			break;

		case 'x':		/* get x,y coor. for upper left corner */
			if(mouse && mode==NO9)
				makecur9(mx,my);
			textmode();
			printf("Input X-coordinates for upper left hand corner:");
			scanf("%d",&i);
			printf("\n\nInput Y-coordinates for upper left hand corner:");
			scanf("%d",&j);
			if((i<0) || ((xdim-maxx)<0))	/* move image to those coor. */
				xoff=0;
			else
				if(i>(xdim-maxx))
					xoff=xdim-maxx;
				else
					xoff=i;
			if((j<0) || ((ydim-maxy)<0))
				yoff=0;
			else
				if(j>(ydim-maxy))
					yoff=ydim-maxy;
				else
					yoff=j;
			grafmode();
			updatescrn();
			break;

		case SCRLLEFT:		/* move screen left ten pixels */
			scroll('l');
			break;

		case SCRLUP:		/* move screen up ten pixels */
			scroll('u');
			break;

		case SCRLDOWN:		/* move screen down ten pixels */
			scroll('d');
			break;

		case SCRLRIGHT:		/* move screen right ten pixels */
			scroll('r');
			break;

		case PAGEUP:		/* move screen up a full screen */
			scroll('U');
			break;

		case PAGEDOWN:		/* move screen down a full screen */
			scroll('D');
			break;

		case HOME:		/* move screen to the upper left hand corner */
			scroll('H');
			break;

		case END:		/* move screen to lower left hand corner */
			scroll('E');
			break;

		case 'c':		/* show color bar on the screen */
			if(!show)
				showpal();
			else
				nopal(xoff,yoff);
			show=!show;
			break;

		case 'n': 		/* change current palette */
			palnum++;
			if (palnum>palmax)
				palnum=0;
			if(mode!=EGA) {
				memcpy(rmap,rpal[palnum],256);
				memcpy(gmap,gpal[palnum],256);
				memcpy(bmap,bpal[palnum],256);
			  } /* end if */
			else
				memcpy(regrs,egapals[palnum],16);
			putpal();
	 		break;

#ifdef QAK
		case 'o':	/* turn vga screen off or on */
			if(mode==VGA)
				if(screen) {
					vgaoff();
					screen=0;
				  }	/* end if */
				else {
					vgaon();
					screen=1;
				  }	/* end else if */
			break;
#endif

		case 'f':		/* rotate palette forwards continuously */
			l='z';
			while (l!=' ') {
				if(mode!=EGA) {
				    i=rmap[0];
					j=gmap[0];
					k=bmap[0];
					memcpy(rmap,rmap+1,255);	/* shift palettes down one byte */
					memcpy(gmap,gmap+1,255);
					memcpy(bmap,bmap+1,255);
					rmap[255]=i;
					gmap[255]=j;
					bmap[255]=k;
					j=palspeed;
				  } /* end if */
				else {
					i=regrs[0];
					for(j=0; j<=14; j++)
						regrs[j]=regrs[j+1];
					regrs[15]=i;
					j=palspeed+2000;
				  } /* end else */
				putpal();
				if(kbhit()) {
					l=getch();
					if(l==0)				/* get extended code if necessary */
						l=getch()|(unsigned char)128;	/* set high bit to indicate extended code */
				  }	/* end if */
				if(l=='+') {		/* increase the palettes rotation speed */
					if(mode!=EGA)
						palspeed+=100;
					else
						palspeed+=20;
					l='x';
				  }	/* end if */
				if(l=='-') {		/* decrease palette rotation speed */
					if(mode!=EGA)
						palspeed-=100;
					else
						palspeed-=20;
					l='x';
				  }	/* end if */
				for(; j<=2500; j++); 
			  } /* end while */
		  	break;

		case 'b':		/* rotate palette backwards continuously */
			l='x';
			while (l!=' ') {
				if(mode!=EGA) {
					i=rmap[255];
					j=gmap[255];
					k=bmap[255];
					memcpy(rmap+1,rmap,255);		/* shift palettes up one byte */
					memcpy(gmap+1,gmap,255);
					memcpy(bmap+1,bmap,255);
					rmap[0]=i;
					gmap[0]=j;
					bmap[0]=k;
					j=palspeed;
				  } /* end if */
				else {
					i=regrs[15];
					for(j=15; j>=1; j--)
						regrs[j]=regrs[j-1];
					regrs[0]=i;
					j=palspeed+2000;
				  } /* end else */
				putpal();
				if(kbhit()) {
					l=getch();
					if(l==0)				/* get extended code if necessary */
						l=getch()|(unsigned char)128;	/* set high bit to indicate extended code */
				  }	/* end if */
				if(l=='+') {		/* increase the palettes rotation speed */
					if(mode!=EGA)
						palspeed+=100;
					else
						palspeed+=20;
					l='x';
				  }	/* end if */
				if(l=='-') {		/* decrease palette rotation speed */
					if(mode!=EGA)
						palspeed-=100;
					else
						palspeed-=20;
					l='x';
				  } /* end if */
				for(; j<=2500; j++);
			  } /* end while */
	  		break;

		case 'e':		/* rotate palette forwards once */
			rotate('r');
		  	break;

		case 'v':		/* rotate palette backwards once */
			rotate('l');
			break;

		case 'r':	/* reset the palette to its initial values */
			if(mode!=EGA) {
				memcpy(rmap,rpal[palnum],256);
				memcpy(gmap,gpal[palnum],256);
				memcpy(bmap,bpal[palnum],256);
			  } /* end if */
			else 
				memcpy(regrs,egapals[palnum],16);
			palspeed=0;	/* set the palette rotation speed back to zero also */
			putpal();
			break;
	  } /* end switch */
}	/* end parse() */
