/****************************************************************************/
/* Copyright (c) 2000 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : _lblTest.cc                                                   */
/* Author   : Rob McEwen                                                    */
/* Project  :                                                               */
/* Version  : 1.0                                                           */
/* Created  : 08/015/2000                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
/*-----------------------------------------------------------------------*
  $Id: _lblTest.cc,v 1.7 2001/06/02 21:33:24 hthomas Exp $
 *-----------------------------------------------------------------------*/

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <signal.h>
#include <process.h>
#include <time.h>

#include "LblIF.h"
#include "TimeIF.h"
#include "LblServer.h"
#include "Syslog.h"
#include "System.h"
#include "SerialParameters.h"
#include "TimeP.h"

int main( int argc, char **argv ) 
{
  LblIF *lbl;
  TimeIF::TimeSpec sampleTime;
  double depth, temp, pressure;
  pid_t _serverPid;
  Boolean debug = True;

  dprintf(" Start lblTest.\n");

  try { 
    SerialParameters serialParams(&argc, argv);
    char argString[100];
    dprintf(" lblTest: Serial Port String = %s\n", serialParams.string());
    sprintf(argString, "-serial %s", serialParams.string());
    if ((_serverPid = System::spawn("lblServer", argString)) == -1)
      {
	Syslog::write("System::spawn(lblServer) failed\n");
      }
  }
  catch ( ... )
    {
      Syslog::write("lblTest -- "
		    "caught exception on spawning of Lbl Server\n");
    }

  dprintf(" lblTest: SerialParams.\n");
  //
  // Start worksite server (needed by ps8000 to read the .cfg files).
  //
  pid_t workSiteServer;

  if ((workSiteServer = System::spawn("workSite",  "")) == -1) 
    throw Exception("System::spawn(workSite Server) failed");

  dprintf(" lblTest: Started WorkSite Server.\n");


  try 
  {
       lbl = new LblIF( "Lbl", 1000 );
  }
  catch (...)
  {
       Syslog::write("lblTest -- Caught exception on IF creation\n");
       exit( -1 );
  }

  dprintf(" lblTest: Opened lblIF.\n");

  LblIF ::RTimes     times[1];
  double decimalTime;
  TimeIF::TimeSpec   ping_time[1];
  char buf[256];


  fprintf(stderr, " Enter a command.  Type h for help.\n");
  //
  // Wait for the worksite to write to the screen, so the user will see
  // the prompt lblTest>
  //
  sleep(2);
  while (True) 
  {
    fprintf(stderr, "lblTest> ");
    if (gets(buf) == 0) 
    {
      // Some error occurred
      continue;
    }

    char *token = strtok(buf, " \t");

    //
    // If strtok returns a null pointer it means that buf is empty.  Jump to 
    // the bottom of the while loop and try again.
    //
    if (!token)                          //if(NULL)
      continue;

    if (!strncmp(token, "pi", 2 )) 
    {
      lbl->ping();
      printf(" Ping issued.\n");
    }
    else if (!strncmp(token, "t", 1 )) 
    { 

      lbl->get_ptime(ping_time);
      decimalTime = ping_time->seconds + ping_time->nanoSeconds/1000000000;
      printf(" The time at which the ping occured is: %.2f seconds\n", 
	     decimalTime );

      lbl->get_tof( times );
      printf(" The time-of-flight for each channel is:\n");
      printf("    Channel 1 = %.6f\n", times->t1 );
      printf("    Channel 2 = %.6f\n", times->t2 );
      printf("    Channel 3 = %.6f\n", times->t3 );
      printf("    Channel 4 = %.6f\n", times->t4 );
      printf("    Channel 5 = %.6f\n", times->t5 );
      printf("    Channel 6 = %.6f\n", times->t6 );
      printf("    Channel 7 = %.6f\n", times->t7 );
      printf("    Channel 8 = %.6f\n", times->t8 );
      printf("    Channel 9 = %.6f\n", times->t9 );
      printf("    Channel 10= %.6f\n", times->t10);
    }
    else if (!strncmp(token, "pe", 2 )) 
    { 

      pid_t scheduler;
      double lastReturnTime, returnTime;
      //TimeIF::TimeSpec timeSpec;
      struct timespec timeSpec;

      if ((scheduler = System::spawn("scheduler",  "True")) == -1) 
	throw Exception("System::spawn(Ping Scheduler) failed");

      dprintf(" lblTest: Started Ping Scheduler.\n");

      lbl->get_tof( times );
      //lastReturnTime = ping_time->seconds + (ping_time->nanoSeconds)/1000000000.;
      timeSpec.tv_sec   = times->sampleTime.seconds;
      timeSpec.tv_nsec  = times->sampleTime.nanoSeconds;
      lastReturnTime    = Time::seconds( &timeSpec );

      dprintf(" lastReturnTime = %.2f\n", lastReturnTime);
      printf( "Strike any key to terminate.\n");
      while( !kbhit() )
      {
	lbl->get_tof( times );
	timeSpec.tv_sec   = times->sampleTime.seconds;
	timeSpec.tv_nsec  = times->sampleTime.nanoSeconds;
	returnTime        = Time::seconds( &timeSpec );
	dprintf(" returnTime = %.2f\n", returnTime);

	if( returnTime > lastReturnTime )
	{

	  printf(" New data at t = %f seconds.\n", returnTime );
	  
	  printf(" The time-of-flight for each channel is:\n");
	  printf("    Channel 1 = %.6f\n", times->t1 );
	  printf("    Channel 2 = %.6f\n", times->t2 );
	  printf("    Channel 3 = %.6f\n", times->t3 );
	  printf("    Channel 4 = %.6f\n", times->t4 );
	  printf("    Channel 5 = %.6f\n", times->t5 );
	  printf("    Channel 6 = %.6f\n", times->t6 );
	  printf("    Channel 7 = %.6f\n", times->t7 );
	  printf("    Channel 8 = %.6f\n", times->t8 );
	  printf("    Channel 9 = %.6f\n", times->t9 );
	  printf("    Channel 10= %.6f\n", times->t10);

	  lastReturnTime = returnTime;
	}

	sleep(1);

      }
      kill(scheduler, SIGTERM);
    }
    else if (!strncmp(token, "pt", 2 )) 
    { 
      lbl->get_ptime(ping_time);
      decimalTime = ping_time->seconds + (ping_time->nanoSeconds)/1000000000.;

      printf(" The time at which the ping occured is: %.2f seconds\n", 
	     decimalTime );
    }
    else if (!strncmp(token, "h", 1 )) 
    {
      fprintf(stderr, "\n ***HELP*** \n");
      fprintf(stderr, " Valid commands are:\n");
      fprintf(stderr, "  'quit'   -  Quit this program.\n");
      fprintf(stderr, "  'ping'   -  Send a ping.\n");
      fprintf(stderr, "  'periodicPing' -  Enter a loop that periodically,\n");
      fprintf(stderr, "           -  pings and displays return times. \n");
      fprintf(stderr, "           -  Depress any key to exit the loop.\n");
      fprintf(stderr, "  'times'  -  Display ping time and time-of-flight\n");
      fprintf(stderr, "              for each channel.\n");
      fprintf(stderr, "  'ptime'  -  Display ping time.\n");
      fprintf(stderr, "\n");
      fprintf(stderr, " Note:  All commands can be abbreviated by their first.\n");
      fprintf(stderr, " two characters.\n");

      continue;
    }
    else if (!strncmp(token, "q", 1 )) 
    {
      // Quit
      break;
    }
    else 
    {
      fprintf(stderr, "Unknown command: %s\n", token);
      fprintf(stderr, "Type h for help.\n");
      continue;
    }
  }

  fprintf(stderr, " Exiting lblTest\n");
  delete lbl;
  kill(0, SIGTERM);
  kill(workSiteServer, SIGTERM);
  return 0;
}
