/* KB2.C */

#include "externs.h"

keybd2(cmd) /* read keyboard; execute commands */
char cmd;
{
  char ch, place;
  int i, x, y, j, k, done, x1, x2;
  double scr;
  void far help();
  struct dfree df;
  long avail, sects, bytes, total;
  
        
    switch (cmd) {
      case 0:   /* arrows or F1, F2, F3, etc. or Alt keys */
        cmd = getch();
        
        if (cmd == 25) { /* Alt-p: send data to printer */
          print = 1;
          break;
        }
        
        if (cmd == 119) { /* Ctrl-HOME  recall a transponder */
          bar(0,0,719,347);	/* erase screen */
          x = 3; y = 50;
          gprintf(&x,&y,"Recall which transponder frequency? (1-5) (other aborts)");
          ch = getch();
          j = ch - 49;
          if (ch >= '1' && ch <= '5') {
            gprintf(&x,&y,"");
            gprintf(&x,&y,"READY TO RECALL TRANSPONDERS ON FREQ. %d", j+1);
            putchar(7);
            gprintf(&x,&y,"");
            gprintf(&x,&y,"Press 'Y' to execute it!");
            gprintf(&x,&y,"");
            gprintf(&x,&y,"Press any other key to abort...");
            if (getch() == 'Y') { /* do it */
              gprintf(&x,&y,"");
              gprintf(&x,&y,"RECALLING TRANSPONDERS ON FREQ. %d....",j+1);

              
              for(k = 0; k < 333; k++) {  /* for 3 secs. */
                /* set xmit line hi */
                outportb(PORTB,0);
                outportb(PORTB,xfreq[j]);
                
                /* start timer 2 for 3.663 ms. time (136.5 Hz) */
                /* start timer 2 for 4.509 ms. time (110.9 Hz) */
                outport(TIMCNTL,0xb0); /* timer2 set for mode 0 */

/*                outport(TIMER2,0x4f);  /* set count for 3.663 ms. */
                outport(TIMER2,0x40);  /* empirical correction */
                outport(TIMER2,0xe);
*/                
                outport(TIMER2,0x80);  /* empirical correction */
                outport(TIMER2,0x11);
                /* wait for timer2 to time out */
                i = 0;
                while(!i) {
                  i = inportb(PORTA);
                  i &= 1; /* check port A bit 0 (connected to timer2 out) */
                }
  
                /* set xmit line lo */
                outportb(PORTB,0);
                outportb(PORTB,xfreq[3]); /* 12.5 KHz on */

                /* start timer 2 for 3.663 ms. time (136.5 Hz) */
                outport(TIMCNTL,0xb0); /* timer2 set for mode 0 */
                outport(TIMER2,0x80);  /* empirical correction */
                outport(TIMER2,0x11);
                /* wait for timer2 to time out */
                i = 0;
                while(!i) {
                  i = inportb(PORTA);
                  i &= 1; /* check port A bit 0 (connected to timer2 out) */
                }
                outportb(PORTB,0);
              }
              dmode = STRIP;
              initstrip();
              break;
            }
          }
          gprintf(&x,&y,"");
          gprintf(&x,&y,"Recall aborted!!");
          gprintf(&x,&y,"");
          gprintf(&x,&y,"Press any command key.");
          dmode = NODISPLAY;

          break;
        }
        
        if (cmd == 46) { /* Alt-C toggle net calibration routine */
          if(docal) docal = 0;
          else {
            docal = 1;
            fix = 0;
            mode = GATES;
            dmode = STRIP;
            quick = 0;
            bar(0,0,719,347);	/* erase screen */
            x = 3; y = 50;
            gprintf(&x,&y,"Starting baseline calibration routine.");
            gprintf(&x,&y,"Fixes should stay off.");
            gprintf(&x,&y,"Mode should stay GATES.");
            gprintf(&x,&y,"Do not use quick mode.");
            gprintf(&x,&y,"");
            gprintf(&x,&y,"Press any key to continue...");
            getch();
          }
          initstrip();
          break;
        }
        
        if (cmd == 31) { /* Alt-S toggle self-time/external time */
          bar(0,0,719,347);	/* erase screen */
          x = 3; y = 3;
          gprintf(&x,&y,"");
          if(selftime) {
            selftime = 0;
            gprintf(&x,&y,"Switching to external timing mode.");
          }
          else {
            selftime = 1;
            gprintf(&x,&y,"Switching to self-timing mode.");
          }
          gprintf(&x,&y,"");
          gprintf(&x,&y,"Any key to continue...");
          getch();
          dmode = STRIP;
          initstrip();
          break;
        }
        
        if (cmd == 72 || cmd == 75 || cmd == 77 || cmd == 80) {
          /* arrows (offset 1/3 of plan screen) */
          bar(1,1,87,346);	/* clear plan text area */
          x = 3; y = 3;
          gprintf(&x,&y,"Hit 'space'");
          gprintf(&x,&y," to quit");
          gprintf(&x,&y,"offsetting.");
          center = -1;	/* turn off centering */
          done = 0;
          while(!done) {
            if(cmd == 72) offy += scale * 111; /* up */
            if(cmd == 80) offy -= scale * 111; /* down */
            if(cmd == 75) offx -= scale * 206; /* left */
            if(cmd == 77) offx += scale * 206; /* right */
            plan();
            cmd = getch();
            if(cmd != 0) break;
            cmd = getch();
            if(cmd != 79) done = 0; /* 'end' key */
            else done = 1;
          }
          break;
        }
        
        /* must be F keys (set gates) */
        if(cmd < 59 || cmd > 68) break;
        if (mode != GATES) break;
        i = (int)cmd - 59; /* i goes from 0 thru 9 */
        j = i / 2;         /* j goes from 0 thru 4 */
        if(!xpond[j]) break; /* don't do it if xponder not on */
        bar(3,310,718,346);	/* erase text screen */
        changetextstyle(2, HORIZ_DIR, 7); /* medium horz. SmallText */
        outtextxy(10,322,"Set ship or RUM gate (s/r)?");
        cmd = getch();
        bar(3,310,718,346);	/* erase text screen */
        if (cmd == 's') {
          x = 10; y = 322;
          if(i==0 || i == 2 || i == 4 || i == 6 || i == 8) {
            gprintf(&x,&y,"Setting ship mid point of xponder %d  ( < > )", j+1);
            while (cmd != 13) { /* end by hitting return */
              cmd = getch();
              if(cmd == '<') {
                if(slogate[j] > 52) {
                  slogate[j] -= 50;
                  shigate[j] -= 50;
                }
              }
              if(cmd == '>') {
                if(shigate[j] < 19948) {
                  slogate[j] += 50;
                  shigate[j] += 50;
                }
              }
              movegates();
            }
          }
          else {
            gprintf(&x,&y,"Setting ship gate width of xponder %d  ( < > )",j+1);
            while (cmd != 13) { /* end by hitting return */
              cmd = getch();
              if(cmd == '<') {
                if(shigate[j] - slogate[j] > 99) {
                  shigate[j] -= 25;
                  slogate[j] += 25;
                }
              }
              if(cmd == '>') {
                if(shigate[j] < 19973 && slogate[j] > 27) {
                  shigate[j] += 25;
                  slogate[j] -= 25;
                }
              }
              movegates();
            }
          }
        }
        if (cmd == 'r') {
          x = 10; y = 322;
          if(i==0 || i == 2 || i == 4 || i == 6 || i == 8) {
            gprintf(&x,&y,"Setting RUM mid point of xponder %d  ( < > )", j+1);
            while (cmd != 13) { /* end by hitting return */
              cmd = getch();
              if(cmd == '<') {
                if(rlogate[j] > 52) {
                  rlogate[j] -= 50;
                  rhigate[j] -= 50;
                }
              }
              if(cmd == '>') {
                if(rhigate[j] < 19948) {
                  rlogate[j] += 50;
                  rhigate[j] += 50;
                }
              }
              movegates();
            }
          }
          else {
            gprintf(&x,&y,"Setting RUM gate width of xponder %d  ( < > )",j+1);
            while (cmd != 13) { /* end by hitting return */
              cmd = getch();
              if(cmd == '<') {
                if(rhigate[j] - rlogate[j] > 99) {
                  rhigate[j] -= 25;
                  rlogate[j] += 25;
                }
              }
              if(cmd == '>') {
                if(rhigate[j] < 19973 && rlogate[j] > 27) {
                  rhigate[j] += 25;
                  rlogate[j] -= 25;
                }
              }
              movegates();
            }
          }
        }
        changetextstyle(2, HORIZ_DIR, 5); /* small horz. SmallText */
	initstrip();
        break;
        
      case '1': /* toggle interogate freqs. */
      case '2':
      case '3':
        i = (int)cmd - 0x31;
        /* don't turn them all off */
        if((xfreqsel[0] + xfreqsel[1] + xfreqsel[2] - xfreqsel[i]) != 0) {
          if(xfreqsel[i]) xfreqsel[i] = 0; /* toggle it */
          else xfreqsel[i] = 1;
        }
        if(dmode == STRIP) striptext();
        break;
        
      case 't':
        if(dmode == STRIP) {
          bar(3,310,718,346);	/* erase text screen */
          x = 3; y = 310;
          gprintf(&x,&y,"Enter receive time (0 - 9):");
          gprintf(&x,&y,"  4 - 4 sec.   5 - 5 sec.   6 - 6 sec.   7 - 7   sec.   8 - 8 sec.   9 - sec.");
          gprintf(&x,&y,"  0 - 10 sec.  1 - 11 sec.  2 - 12 sec.    3 - 13 sec.");
          cmd = getch();
          if(cmd < '0' || cmd > '9') {
            striptext();
            break;
          }
          if(cmd >= '0' && cmd <= '3') rectime = 2000 * ((int)cmd - 0x30 + 10);
          else rectime = 2000 * ((int)cmd - 0x30);
          
          if(expoff > rectime - 2000 && rectime > 2000) 
            expoff = rectime - 2000; /* keeps expanded area on screen */
          striptext();
        }
        break;
        
      case 'n':
        mode = NOGATES;
        fix = 0;
        if(dmode == STRIP) striptext();
        break;
        
      case 'p':			/* plan view display */
        dmode = PLAN;
        initplan();
        plan();
        break;
        
      case 'c':			/* strip chart display */
        dmode = STRIP;
        initstrip();		/* draw border and text */
        break;
        
      case 'B':			/* toggle sound (beep) */
        if(beep) beep = 0;
        else beep = 1;
        break;
        
      case 'F':
        bar(0,0,719,347);	/* erase screen */
        x = 3; y = 3;
        gprintf(&x,&y,"Set freq. of which xponder? (1-5)");
        cmd = getch();
        i = (int)cmd - 0x31;
        if(i < 0 || i > 4) goto fdone;
        gprintf(&x,&y,"What frequency? (1-3)");
        cmd = getch();
        xpondfreq[i] = (int)cmd - 0x30;
      fdone:
        if(dmode == STRIP) initstrip();
        else initplan();
        break;
        
      case 'P':	/* toggle print every fix */
        if(printall) printall = 0;
        else printall = 1;
        break;
        
      case 'h':	/* change track history length */
        if(dmode == BULL) {
          bar(620,1,718,245); /* erase text portion */
          x = 622; y = 3;
        }
        else {
          bar(1,1,87,346);	/* clear plan text area */
          x = 3; y = 3;
        }
        gprintf(&x,&y,"Enter new");
        gprintf(&x,&y,"  track");
        gprintf(&x,&y,"  length.");
        gprintf(&x,&y,"(2 - 200)");
        moveto(x,y);
        scr = getfloat();
        trlen = (int)scr;
        if(trlen < 2) trlen = 2;
        if(trlen > 200) trlen = 200;
        if(dmode == BULL) bulltext();
        else plantext();
        break;
      
      case 'v': /* display all variables (static display) */
        showall(); /* this is in far.c */
        /* check if disk is getting full */
        getdfree(4,&df); /* check disk D: */
        avail = (long)df.df_avail;
        bytes = (long)df.df_bsec;
        sects = (long)df.df_sclus;
        total = avail * bytes * sects; /* total bytes free on disk D: */
        x = 350;
        y = 334;
        gprintf(&x,&y,"%ld bytes left on disk.", total);
        break;
      
      case 'K': /* set new station keeping location */
        bar(0,0,719,347);	/* erase screen */
        x = 3; y = 3;
        gprintf(&x,&y,"");
        gprintf(&x,&y,"NOTIFY BRIDGE OF CHANGE FIRST!!");
        gprintf(&x,&y,"");
        gprintf(&x,&y,"Set new station keeping location at");
        gprintf(&x,&y,"        1) RUM location");
        gprintf(&x,&y,"        2) SHIP location");
        gprintf(&x,&y,"        3) absolute location");

        place = getch();
        switch (place) {
          case '1':
            keepx = obj[RUM].x;
            keepy = obj[RUM].y;
            gprintf(&x,&y,"Station keep at RUM location");
            break;
          case '2':
            keepx = obj[SHIP].x;
            keepy = obj[SHIP].y;
            gprintf(&x,&y,"Station keep at SHIP location");
            break;
          case '3':
            gprintf(&x,&y,"Present station keeping position is:");
            gprintf(&x,&y,"  X: %.0f", keepx);
            gprintf(&x,&y,"  Y: %.0f", keepy);
            moveto(x,y);
            outtext("New absolute X location? ");
            keepx = getfloat();
            gprintf(&x,&y,"");
            moveto(x,y);
            outtext("New absolute Y location? ");
            keepy = getfloat();
            gprintf(&x,&y,"");
            gprintf(&x,&y,"Station keep at %.0f, %.0f", keepx, keepy);
            break;
        }
        gprintf(&x,&y,"");
        gprintf(&x,&y,"Press any key to continue.");
        getch();
        if(dmode == STRIP) initstrip();
        else if(dmode == BULL) {
          initbull();
          bulltext();
          bulldisplay();
        }
        else initplan();
        break;
        
      case 'N':  /* Toggle 3 pt. fixes only */
        bar(0,0,719,347);	/* erase screen */
        x = 3; y = 3;
        gprintf(&x,&y,"Presently:");
        if(onlysfix3) {
          gprintf(&x,&y,"  Accepting only 3 pt. fixes for ship.");
          gprintf(&x,&y,"  Change to 2 & 3 pt. fixes? (y/n)");
        }
        else {
          gprintf(&x,&y,"  Accepting 2 & 3 pt. fixes for ship.");
          gprintf(&x,&y,"  Change to only 3 pt. fixes? (y/n)");
        }
        cmd = getch();
        if(cmd == 'y') {
          if(onlysfix3) onlysfix3 = 0;
          else onlysfix3 = 1;
        }
        /* now rum */
        if(onlyrfix3) {
          gprintf(&x,&y,"  Accepting only 3 pt. fixes for RUM.");
          gprintf(&x,&y,"  Change to 2 & 3 pt. fixes? (y/n)");
        }
        else {
          gprintf(&x,&y,"  Accepting 2 & 3 pt. fixes for RUM.");
          gprintf(&x,&y,"  Change to only 3 pt. fixes? (y/n)");
        }
        cmd = getch();
        if(cmd == 'y') {
          if(onlyrfix3) onlyrfix3 = 0;
          else onlyrfix3 = 1;
        }
        if(dmode == STRIP) initstrip();
        else if(dmode == BULL) {
          initbull();
          bulldisplay();
        }
        else {
          initplan();
          plan();
        }
        break;
        
      case 'e':  /* Change expand variables */
        if(dmode == STRIP) { /* only do if in strip mode */
          bar(3,310,718,346);	/* erase chart text screen */
          /* show expanded area with lines */
          x1 = (int)(expoff * 717 / rectime + 2);
          x2 = (int)((expoff + 2000) * 717 / rectime + 2);
          line(x1,1,x2,1);
          line(x1,315,x2,315);
          x = 3;
          y = 322;
          if(expand) gprintf(&x,&y,"Expand is on.  Toggle it? (y/n)");
          else gprintf(&x,&y,"Expand is off.  Toggle it? (y/n)");
          cmd = getch();
          if(cmd == 'y') {
            if(expand) expand = 0;
            else expand = 1;
          }
          if(!expand) {
            striptext();
            break;
          }
          gprintf(&x,&y,"Change location of expanded portion? (y/n)");
          cmd = getch();
          if(cmd == 'y') {
            bar(3,322,718,346);	/* erase part of chart text screen */
            x = 3; y = 322;
            gprintf(&x,&y,"Use < or > to adjust. CR to end.");
            done = 0;
            while (!done) {
              cmd = getch();
              if(cmd == '<') {
                /* move expanded area left */
                if(expoff >= 500) expoff -= 500;
              }
              else if(cmd == '>') {
                /* move expanded area right */
                if(expoff < rectime - 2000) expoff += 500;
              }
              else if(cmd == 13) done = 1;
              
              /* show expanded area with lines */
              setcolor(0);		/* erase expand lines */
              line(3,1,717,1);
              line(3,315,717,315);
              setcolor(1);
              x1 = (int)(expoff * 717 / rectime + 2);
              x2 = (int)((expoff + 2000) * 717 / rectime + 2);
              line(x1,1,x2,1);
              line(x1,315,x2,315);
            }
          }
          striptext();
        }
        break;
        
      case 'D':  /* change receive dead time */
        bar(0,0,719,347);	/* erase screen */
        x = 3; y = 3;
        gprintf(&x,&y,"Present receiver dead time is %.1lf secs.",
        	deadtime / 2000);
        moveto(x,y);
        outtext("Enter new dead time in secs. ");
        deadtime = getfloat() * 2000.0;
        gprintf(&x,&y,"");
        gprintf(&x,&y,"New dead time is %lf secs.",deadtime / 2000);
        gprintf(&x,&y,"Any key to continue...");
        getch();
        if(dmode == STRIP) initstrip();
        else if(dmode == BULL) {
          initbull();
          bulltext();
          bulldisplay();
        }
        else initplan();
        break;
        
      case 'L':  /* change acceptable receive pulse length */
        bar(0,0,719,347);	/* erase screen */
        x = 3; y = 3;
        gprintf(&x,&y,"Present ship minimum receiver pulse length is %.1f ms.",
        	(float)slen / 5);
        gprintf(&x,&y,"Present RUM minimum receiver pulse length is %.1f ms.",
        	(float)rlen / 5);
        moveto(x,y);
        outtext("Enter new minimun pulse length in milliseconds. ");
        scr = getfloat() * 5;
        gprintf(&x,&y,"");
        gprintf(&x,&y,"Ship or RUM? (s/r/e)");
        cmd = getch();
        if(cmd == 's') slen = (int)scr;
        if(cmd == 'r') rlen = (int)scr;
        gprintf(&x,&y,"New pulse lengths are:");
        gprintf(&x,&y,"  Ship: %.1f ms.",(float)slen / 5);
        gprintf(&x,&y,"  RUM: %.1f ms.",(float)rlen / 5);
        gprintf(&x,&y,"Any key to continue...");
        getch();
        if(dmode == STRIP) initstrip();
        else if(dmode == BULL) {
          initbull();
          bulltext();
          bulldisplay();
        }
        else initplan();
        break;
        
      case 'X':  /* change ship xducer depth */
        bar(0,0,719,347);	/* erase screen */
        x = 3; y = 3;
        gprintf(&x,&y,"Present depth of ship transducer is %.1f m.",
        	obj[SHIP].z);
        moveto(x,y);
        outtext("Enter new depth in meters.");
        obj[SHIP].z = getfloat();
        gprintf(&x,&y,"");
        gprintf(&x,&y,"New transducer depth is %.1f m.",obj[SHIP].z);
        gprintf(&x,&y,"Any key to continue...");
        getch();
        if(dmode == STRIP) initstrip();
        else if(dmode == BULL) {
          initbull();
          bulltext();
          bulldisplay();
        }
        else initplan();
        break;
        
      case 'V':  /* change sound velocity */
        bar(0,0,719,347);	/* erase screen */
        x = 3; y = 3;
        gprintf(&x,&y,"Present ave. sound velocity in water column is %.1f m/sec.",
        	sndvel);
        moveto(x,y);
        outtext("Enter new column velocity. ");
        sndvel = getfloat();
        gprintf(&x,&y,"");
        gprintf(&x,&y,"New ave. column velocity is %.1f m/sec.",sndvel);
        gprintf(&x,&y,"");
        gprintf(&x,&y,"Present sound velocity at bottom is %.1f m/sec.",
        	sndbot);
        moveto(x,y);
        outtext("Enter bottom velocity. ");
        sndbot = getfloat();
        gprintf(&x,&y,"");
        gprintf(&x,&y,"New bottom velocity is %.1f m/sec.",sndbot);
        gprintf(&x,&y,"Any key to continue...");
        getch();
        if(dmode == STRIP) initstrip();
        else if(dmode == BULL) {
          initbull();
          bulltext();
          bulldisplay();
        }
        else initplan();
        break;
        
      case 0x14: /* ctrl-t  Toggle simulated echoes */
        if(sim) sim = 0;
        else sim = 1;
        break;
        
      case 'g':
        mode = GATES;
        dmode = STRIP;
        initstrip();
       break;
        
      case '?':
        changetextstyle(2, HORIZ_DIR, 5); /* small horz. SmallText */
        help();
        break;
    }
}
