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

#ifndef _EdgetechFSDWDRIVER_H
#define _EdgetechFSDWDRIVER_H

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

// Edgetech FSDW Includes.
#include "EdgeTechHandler.h"

// Framework Includes.
#include "Attributes.h"
#include "IntegerAttribute.h"
#include "BooleanAttribute.h"
#include "StringAttribute.h"
#include "FloatAttribute.h"
#include "AttributeParser.h"
#include "Task.h"
#include "Syslog.h"
#include "TimeP.h"
#include "SimpleSocket.h"

// EdgetechFSDWDriver Includes.
#include "EdgetechFSDWOutput.h"
#include "EdgetechFSDWCommand.h"
#include "EdgetechFSDWLog.h"
#include "EdgetechFSDWDataTypes.h"
#include "EdgetechFSDWUtils.h"

// EdgeTech FSDW Handler Class
#include "EdgeTechHandler.h"



#define EdgetechFSDWDriverName "edgetechFSDW"
#define ConfigurationFile "edgetechFSDW.cfg"

/// Class EdgetechFSDWDriver
class EdgetechFSDWDriver : public Task
{
 public:
    EdgetechFSDWDriver();
    ~EdgetechFSDWDriver();

//    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);

    int Command_StartSubsystem(int subSystem, Boolean bUpdate);
    int Command_StopSubsystem(int subSystem, Boolean bUpdate);
    int Command_StartStopSubsystem(int subSystem, int action, Boolean bUpdate);
    int Command_SetPulseFilename(int subSystem, char *pulseFilename, Boolean bUpdate);
    int Command_SetPingRange(int subSystem, float range, Boolean bUpdate);
    int Command_SetPingRate(int subSystem, float rate, Boolean bUpdate);
    int Command_SetPulsePower(int subSystem, float percentage, Boolean bUpdate);
    int Command_StartEdgetechStorage(Boolean bUpdate);
    int Command_StopEdgetechStorage(Boolean bUpdate);
    int Command_GetVersion();
    int Command_GetSonarStatus(int subSystem);
    int Command_SetTime(Boolean bUpdate);
    int Command_SetSBPGain(float gain, Boolean bUpdate);
    int Command_SetSBPDuration(float milliseconds, Boolean bUpdate);
    int Command_StartDataLogging();
    int Command_StopDataLogging();
    int Command_RelayCompositeSituation(long flags,
    		unsigned char vDirections,
    		timespec timestamp,
    		double latitudeD,
    		double longitudeD,
    		float depthM,
    		float altitudeM,
    		float heaveM,
    		float velocity1MS,
    		float velocity2MS,
    		float velocityDownMS,
    		float pitchD,
    		float rollD,
    		float headingD,
    		float soundSpeedMS,
    		float waterTempC
    		);

    int Command_RelaySituation(
    		long flags,  timespec timestamp,  double latitudeD,  double longitudeD,  double depthM,  double headingD,  double pitchD,  double rollD,  double xRelativePosM,  double yRelativePosM,  double zRelativePosM,
			 double xVelocityMS,  double yVelocityMS,  double zVelocityMS,  double northVelocityMS,  double eastVelocityMS,  double downVelocityMS,  double xAngularRateDS,  double yAngularRateDS,  double zAngularRateDS,
			 double xAccelerationMS,  double yAccelerationMS,  double zAccelerationMS,  double latitudeStandardDeviationM,  double longitudeStandardDeviationM,  double depthStandardDeviationM,  double headingStandardDeviationD,
			 double pitchStandardDeviationD,  double rollStandardDeviationD
    	);

    int Command_RelayPressureRecord(
    		 float pressurePSI,
    		 float tempC,
    		 float  salPSU,
    		 float condSM,
    		 float sosMS,
    		 float depthM,
    		 long flags
    );

    int Command_RelayAltitude(
    		long flags,
    		float altitudeM,
    		float forwardVelocityMS,
    		float crossTrackVelocityMS
    );

    int setRecalcInterval(int new_interval) {
      int my_int = _recalcInterval;
      _recalcInterval = new_interval;
      return my_int;
    }
    
 protected:
    // EdgetechFSDWDriver functions.
    void loadConfiguration(char *configFile);
        
    //Attributes _attributes;
    EdgetechFSDWOutput *_output;
    EdgetechFSDWOutput::Data *_data;
    EdgetechFSDWCommand *_command;
    EdgetechFSDWLog *_log;

 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();

    // Edgetech Functions.
    //    EdgetechFSDWCommands *_edgetechPayCmds;

    // EdgeTech Functions
    EdgeTechHandler *_edgetechCmds;

    char _buffer[32];

    // Attributes.
    debug_t debug;

    TimeIF::TimeSpec _timeStamp, _fullTime;
    //    Time::TimeParts _fullTime;
    
    long _lastRecalcTime;
    long _recalcInterval; // in seconds
};

#endif
