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


/** Initializing constructor
    @param driverName driver name
*/
CameraServer::CameraServer(const char *driverName){
  _driverName = strdup(driverName);
}

/** Initializing constructor.
    @param driverName driver name
    @param serialParams serial IO parameters
    @param test test boolean
*/
CameraServer::CameraServer(const char *driverName, 
			   SerialParameters *serialParams,
			   Boolean test, Boolean sim) 
   : CameraIF_SK(), _test(test), _sim(sim)
{
  _serialParams = serialParams;
  _cameraOutput = new CameraOutput();
  _cameraOutput->write();
  _driverName = strdup(driverName);

  if(_test) Syslog::write("CameraServer:: _test = %d\n", _test);

}

/** Default destructor */
CameraServer::~CameraServer()
{
  free((void *)_driverName);
  delete _cameraOutput;
}
/** Start camera photo triggering.
    @param nPhotos Number of photos to take
    @param nSamplePeriods Number of sample periods
    @param distance distance between photos
*/
void CameraServer::start(long nPhotos, long nSamplePeriods, double distance)
{
   _cameraOutput->read();
   if(_cameraOutput->data.nPhotos) 
      Syslog::write("CameraServer::start - nPhotos = %d, resetting to %d.",
		    _cameraOutput->data.nPhotos, nPhotos);

   _cameraOutput->data.nPhotos = nPhotos;
   _cameraOutput->data.nSamplePeriods = nSamplePeriods;
   _cameraOutput->data.distance = distance;
   _cameraOutput->write();
}

void CameraServer::onContinuously(long nSamplePeriods, double distance)
{
   _cameraOutput->read();
   Syslog::write("CameraServer::onContinuously - starting!");
   if(_cameraOutput->data.nPhotos) 
   {
      Syslog::write("CameraServer::onContinuously - Camera still running, "
		    "with %d photos left.  It will now stay on.", 
		    _cameraOutput->data.nPhotos);
   }
   _cameraOutput->data.onContinuously = True;
   _cameraOutput->data.nSamplePeriods = nSamplePeriods;
   _cameraOutput->data.distance = distance;
   _cameraOutput->write();
}

void CameraServer::stop()
{
   _cameraOutput->read();
   Syslog::write("CameraServer::Shutting off the camera!");
   if(_cameraOutput->data.nPhotos) 
   {
      Syslog::write("CameraServer::stop - Camera will stop after "
		    "%d photos.", 
		    _cameraOutput->data.nPhotos);
   }
   _cameraOutput->data.onContinuously = False;
   _cameraOutput->write();
}

#if 0
void CameraServer::state( CameraIF::CameraState *cameraState )
{
   _cameraOutput->read();
   *cameraState = _cameraOutput->data.cameraState;
}
#endif

/** Get camera camera output data 
    @param data pointer to destination Data object
*/
void CameraServer::get( CameraIF::Data *data )
{
  _cameraOutput->read();

  memcpy((void *)data, (void *)&_cameraOutput->data, sizeof(CameraIF::Data));
}

/** Forks a server task */
int CameraServer::spawnAuxTasks()
{
  char *program = (char *)_driverName;

  char errorBuf[256];
  char buf[256];
 
  pid_t pid;
 
  switch ((pid = fork())) {
     
  case 0:
    // In child
    // Execute server program
     if(_test) 
	execlp(program, program, "-serial", _serialParams->string(), "-test", 0);
     else if(_sim) 
	execlp(program, program, "-serial", _serialParams->string(), "-sim", 0);
     else 
	execlp(program, program, "-serial", _serialParams->string(), 0);

    sprintf(errorBuf, 
	    "Task::spawnServer() - execlp() of \"%s\" failed", program);

    perror(errorBuf);
 
    break;

  case -1:
    perror("Task::spawnServer() - fork() failed");
    return -1;
  }

  return 0;
}

