//============================================================================
/// Summary  : Reson 6046 Driver
/// Filename : Reson6046Driver.h
/// Author   : Reed Christeson, reed@bluefinrobotics.com
/// Project  : Reson 6046 Driver
/// Revision : 0.0
/// Created  : 2002.03.21
/// Modified : 2002.03.21
//============================================================================

#ifndef _RESON6046DRIVER_H
#define _RESON6046DRIVER_H

// System Includes.
#include <string.h>
#include <math.h>   // for ceil function

// Framework Includes.
#include "Attributes.h"
//#include "DebugAttribute.h"
#include "IntegerAttribute.h"
#include "BooleanAttribute.h"
#include "StringAttribute.h"
#include "FloatAttribute.h"
#include "AttributeParser.h"
#include "PeriodicTask.h"
#include "Syslog.h"
//#include "VehicleConfigurator.h"
#include "TimeP.h"
#include "InsIF.h"
#include "AuvTimeSyncIF.h"
#include "NavigationIF.h"
#include "FastCatIF.h"
#include "DepthSensorIF.h"
#include "AdamIF.h"
#include "SimpleSocket.h"

// Framework Interfaces.
//#include "VehicleConfigurationIF.h"

// Reson6046Driver Includes.
#include "Reson6046Output.h"
#include "Reson6046Command.h"
#include "Reson6046Log.h"
#include "Reson6046DataTypes.h"
#include "Reson6046Commands.h"
#include "Reson6046Utils.h"

#define Reson6046DriverName "reson6046"
#define ConfigurationFile "reson6046.cfg"

/// Class Reson6046Driver
class Reson6046Driver : public PeriodicTask
{
 public:
    Reson6046Driver();
    ~Reson6046Driver();

    int sendCommand(U32 recordTypeIdentifier,
		    U32 sensorIndex,
		    U32 commandID,
		    U32 action,
		    char *command);
    int sendCommand(U32 recordTypeIdentifier,
		    U32 sensorIndex,
		    U32 commandID,
		    U32 action,
		    char *command,
		    U32 parameter);
    int sendCommand(U32 recordTypeIdentifier,
		    U32 sensorIndex,
		    U32 commandID,
		    U32 action,
		    char *command,
		    F32 parameter);
    int sendCommand(U32 recordTypeIdentifier,
		    U32 sensorIndex,
		    U32 commandID,
		    U32 action,
		    char *command,
		    char *parameter);
    int sendCommand(U32 recordTypeIdentifier,
		    U32 sensorIndex,
		    U32 commandID,
		    U32 action,
		    char *command,
		    U32 parameter1,
		    U32 parameter2);
    int sendCommand(U32 recordTypeIdentifier,
		    U32 sensorIndex,
		    U32 commandID,
		    U32 action,
		    char *command,
		    U32 parameter1,
		    U32 parameter2,
		    U32 parameter3,
		    U32 parameter4,
		    U32 parameter5,
		    F32 parameter6);

    // PLC Command ID  0
    int Command_StartSubsystem(int subSystem);
    int Command_StopSubsystem(int subSystem);
    int Command_StartStopSubsystem(int subSystem, int action);
    int Command_SetPulseFilename(int subSystem, char *pulseFilename);
    int Command_SetPingRange(int subSystem, float range);
    int Command_SetPingRate(int subSystem, float rate);
    int Command_SetPulsePower(int subSystem, float percentage);
    // PLC Command ID  1
    int Command_StartLogging(); 
    int Command_StopLogging();
    // PLC Command ID  4
    int Command_GetVersion();
    // PLC Command ID  9
    int Command_SetAlarm(int alarmID, int action);
    // PLC Command ID 10
    int Command_GetSonarStatus(int subSystem);
    // PLC Command ID 11
    int Command_SetVerboseMode(int action);
    // PLC Command ID 14
    int Command_GetModules();
    // PLC Command ID 15
    int Command_GetRunList();
    // PLC Command ID 18
    int Command_Reserved1();
    // PLC Command ID 19
    int Command_Reserved2();
    // PLC Command ID 20
    int Command_SetTime();
    // PLC Command ID 21
    int Command_GetHealth(int subSystem);

    int Command_SetSBPGain(float gain);
    int Command_SetSBPDuration(float milliseconds);
    
    // Multibeam Remote Command
    int MB_RemoteCommand(int cmdID,
			 float cmdParam = 0.,
			 float cmdParam1 = 0.,
			 float cmdParam2 = 0.,
			 float cmdParam3 = 0.,
       int   iParam = 0);

    // Nav and CTD messages
    // PLC Record Type 1010 appended to Bluefin-style Env record
    int Message_SetCTD();
    int Message_SetNav();
    void initBFRecords();
    void displayBFRecords(int type); // type: Nav = 1, env = 2
    void processExternalSensors();

    int setRecalcInterval(int new_interval) {
      int my_int = _recalcInterval;
      _recalcInterval = new_interval;
      return my_int;
    }
    
 protected:
    // Reson6046Driver functions.
    void loadConfiguration(char *configFile);
        
  	// Recalculate params based on current altitude
    // If commanded from mission script, recalc immediately
  	// otherwise only do it at interval from config file
    //    
    void recalcParams(Boolean commanded = false);

    //Attributes _attributes;
    Reson6046Output *_output;
    Reson6046Output::Data *_data;
    Reson6046Command *_command;
    Reson6046Log *_log;

    // Bluefin nav and env records
    T7KCTDRTH  _7kCTD;
    TBfNavRecord _bfNav;
    TBfEnvRecord _bfEnv;

 private:
    // Framework functions.
    void periodicCallback(void);
    virtual DeviceIF::Status processCommand(void);
    virtual DeviceIF::Status createCommand(DriverCommand **cmd);

    //error handling function
    void resetInitError();
    void onInitError();
    void onInitFailure();
    void resetError();
    void onError();
    void onFailure();
    U32 decodeRecord(unsigned char* data, int dataLen); // return record type id

    // Socket Functions.
    SimpleSocket *_plcConnSocket;
    SimpleSocket *_mbDataSocket;
    SimpleSocket *_bfDataSocket;

    // Reson Functions.
    Reson6046Commands *_resonPayCmds;

    char _buffer[32];

    // Attributes.
    debug_t debug;

    TimeIF::TimeSpec _timeStamp, _fullTime;
    //    Time::TimeParts _fullTime;

    // Server interfaces
    NavigationIF  *_navIF;
    AuvTimeSyncIF *_atsIF;
    InsIF         *_insIF;
    FastCatIF     *_fastcatIF;
    DepthSensorIF *_depthSensorIF;
    AdamIF	  *_adamIF;
    
    long _lastRecalcTime;
    long _recalcInterval; // in seconds
};

#endif
