//=========================================================================
// Summary  :
// Filename : DeviceDriver.cc
// Author   : marsh
// Project  :
// Revision : 1
// Created  : 2000/08/19
// Modified : 2000/08/19
//=========================================================================
// Description :
//=========================================================================
#include "DeviceDriver.h"
#include "Syslog.h"
#include "DeviceIF.h"

int SignalTable<DeviceDriver::SignalCallbackMethod>::_lastSignal = -1;

DeviceDriver::DeviceDriver(const char * name)
     : Task(name)
{
     _Child_Processes_Own_Commands = False;
     _state = DeviceIF::Initializing;
     _log = NULL;
     _output_skel = NULL;
     _command = NULL;
}


DeviceDriver::~DeviceDriver()
{
//     delete _log;
//     delete _output_skel;
//     delete _command;
}

// this method may be broken.  Either modify your own inherited createCommand
// or use the method below.

DeviceIF::Status DeviceDriver::createCommand(DriverCommand **_cmd)
{
     *_cmd = new DriverCommand( MessageQueue::ReadWrite );
     return DeviceIF::Ok;
}

//this is the createCommand used by devices that don't have their own command.
// i.e. most streamserialDrivers.

DeviceIF::Status DeviceDriver::createCommand(DriverCommand **_cmd, char *name)
{
     *_cmd = new DriverCommand(MessageQueue::ReadWrite,name,sizeof(DriverCommand::Command_Skel),5,False);
     return DeviceIF::Ok;
}

int DeviceDriver::processCommand_Skel(int request)
{
     //ugh okay, we're gonna let the child driver actually read the command
     // and then pass what it reads to us.  Right now this seems like the worst
     // of evils

     // we will return a "1" if we intercepted the command
     // and a "0" if we did not.
     // Syslog::write("DeviceDriver:processCommand: %d\n",request);

  // i regret that because this takes a single value of int, it cannot parse
  // the "ival" of a command.  This will soon change (as soon as it needs to)

     switch(request)
     {
     case DriverCommand::StartLogging:
	  Syslog::write("DeviceDriver:processCommand_Skel: StartLogging\n");
	  loggingOn();
	  return 1;
     case DriverCommand::StopLogging:
	  Syslog::write("DeviceDRiver:processCommand_Skel: StopLogging\n");
	  loggingOff();
	  return 1;
     default:
	  return 0;
     }

}

/////////////////////////////////////////////////////////////////////////////
// This virtual function should be overwritten by device drivers
// that need more commands than the basic ones.
virtual DeviceIF::Status DeviceDriver::processCommand()
{
     DriverCommand::Command_Skel cmdIn;

     //  Syslog::write("DeviceDriver::processCommand() - parent is processcing commands!\n");
     if (_command)
     {
	  while ( (_command->read(&cmdIn)) > 0)
	  {
	       if (!(DeviceDriver::processCommand_Skel(cmdIn.request)))
	       {
	       }
	  }
     }
     else
     {
	  Syslog::write("DeviceDriver::processCommand() - command does not exist!\n");
     }
     return DeviceIF::Ok;
}

DeviceIF::Status DeviceDriver::initialize()
{
     return DeviceIF::Ok;
}

DeviceIF::Status DeviceDriver::processRecord(unsigned char *record,int nRecordBytes)
{
     return DeviceIF::Ok;
}

void DeviceDriver::loggingOn()
{
     if (_log)
     {
	  if (!(loggingStatus()))
	       _log->loggingOn();

     }
     else
	  Syslog::write("DeviceDriver:;loggingOn() - log doesn't exist!\n");
}

void DeviceDriver::setChildProcessesOwnCommands(Boolean it_does)
{
     _Child_Processes_Own_Commands = it_does;
}


void DeviceDriver::loggingOff()
{
     if (_log)
     {
	  if (loggingStatus())
	       _log->loggingOff();
     }
     else
	  Syslog::write("DeviceDriver::loggingOff() - log doesn't exist!\n");
}

Boolean DeviceDriver::loggingStatus()
{
     return _log->loggingStatus();
}

int DeviceDriver::getOptions(int argc, char **argv,
			     DeviceDriver::Options *options)
{
     Boolean error = False;

     for (int i = 1; i < argc; i++) {

	  if (!strcmp(argv[i], "-dev") && i < argc - 1) {
	       options->portName = strdup(argv[++i]);
	  }
	  else if (!strcmp(argv[i], "-cfg") && i < argc - 1) {
	       options->configFileName = strdup(argv[++i]);
	  }
	  else {
	       error = True;
	  }
     }

     if (error) {
	  return -1;
     }
     else
	  return 0;
}


int DeviceDriver::addSignalCallback( int signo,
				     SignalCallbackMethod callback )
{
//     Syslog::write("Registering function at %x to signal %d",
//		   callback, 17 );
     return _sigTable.addCallback( 17, callback );
}

