/****************************************************************************/
/* Copyright (c) 2008 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : CameraTest.cc                                                 */
/* Author   : rsm                                                           */
/* Project  :                                                               */
/* Version  : 1.0                                                           */
/* Created  : 05/01/2008                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/

#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 "CameraIF.h"
#include "TimeP.h"
#include <i86.h>   //For the delay()

void signalHandler(int signalNo);

pid_t cameraPID;

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

void readCam(CameraIF *cameraIF, long nPhotos, double distance, long nSamplePeriods);

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

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

  if ( (cameraPID = System::spawn("cameraServer", argString)) == -1) {
    fprintf(stderr, "System::spawn(cameraServer) failed\n");
  }
  //
  // Now get a handle to the server IF
  //
  long nPhotos = 5, nSamplePeriods = 5;
  double distance = 0.;
  CameraIF *cameraIF;
  try {
    cameraIF = new CameraIF("Camera");
  }
  catch (Exception e) 
  {
    Syslog::write(
        "cameraTest -- Caught exception on creation of CameraIF:%s\n", e.msg);
    exit( -1 );
  }

  TimeIF::TimeSpec updateTime;


  Boolean First = True;
  int nRead;
  
  char buf[256];
  char *helpStr = "\n"
                  "Enter the number of photos to take, and either the number of \n"
                  "200 ms sample periods between photos, or the distance, in m,\n"
                  "between photos.\n"
                  "\n"
                  "Valid commands are:\n"
                  "   help           - Help\n"
                  "   nPhotos        - Number of photos to take.\n"
                  "   nSamplePeriods - Number of sample periods between photos.\n"
                  "   distance       - Distance between photos.\n"
                  "   start          - Take ""nPhoto"" photos.\n"
                  "   show           - Display information.\n"
                  "   on             - Take photos continouosly; press any key to stop.\n"
                  "   read           - Check to see if the camera is busy.\n"
                  "   quit           - Quit.\n"
                  "\n"
                  "You only need type the first three letters of the above commands.\n"
                  "\n";
  CameraIF::Data data;
  printf("%s",helpStr);
  while (True) 
  {
     // 
     // Read from the command line:
     printf("cameraTest> ");
     if (gets(buf) == 0) continue;  // Some error occurred

     if ( !strncmp(buf, "help", 1) || !strncmp(buf, "Help", 1) || 
	  !strncmp(buf, "" , 1) )
     {
	printf("%s",helpStr);
     }
     else if (!strncmp(buf, "start", 3 )) 
     {
	cameraIF->get(&data);
	cameraIF->start( nPhotos, nSamplePeriods, distance );
	while( data.cameraState == CameraIF::Ready )
	{
	   cameraIF->get(&data);
	   delay(200);
	}
	readCam(cameraIF, nPhotos, distance, nSamplePeriods);
     }
     else if ( !strcmp(buf, "on" )) 
     {
	printf("Strike any key to stop.\n");
	cameraIF->get(&data);
	cameraIF->onContinuously( nSamplePeriods, distance );
	while( data.cameraState == CameraIF::Ready )
	{
	   cameraIF->get(&data);
	   delay(200);
	}
        readCam(cameraIF, nPhotos, distance, nSamplePeriods);
        sleep(1);
	cameraIF->stop();
     }
     else if (!strncmp(buf, "nPhotos", 3 )) 
     {
	printf("Enter the number of photos to take:\n");
	nRead = scanf("%d", &nPhotos);
	if( nRead != 1 )
	{
	   printf("Error reading nPhotos.\n");
	   continue;
	}
	gets(buf);        //Clear any characters in the buffer.
	printf("nPhotos = %d, nSamplePeriods = %d, distance = %.2f\n", 
	       nPhotos, nSamplePeriods, distance);
     }
     else if (!strncmp(buf, "show", 3 )) 
     {
	printf("nPhotos = %d, nSamplePeriods = %d, distance = %.2f\n", 
	       nPhotos, nSamplePeriods, distance);
     }
     else if (!strncmp(buf, "nSamplePeriods", 3 )) 
     {
	printf("Enter the number of 200 ms sample periods:\n");
	nRead = scanf("%d", &nSamplePeriods);
	if( nRead != 1 )
	{
	   printf("Error reading nSamplePeriods.\n");
	   continue;
	}
	gets(buf);        //Clear any characters in the buffer.
	printf("nPhotos = %d, nSamplePeriods = %d, distance = %.2f\n", 
	       nPhotos, nSamplePeriods, distance);
     }
     else if (!strncmp(buf, "distance", 3 )) 
     {
	printf("Enter the distance increment in meters (> .2 m) :\n");
	float floatdist;
	nRead = scanf("%f", &floatdist);
	distance = floatdist;
	if( nRead != 1 )
	{
	   printf("Error reading distance.\n");
	   continue;
	}
	gets(buf);        //Clear any characters in the buffer.
	printf("nPhotos = %d, nSamplePeriods = %d, distance = %.2f\n", 
	       nPhotos, nSamplePeriods, distance);
     }
     else if (!strncmp(buf, "read", 2 )) 
     {
	readCam(cameraIF, nPhotos, distance, nSamplePeriods);
     }
     else if ( !strncmp(buf, "q", 1 ) || !strncmp(buf, "Q", 1 ) ) break;
     else printf(" Error: Command unrecognized.\n %s", helpStr);
  }

  // Just wait for termination signal
  signalHandler(0);
  return 0;
}

void readCam(CameraIF *cameraIF, long nPhotos, double distance, long nSamplePeriods)
{
	CameraIF::Data data;
	char stateStr[32];
	stateStr[31] = '\0';
	while(!kbhit())
	{
	   cameraIF->get( &data );
	   if  ( data.cameraState == CameraIF::Ready )     strcpy( stateStr, "ready" );
	   else if( data.cameraState == CameraIF::Busy )   strcpy( stateStr, "busy" );

	   printf("\n\nThe camera is %s.\n", stateStr);
	   printf("There are %d/%d photos left.\n", data.nPhotos, nPhotos);
	   printf("The camera has taken %d photos.\n", data.photoCntr);
	   printf("The distance made good is %.2f meters.\n", data.dmg);
	   printf("The distance increment is %.2f.\n", distance);
	   printf("The number of sample periods is %d.\n", nSamplePeriods);
	   printf("Continuously on = %d.\n", data.onContinuously);

	   if( data.cameraState == CameraIF::Ready ) break;

	   sleep(1);
	}
}
