#include <stdio.h>
#include "head.h"
#include <GL/glut.h>        /* OpenGl headers   - aadesche       */
#include <string.h>     /* For String compare                */
#include <stdlib.h>

/*Erika*/
#include "camera.h"

//yw changed! start
extern int useTexturing;
extern void LoadTexture(char* filename);
//yw changed! end

//Add by victor chen
extern float face_specular;
extern float face_brightness;

//victor chen change end

void KeyBoard(char* line)
{
    int both=0,sarg,pnum,fr,sf=0,ef=0,ff,lf,nlf,frtf_on;
    int mode=0777;
//by victor : set up brightness and specular
	int fa;
	float fval=50.0f;

//end by victor
    float pval=0.0f,lpval,rpval;
    char frtfname[MAX_LINE]; /*,line[MAX_LINE];*/
    char tlibfile[MAX_LINE],libfile[MAX_LINE];
    char tanimfile[MAX_LINE],animfile[MAX_LINE];
    FILE *fd ,*fopen();

	switch (line[0])
	{

		/*sss*/
      case 's':
             if (line[1]=='k') {
              if (sscanf(line+2,"%d%d%d",&nlf,&ff,&lf)==3)
	         ScaleKeys(nlf,ff,lf);
	      else printf("sk <nlf> <ff> <lf> -- Scale Keys ff-lf to ff-nlf\n");
	     }
   	     break;
			/*xxx*/
      case 'x':  /* copy given face data to default and reread it data */
              if (sscanf(line+1,"%s",tlibfile)==1) {
                sprintf(libfile,"copy Heads\\%s\\full1.pts full1.pts",tlibfile);
	        if (strncmp(tlibfile,"human",5)==0) g_facetype=HUMAN;
	        else g_facetype=NOTHUMAN;
	      system(libfile);
	      faceinit();
		  UpdateObject();
		  glutPostRedisplay();
	      }
       	      else printf("x <face data dir> readin in new face data\n");
	      break;
			/*lll*/
      case 'l':
      switch (line[1]) {
		 case 'e':
            if (sscanf(line+2,"%s",tanimfile)==1) {
                    sprintf(animfile,"Anims/%s",tanimfile);
		    if (CreateLips(animfile)) {
		    g_lipsync=1;
			g_sndFileName = (char*) malloc(strlen(animfile)+5);
			sprintf(g_sndFileName,"%s.wav",animfile);
	            printf("lip sync enabled,read in: %s\n",animfile);
		    }
		  } else printf("le <lip sync file> -- Enable reading in lip sync\n");
		  break;
   	    case 'd':
		    g_lipsync=0;
	            printf("lip sync disable: will NOT read in lip sync file\n");
		  break;
       case 'r':
                 sarg=sscanf(line+2,"%s%s",tlibfile,frtfname);
		 frtf_on=0;
                 if (sarg>0){
		   sprintf(libfile,"Library/%s",tlibfile);
		   if (sarg==2)
		    if (GetRegionPm(frtfname)) frtf_on=1; else sarg= -1;

		    if (ReadLibrary(libfile,frtf_on) && sarg != -1) {
				printf("Reading Library file: %s\n",libfile);
                       UpdateObject();
                       glutPostRedisplay();
		    }
		    else printf("Can't read Library region, aborted request\n");
		 }
       	         else printf("lr <entry> [region] -- read in library entry - region: m - mouth, e - eyes\n");
                 break;
             case 'w':
                 if (sscanf(line+2,"%s",tlibfile)==1) {
                 sprintf(libfile,"Library/%s",tlibfile);
                 WriteLibrary(libfile);
		 }
       	         else printf("lw <entry> -- write out library entry \n");
                 break;
   	   default: {
	          printf("l{rw} <entry> [region] -- read / write library entry, region - m:mouth, e:eyes\n");
		  printf("le <lip sync file> -- Enable reading in lip sync\n");
		  printf("ld -- disable lip sync\n");
		  }
		} break;
			/*rrr*/
      case 'r':
      switch (line[1]) {

         if (sscanf(line+1,"%d",&fr)==1) {
		    if (ReadKey(fr)) {
		    	g_curframe=fr;
                UpdateObject();
                glutPostRedisplay();
	      }
	      else printf("r <frame #> -- Read frame \n");
		} } break;

			/*kkk*/
      case 'k':
              PrintKeys(g_curframe);
              break;
			/*aaa*/
      case 'a':
            switch (line[1]) {
   	       case 'r':
                 if (sscanf(line+2,"%s",tanimfile)==1) {
                 sprintf(animfile,"Anims\\%s",tanimfile);

		 if ((fd=fopen(animfile,"r"))!= NULL) {
		    fclose(fd);
                    sprintf(tanimfile,"copy %s fas.keys",animfile);
	            printf("Reading Keys file %s.\n",animfile);
		    system(tanimfile);
    		    g_curframe=SetUpKeys();
		    if (ReadKey(g_curframe)) {
                UpdateObject();
                glutPostRedisplay();
	      }
		  }
	          else  printf("Can't find keys file  %s.\n",animfile);
		  }
	          else printf("ar <Anims file>  -- reads in Animation file (all keys)\n");
                 break;
   	       case 'w':
                 if (sscanf(line+2,"%s",tanimfile)==1) {
                 sscanf(line+2,"%s",tanimfile);
                 sprintf(animfile,"Anims\\%s",tanimfile);
                     sprintf(tanimfile,"copy fas.keys %s",animfile);
		     system(tanimfile);
	             printf("Writing keys file to %s.\n",animfile);
	       } else printf("aw <Anims file>  -- writes out Animation file (all keys)\n");
                 break;
              default:
	        printf("a{rw} <file name>  -- reads/writes Animation file\n");
              } break;
			/*bbb*/
	/* added by Erika - Camera related command */
			/*ccc*/
      case 'c':
		  switch (line[1])  {
		  case 'd':  /* delete */
			  if (sscanf(line+2, "%d", &fr)==1) {
				  DeleteCameraKey(fr);
				  if (fr == g_curframe) {
					  g_curframe = 0;
					  ReadKey(0);
					  ReadCameraKey(0);
					  UpdateObject();
					  glutPostRedisplay();
				  }
			  }
			  else printf("cd <frame #> -- delete camera key at frame\n");
			  break;
		  case 's':   /* scale */
			  if (sscanf(line+2,"%d%d%d",&nlf,&ff,&lf)==3)
				  ScaleCameraKeys(nlf,ff,lf);
			  else printf("sk <nlf> <ff> <lf> -- Scale camera Keys ff-lf to ff-nlf\n");

			  break;

		  case 'w':   /* write keys to file */
			  if (sscanf(line+2, "%s", frtfname) == 1) {
				  printf("%s\n", frtfname);
				  SaveCameraKeys(frtfname);
			  }
			  else printf("cw fname\n");
			  break;

		  case 'l':	   /* load keys from file */
			  if (sscanf(line+2, "%s", frtfname) == 1) {
				  printf("%s\n", frtfname);
				  LoadCameraKeys(frtfname);
			  }
			  else printf("cr fname\n");
			  break;

		  case 'k':    /* add key */
			  if (sscanf(line+2, "%d", &fr)>1) fr = g_curframe;
			  if (WriteCameraKey(fr)) {
				  printf("writing camera key %d\n", fr);
				  g_curframe=fr;
				  glutPostRedisplay();
			  }
			  break;

		  default:

			  PrintCameraKeys();
			  break;

		  }
	/* End of Erika modification - Camera related command */
      case 'b':
            switch (line[1]) {
   	       case 'i':
                 if (sscanf(line+2,"%d %d %d",&lf,&nlf,&pnum)==5)
		 InterpParam(lf,nlf,pnum);
                 else printf("bi <lowkey> <highkey> <pnum> - Interp Param and write at keys\n");
		 lf=999;
		 break;
   	       case 'w':
                 if (sscanf(line+2,"%d %d %d %f %f",&lf,&nlf,&pnum,&lpval,&rpval)==5)
		 WriteParam(lf,nlf,pnum,lpval,rpval);
                 else printf("bw <lowkey> <highkey> <pnum> <leftval> <rghtval> - write param\n");
		 lf=999;
		 break;
   	       case 'r':
		 cpm=cpmr;
                 sarg=sscanf(line+2,"%d%f",&pnum,&pval);
                 printf("right");
                 break;
   	       case 'l':
		 cpm=cpml;
                 sarg=sscanf(line+2,"%d%f",&pnum,&pval);
                 printf("left");
                 break;
               default:
		 cpm=cpmr;
		 both=1;
                 sarg=sscanf(line+1,"%d%f",&pnum,&pval);
	      }
              if (sarg==1)
		 printf("pm index %d r %g, l %g, \n",pnum,cpmr[pnum],cpml[pnum]);
              else if (sarg==2) {
                 cpm[pnum]=pval;
                 if (both) cpml[pnum]=pval;
		 printf("pm index %d: r %g, l %g\n",pnum,cpmr[pnum],cpml[pnum]);
              UpdateObject();
              glutPostRedisplay();
              }
	      break;
			/*ppp*/
      case 'p':
            switch (line[1]) {
   	       case 'i':
                 if (sscanf(line+2,"%d %d %d",&lf,&nlf,&pnum)==3)
		 InterpParam(lf,nlf,pnum);
                 else printf("pi <lowkey> <highkey> <pnum> - Interp Param and write at keys\n");
		 lf=999;
		 break;
   	       case 'w':
                 if (sscanf(line+2,"%d %d %d %f %f",&lf,&nlf,&pnum,&lpval,&rpval)==5)
		 WriteParam(lf,nlf,pnum,lpval,rpval);
                 else printf("pw <lowkey> <highkey> <pnum> <leftval> <rghtval> - write param\n");
		 lf=999;
		 break;
   	       case 'r':
		 cpm=cpmr;
                 sarg=sscanf(line+2,"%d%f",&pnum,&pval);
                 printf("right");
                 break;
   	       case 'l':
		 cpm=cpml;
                 sarg=sscanf(line+2,"%d%f",&pnum,&pval);
                 printf("left");
                 break;
               default:
		 cpm=cpmr;
		 both=1;
                 sarg=sscanf(line+1,"%d%f",&pnum,&pval);
	      }
              if (sarg==1) {
                 printf(" p  %d r %g, l %g,",pnum,cpm[ pnum ],cpml[ pnum ]);
              }
              else if (sarg==2) {
                 cpm[ pnum ]=pval;
                 if (both) cpml[ pnum ]=pval;
                 printf(" p %d r %g, l %g\n",pnum,cpmr[ pnum ],cpml[ pnum ]);
                 UpdateObject();
                 glutPostRedisplay();
              }
              else if (lf!=999) printf("p<[rl]> <pnum> [pvalue] -- parameter,display and/or change\n");
              break;
			/*ddd*/
      case 'd':
             if (sscanf(line+1,"%d",&fr)==1) {
	         DeleteKey(fr);
			 if (fr==g_curframe) {
				 g_curframe=0;
				 ReadKey(0);
				 UpdateObject();
				 glutPostRedisplay();
			 }
	         }
              else printf("d <key #> -- delete key\n");
              break;
			/*iii*/
      case 'i':
              if (sscanf(line+1,"%d",&fr)==1) {
		    if (ReadKey(fr)) {
				g_curframe=fr;
                UpdateObject();
                glutPostRedisplay();
	      }
	      } else printf("r <frame #> -- Read frame (or i)");
	      break;
			/*www*/
      case 'w':
              if (sscanf(line+1,"%d",&fr)>1) fr=g_curframe;

              if (WriteKey(fr)) {
				 g_curframe=fr;
                 UpdateObject();
                 glutPostRedisplay();
	      }
              break;
			/*>>>*/
      case '>':			/*  input next higher key frame */
	      if (g_curframe == g_keys[g_nkeys-1])  fr=g_keys[0]; /*wrap*/
              else fr=g_keys[NextHigherKey(g_curframe)];

		    if (ReadKey(fr)) {
                g_curframe=fr;
				UpdateObject();
                glutPostRedisplay();
	      }
              break;
			/*<<<*/
      case '<':			/*  input next lower key frame */
	      if (g_curframe == g_keys[0])  fr=g_keys[g_nkeys-1]; /*wrap*/
              else fr=g_keys[NextLowerKey(g_curframe)];
		    if (ReadKey(fr)) {
				g_curframe=fr;
                UpdateObject();
                glutPostRedisplay();
	      }
              break;
			/*+++*/
      case '+':			/*  input next higher frame */
	      if (g_curframe == g_keys[g_nkeys-1])  fr=g_keys[0]; /*wrap*/
              else fr=g_curframe+1;
		    if (ReadKey(fr)) {
                g_curframe=fr;
				UpdateObject();

				/*Erika */
				ReadCameraKey(fr);
                glutPostRedisplay();
	      }
              break;
			/*---*/
      case '-':			/* input next lower frame */
	      if (g_curframe == g_keys[0])  fr=g_keys[g_nkeys-1]; /*wrap*/
              else fr=g_curframe-1;
		    if (ReadKey(fr)) {
				g_curframe=fr;
                UpdateObject();

				/*Erika */
				ReadCameraKey(fr);
                glutPostRedisplay();
	      }
              break;
			  /*ooo*/
	case 'o':
            switch (line[1]) {
   	       case 'v':
	         draw_mode_select(0);
                 printf("Vector shading\n");
	         break;
   	       case 'f':
	         draw_mode_select(1);
                 printf("Facet shading\n");
		   break;
   	       case 's':
	         draw_mode_select(2);
                 printf("Shaded shading\n");
		   break;
        default:
	        printf("ov <vector shading>\n");
	        printf("of <facet shading>\n");
			printf("os <smooth shading>\n");
		}
			/*PPP*/
      case 'P':
		     g_anim=1;
			 g_curframe=0;
			 printf("Playing back ");
			 PrintKeys(g_curframe);
              break;

			/*qqq*/
      case 'q':
              printf("bye\n");
			  exit(0);
              /* quit */
	      break;
			/*...*/
      case '.':
             /*  undo(); */
              break;
			/*???*/
      case '?':
			/*hhh*/
      case 'h':
              printf("			KEYFRAME COMMANDS\n");
              printf("r <frame #> -- Read frame (or i)");
              printf("\t> <  -- incr/decr through key frames\n");
			  printf("fb <int Brightness> -- set brightness of texture mapped model\n");
			  printf("fs <int Specular> -- set specular of texture mapped model\n");
              printf("d <key #> -- Delete key");
              printf("\t\t\t+ -  -- incr/decr through frames\n");
              printf("w <key #> -- Write out key");
              printf("\t\tk -- print all Keys\n");
	          printf("sk <nlf> <ff> <lf> -- Scale Keys firstf-lastf to firstf-newlastf\n");
              printf("			PARAMETER COMMANDS\n");
              printf("p{rl} <pnum> [pvalue] -- Param value: display or change (left,right or both\n");
       	      printf("l{rw} <entry> [region] -- Read/Write Library Entry, region: m - mouth, e - eyes\n");
              printf("pw <lowkey> <highkey> <pnum> <leftval> <rghtval> -- write param to set of keys\n");
              printf("pi <lowkey> <highkey> <pnum> - Interp a specific param over a set of keys\n");
              printf(". (dot) -- undo current parameter change \n");
              printf("			PLAYBACK COMMANDS\n");
              printf("P -- Playback animation\n");
			  printf("le <lipsync file> -- Enable lipsyncing");
		      printf("\tld -- disable lipsyncing\n");
              printf("			DISPLAY COMMANDS\n");
              printf("ov -- Vector output");
              printf("\t\t\tof -- Facet shaded output\n");
              printf("os -- Smooth shaded output");
			  printf("\t\t1-5 -- turn on/off light 1-5\n");
			  printf("t <texture file> -- texture output");
			  printf("\ttd -- Disable texture mapping\n");
              printf("			MISCELLEOUS COMMANDS\n");
              printf("q -- Quit");
              printf("\t\t\t\t? or h -- help message\n");
	          printf("a{rw} <file name>  -- reads writes Animation file (all keys)\n");
              break;

	  //yw changed! start
	  case 't':
		  sarg=sscanf(line+1,"%s",tlibfile);
		  if (sarg == -1)
		  {
			  useTexturing = 0;
		  }
		  else
		  {
			useTexturing = 1;
			LoadTexture(tlibfile);
		  }

		  break;

	  //yw changed! end
	  //add by victor chen
	  case 'f':
		  switch (line[1]) {
			case 'b':
				sarg = sscanf(line+2,"%f",&fval);
				if (sarg == -1){
					face_brightness=0.7f;
				}else{
					face_brightness= fval /100.0;
				}
				printf ("Brightness set to %f",face_brightness);
				break;
			case 's':
				sarg = sscanf(line+2,"%f",&fval);
				if (sarg == -1){
					face_specular=1.0f;
				}else{
					face_specular= fval / 100.0 ;
				}
				printf ("Specular set to %f",face_specular);
				break;
			default:
				printf(" \nfb <int 0-100>: set brightness\nfs <0-1000>: set specular\n");

		  }

		  break;

      default: printf(" type ? for help\n");

	}
}
