#include <signal.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "Syslog.h"
#include "SerialParameters.h"
#include "System.h"
#include "BenthosModemServer.h"

void signalHandler(int signalNo);

pid_t benthosPID;

void displayMenu()
{
  printf("\nEnter a command\n");
  printf("\tChange Modem (P)ower level\n");
  printf("\tGet (R)ange to another modem\n");
  printf("\tChange Modem (D)oppler correction mode\n");
  printf("\t(S)et a modem register to a value\n");
  printf("\t(T)ranspond at a given frequency\n");
  printf("\t(W)rite a string\n");
  printf("\t(Q)uit\n");
  printf("\n\t>> "); fflush(stdout);
}

void signalHandler(int signalNo)
{
  kill(benthosPID, SIGTERM);
  kill(0, SIGQUIT);
  exit(0);
}

int main(int argc, char **argv)
{
  //
  SerialParameters serialParams(&argc, argv);
  char argString[100];

  sprintf(argString, "-serial %s", serialParams.string());
  signal(SIGQUIT, signalHandler);
  printf("Starting benthosServer ...\n");

  if ( (benthosPID = System::spawn("benthosServer", argString)) == -1) {
    fprintf(stderr, "System::spawn(benthos) failed\n");
  }

  // Now get a handle to the server IF
  //
  AcousticModemIF *benthos;
  try {
    benthos = new AcousticModemIF(BENTHOSSERVERNAME);
  }
  catch (Exception e) 
  {
    Syslog::write(
        "benthosTest -- Caught exception on creation of AcousticModemIF:%s\n",
		  e.msg);
    exit( -1 );
  }
     

  // Just wait for termination signal
  char command = ' ';
  char carg = ' ';
  while (command != 'q') {
    sleep(2);
    displayMenu();
    command = getch();
    switch (command) {


      case 'p':   // alter modem power level
      case 'P':
	printf("\n\tEnter a power level (1-8) >> ");
	fflush(stdout);
	carg = getch();
	if (carg < '1' || carg > '8') {
	  printf("\nInvalid power level!\n");
	  break;
	}
	printf("\n\tSetting power level to %c...\n", carg);
	benthos->power(carg - '0');
	break;


      case 'r':   // get range to other modem
      case 'R': {
	printf("\n\tEnter the address of the remote modem (0-31) >> ");
	fflush(stdout);
	char sadd[10];
	char *sp;
	gets(sadd);
	long iadd = strtol(sadd, &sp, 10);
	if ((iadd == 0 && sp == sadd) || iadd < 0 || iadd > 31) {
	  printf("Invalid address!\n");
	  break;
	}
	printf("\tGetting range to %d...\n", iadd);
	float frange;
	benthos->range(iadd, &frange);
	break;
      }

      case 't':   // transpond
      case 'T': {
	printf("\n\tEnter the freq in tenths of a kHz >> ");
	fflush(stdout);
	char sfreq[10];
	char *sf;
	gets(sfreq);
	long ifreq = strtol(sfreq, &sf, 10);
	if ((ifreq == 0 && sf == sfreq) || ifreq < 90 || ifreq > 140) {
	  printf("Invalid frequency!\n");
	  break;
	}
	printf("\tSending interogation at %d...\n", ifreq);
	benthos->transpond(ifreq);
	break;
      }

      case 's':   // set register value
      case 'S': {
	printf("\n\tEnter the register number >> ");
	fflush(stdout);
	char sreg[10];
	char *s;
	gets(sreg);
	long ireg = strtol(sreg, &s, 10);
	if ((ireg == 0 && s == sreg) || ireg < 1 || ireg > 41) {
	  printf("Invalid register!\n");
	  break;
	}

	printf("\n\tEnter a value for register %d >> ", ireg);
	fflush(stdout);
	char sval[10];
	gets(sval);
	long ival = strtol(sval, &s, 10);
	if ((ival == 0 && s == sval)) {
	  printf("Invalid value\n");
	  break;
	}

	printf("\tSetting register %d to %d...\n", ireg, ival);
	benthos->setRegister(ireg, ival);
	break;
      }

      case 'd':   // doppler correction
      case 'D':
      {
	printf("\n\tOn=1 or Off=0?  >> ");
	fflush(stdout);
	char sreg[10];
	char *s;
	gets(sreg);
	long ireg = strtol(sreg, &s, 10);
	if ((ireg == 0 && s == sreg) || ireg < 0 || ireg > 1) {
	  printf("Invalid response!\n");
	  break;
	}
	benthos->dopplerCorrection(ireg == 1);

	break;
      }

      case 'w':   // Write a string
      case 'W':
	{
	  printf("\n\tEnter the a string (max. 128 chars) >> ");
	  fflush(stdout);

	  AcousticModemIF::modemString mstr;
	  char str[129];
	  gets(str);
	  str[128] = '\0';
	  strcpy(mstr, str);
	  printf("%s\n", mstr);
	  benthos->writeString(mstr);
	}
	break;


      case 'q':   // Quit
      case 'Q':
	command = 'q';
	printf("Bye\n");
	break;

      default:
	printf("\nInvalid command: %c\n", command);
    }
  }

  signalHandler(0);
  return 0;
}

