//=========================================================================
// Summary  : 
// Filename : DeviceDriver.h
// Author   : marsh, jrieffel
// Project  : 
// Revision : 1
// Created  : 2000/08/19
// Modified : 2000/08/19
//=========================================================================
// Description :
//=========================================================================
#ifndef _DEVICEDRIVER_H
#include <malloc.h>
#include "DeviceIF.h"
#include "Task.h"
#include "DriverOutput.h"
#include "DataLog.h"
#include "DataLogWriter.h"
#include "DriverCommand.h"
#include "SignalTable.h"

class DeviceDriver : public Task {

  friend class DataLogWriter;

public:

  DeviceDriver(const char *name);

  ~DeviceDriver();

  ////////////////////////////////////////////////////////////////////
  // Send data request to device. DeviceDriver::requestData() does
  // nothing; subclass can override.
  //virtual DeviceIF::Status requestData();

  ////////////////////////////////////////////////////////////////////
  // run() command inherited from Task, does nothing now
  // virtual void run();

  ////////////////////////////////////////////////////////////////////
  // Read data record from device
  //virtual DeviceIF::Status readData() = 0;

  ////////////////////////////////////////////////////////////////////
  // Initialize device
  virtual DeviceIF::Status initialize();


  ////////////////////////////////////////////////////////////////////
  // Process device data
  virtual DeviceIF::Status processRecord(unsigned char *record, 
					 int nRecordBytes);

  ////////////////////////////////////////////////////////////////////
  // Create Command
  // This should also be over-written by drivers that have their own
  // command sets.
  DeviceIF::Status createCommand(DriverCommand **_cmd);
  DeviceIF::Status createCommand(DriverCommand **_cmd, char *name);

  ////////////////////////////////////////////////////////////////////
  // Process Command should be overwritten by drivers that require more
  // commands than the basic.
  virtual DeviceIF::Status processCommand();
  
  ////////////////////////////////////////////////////////////////////
  // Process commands in the Message Queue
  int processCommand_Skel(int request);

  ////////////////////////////////////////////////////////////////////
  // commands to toggle logging on and off 
  void loggingOn();
  void loggingOff();
  Boolean loggingStatus();

  // the following is a kludge for bpauvTailcone
  void setChildProcessesOwnCommands(Boolean it_does);

  ////////////////////////////////////////////////////////////////////
  
  struct Options {

    Options() {
      portName = 0;
      configFileName = 0;
    }

    ~Options() {
      free((void *)portName);
      free((void *)configFileName);
    }

    char *portName;
    char *configFileName;

  };

  static int getOptions(int argc, char **argv, Options *options);


protected:
  typedef void (DeviceDriver::*SignalCallbackMethod)( void );
  typedef SignalTable<SignalCallbackMethod> DriverSignalTable;

  int addSignalCallback( int signo,
			    SignalCallbackMethod callback );

  DeviceIF::Status _state;

  DataLogWriter *_log;
  DriverOutput  *_output_skel;
  DriverCommand *_command;
  
  const unsigned char *_recordTerminator;
  unsigned char *_record;
  unsigned _maxRecordBytes;
  
  // the following is a kludge for bpauvtailcone
  Boolean _Child_Processes_Own_Commands;

   private:
  DriverSignalTable _sigTable;
  //  loadConfig();
};


#endif
