/****************************************************************************/
/* Copyright (c) 2000 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : BuoyLauncherServer.cc                                         */
/* Author   :                                                               */
/* Project  :                                                               */
/* Version  : 1.0                                                           */
/* Created  : 02/07/2000                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
#include <process.h>
#include <i86.h>
#include <Syslog.h>
#include "BuoyLauncherServer.h"

BuoyLauncherServer::BuoyLauncherServer(SerialParameters *params)
  : BuoyLauncherIF_SK()
{
  _params = params;
  _input = new BuoyLauncherInput(SharedData::ReadWrite);
  _output = new BuoyLauncherOutput(SharedData::Read);
}


BuoyLauncherServer::~BuoyLauncherServer()
{
  delete _input;
  delete _output;
}


DeviceIF::Status BuoyLauncherServer::nBuoys(short *total, short *launched)
{
  _output->read();

  *total = _output->data._totalNumBuoys;
  *launched = _output->data._numBuoysLaunched;
  return DeviceIF::Ok;
}

DeviceIF::Status BuoyLauncherServer::currentBuoy(short buoyNo)
{
  _input->read();
  if (_input->data._command != '#')
  {
    Syslog::write("BuoyLauncherServer::currentBuoy():Driver busy");
    return DeviceIF::Offline; // device busy
  }

  _input->data._command = 'N';
  _input->data._currentBuoy = buoyNo;
  _input->write();

  // Fire off the LoadData event to the Driver

  return DeviceIF::Ok;
}

DeviceIF::Status BuoyLauncherServer::rotateBuoy()
{
  _input->read();

  if (_input->data._command != '#')
  {
    Syslog::write("BuoyLauncherServer::rotateBuoy():Driver busy %c",
		  _input->data._command);
    return DeviceIF::Offline; // device busy
  }

  _input->data._command = 'R';
  _input->write();

  // Fire off the LoadData event to the Driver

  return DeviceIF::Ok;
}

DeviceIF::Status BuoyLauncherServer::rotateCarousel()
{
  _input->read();

  if (_input->data._command != '#')
  {
    Syslog::write("BuoyLauncherServer::rotate():Driver busy %c",
		  _input->data._command);
    return DeviceIF::Offline; // device busy
  }

 Syslog::write("BuoyLauncherServer::rotateCarousel sending B\n");
  _input->data._command = 'B';
  _input->write();

  // Fire off the LoadData event to the Driver

  return DeviceIF::Ok;
}

DeviceIF::Status BuoyLauncherServer::loadData(BuoyLauncherIF::Filename fname)
{
  _input->read();

  if (_input->data._command != '#')
  {
    Syslog::write("BuoyLauncherServer::loadData():Driver busy %c",
		  _input->data._command);
    return DeviceIF::Offline; // device busy
  }

  _input->data._command = 'X';
  strcpy(_input->data._dataFilename, fname);
  _input->write();

  // Fire off the LoadData event to the Driver

  return DeviceIF::Ok;
}

DeviceIF::Status BuoyLauncherServer::launch()
{
  _output->data._lastLaunchDone = _output->data._inLaunchPosition = 0;
  _output->write();
  _input->read();

  if (_input->data._command != '#')
  {
    Syslog::write("BuoyLauncherServer::launch():Driver busy %c",
		  _input->data._command);
    return DeviceIF::Offline; // device busy
  }

  _input->data._command = 'L';
  _input->write();

  return DeviceIF::Ok;
}

DeviceIF::Status BuoyLauncherServer::launchDummyBuoy()
{
  _output->data._lastLaunchDone = _output->data._inLaunchPosition = 0;
  _output->write();
  _input->read();

  if (_input->data._command != '#')
  {
    Syslog::write("BuoyLauncherServer::launchDuumyBuoy():Driver busy %c",
		  _input->data._command);
    return DeviceIF::Offline; // device busy
  }

  _input->data._command = 'Y';
  _input->write();

  return DeviceIF::Ok;
}

DeviceIF::Status BuoyLauncherServer::statusOn(Boolean on)
{
  return DeviceIF::Ok;

  _input->read();

  if (_input->data._command != '#')
  {
    Syslog::write("BuoyLauncherServer::statusOn():Driver busy %c",
		  _input->data._command);
    return DeviceIF::Offline; // device busy
  }

  if (on)
  {
    Syslog::write("BuoyLauncherServer::calling statusOn(TRUE)");
    _input->data._command = 'C';
  }
  else
  {
    Syslog::write("BuoyLauncherServer::calling statusOn(FALSE)");
    _input->data._command = 'c';
  }

  _input->write();

  return DeviceIF::Ok;
}

DeviceIF::Status BuoyLauncherServer::launched(Boolean *launched)
{
  _output->read();
  *launched = (_output->data._lastLaunchDone != 0);

  return DeviceIF::Ok;
}

DeviceIF::Status BuoyLauncherServer::getLauncherStatus(BuoyLauncherIF::LC_status *status)
{
/* For now, just use the status heartbeat on the Driver
  _input->read();

  if (_input->data._command != '#')
  {
    Syslog::write("BuoyLauncherServer::getLauncherStatus():Driver busy %c",
		  _input->data._command);
    return DeviceIF::Offline; // device busy
  }

  _input->data._command = 'G';
  _input->write();

  while(1)
  {
    delay(100);
    _input->read();
    if (_input->data._command == '#')
      break;
  }
*/
  _output->read();

  status->launcherError = _output->data._launcherError;
  status->lastLaunchOK  = _output->data._lastLaunchOK;
  status->lastLaunchDone = _output->data._lastLaunchDone;
  status->inLaunchPosition = _output->data._inLaunchPosition;
  status->buoyResponsive = _output->data._buoyResponsive;
  status->nextBuoyReady = _output->data._nextBuoyReady;
  status->currentBuoyNumber = _output->data._currentBuoyNumber;
  status->numTotalBuoys = _output->data._totalNumBuoys;
  status->numBuoysRemain = _output->data._numBuoysRemain;
  status->numBuoysLaunched = _output->data._numBuoysLaunched;
  status->timeSec = _output->data._timeSec;
  status->argosBytes = _output->data._argosBytesL;
  status->archiveBytes = _output->data._archiveBytesL;
  status->picoBytes = _output->data._picoBytesL;
  status->dataMemory = _output->data._dataMemoryL;

  Syslog::write("BuoyLauncherServer::getLauncherStatus(): buoyResponsive = %d (%d)",
	 status->buoyResponsive, _output->data._buoyResponsive);
  return DeviceIF::Ok;
}

DeviceIF::Status BuoyLauncherServer::getBuoyStatus(BuoyLauncherIF::BC_status *status)
{
/* For now, just use the status heartbeat on the Driver
  _input->read();

  if (_input->data._command != '#')
  {
    Syslog::write("BuoyLauncherServer::getBuoyStatus():Driver busy %c",
		  _input->data._command);
    return DeviceIF::Offline; // device busy
  }

  _input->data._command = 'S';
  _input->write();

  while(1)
  {
    delay(100);
    _input->read();
    if (_input->data._command == '#')
      break;
  }
*/

  _output->read();

  status->buoyNumber = _output->data._buoyNumber;
  status->mainBattVolts = _output->data._mainBattVolts;
  status->auxBattVolts = _output->data._auxBattVolts;
  status->tempDegC = _output->data._tempDegC;
  status->timeSecBuoy = _output->data._timeSecB;
  status->argosBytes = _output->data._argosBytesB;
  status->archiveBytes = _output->data._archiveBytesB;
  status->picoBytes = _output->data._picoBytesB;
  status->dataMemory = _output->data._dataMemoryB;

  return DeviceIF::Ok;
}

int BuoyLauncherServer::spawnAuxTasks()
{
  char *program = "buoyLauncherDriver";
  char params[256];
  char errorBuf[256];
  int driverPid;

  switch ((driverPid = fork())) {
    
  case 0:
    // In child
    // Execute server program
    execlp(program, program, "-serial", _params->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;
}

void BuoyLauncherServer::name(DeviceIF::Name name)
{
  strcpy(name,"BLS");
}

void BuoyLauncherServer::serialNumber(DeviceIF::Name number)
{
  strcpy(number, "XXX");
}

DeviceIF::Status BuoyLauncherServer::initialize()
{
  // Dummy implementation for now
  return DeviceIF::Ok;
}


DeviceIF::Status BuoyLauncherServer::powerOn()
{
  // Dummy implementation for now
  return DeviceIF::Ok;
}


DeviceIF::Status BuoyLauncherServer::powerOff()
{
  // Dummy implementation for now
  return DeviceIF::Ok;
}


DeviceIF::Status BuoyLauncherServer::status()
{
  // Dummy implementation for now
  return DeviceIF::Ok;
}
