//=========================================================================
// Summary  : Remote Agent Driver.
// Filename : RemoteAgentDriver.h
// Author   : bluefinrobotics.com
// Project  : Remote Agent Driver.
// Revision : 1
// Created  : 2002
// Modified : 2003.03.11 Reed: added sendSeabirdSBE25.
//=========================================================================
// Description :  Remote Agent Driver.
//=========================================================================

#ifndef _REMOTEAGENTDRIVER_H
#define _REMOTEAGENTDRIVER_H

#include "BluefinPowerSystemIF.h"
#include "MMDropWeight.h"
#include "LayeredControlIF.h"
#include "MMMissionName.h"
#include "MMRecipient.h"

#include "RemoteAgentOutput.h"
#include "RemoteAgentCommand.h"

class ModemMessage;
class MMActiveBehavior;
class MMAgentRequest;
class MMBehavior;
class MMBehaviorArray;
class MMTailcone;
class MMCircuit;
class MMCircuitBatch;
class MMCurrent;
class MMDriver;
class MMServerAlarm;
class MMDynamicControlCommand;
class MMDynamicControlCommandFull;
class MMBluefinBatteryInfo;
class MMWatchdog;
class MMUSBLFix;
class NavigationIF;
class LayeredControlIF;
class BluefinTailconeIF;
class DynamicControlIF;
class VehicleConfigurationIF;
class BluefinBatteryIF;
class AhrsIF;
class CrossbowIF;
class MicrostrainIF;
class DepthSensorIF;
class LiPolyBatteryIF;
class RdiadcpIF;
class ApogeeHomingIF;
class MultiLeicaIF;
class SeacatSBE19IF;
class SBE25IF;
class GpsIF;
class ExternalPosFixIF;
class MMNmea;
class MMRtcm;
class RtcmIF;
class MMServer;
class MMMissionInfo;
class MMMissionName;
class MMMultiLeica;
class SupervisorIF;
class SocketBroker;
class ModemBroker;
class RangeFinderIF;
class SVSIF;
class AvtrakIF;
class Ln250IF;
class LUSBLFilterIF;
class TaskInterface;
class Sas21IF;
class MMPhins;
class PhinsIF;
class BluefinEnvIF;
class FluorometerIF;


class RemoteAgentDriver :  public MMRecipient
{
public:
	RemoteAgentDriver();
	~RemoteAgentDriver();

	// Overrides.
	virtual int init();
	virtual void run();

	// queues a copy of message to send it out
	static void send(ModemMessage* pMM);

	static RemoteAgentDriver * getRemoteAgentDriver();

	// Sort the messages
	void receive(const ModemMessage* pMessage);

	virtual void enableModem();
	virtual void disableModem();

protected:
	RemoteAgentCommand* _command;
	void nullRequest();
	void nullHandler(ModemMessage* mm);

	static void signalChildHandler( int sigNo );

	int checkServer(char *name);

	// Reset all message flags
	void resetMessageFlags(int speed);

	// Read config file
	void loadConfiguration();

	// Create servers
	void createServers();

	// Verify servers still exist
	void verifyServers();

	// Check for messages at remoteBroker
	Boolean checkForMessages();

	//process commands coming in
	void processRequests();

	// Maintain event service
	void sendMessages();

	// Determine whether or not to send a message
	Boolean checkForSending(Boolean flag, int period);

	//polls acks if they need polling
	void pollAcks();

	//file requests for sends to topside
	void processRequestCommand(short mm, short tt, short p);

	//handle special "poinker" commands
	void processPoinkerCommand(char * j);

	//alternate, string based parsing of string messages
	void handleString(ModemMessage* mm);

	// Handle an agent request message
	void handleRequest(ModemMessage* mm);

	//handle a behavior message
	void handleBehavior(ModemMessage* mm);

	//handle a behavior array message
	void handleBehaviorArray(ModemMessage* mm);

	//handle a mission name, meaning changing current mission

	void handleMissionName(ModemMessage* mm);

	void handleJumpBehavior(ModemMessage* mm);

	//handle a driver command
	void handleDriverCommand(ModemMessage* mm);

	// Get the current time
	int getTime();

	// Reload the vehicle configuration (etc.)
	void reloadVehicle();

	// Message sending functions
	void sendAck();
	void sendActiveBehavior();
	void sendOas();
	void sendSvs();
	void sendLN250();
	void sendNavigationPosition();
	void sendNavigationAttitude();
	void sendTailconeRemote();
	void sendTailconeLocal(ModemMessage* mm);
	void sendTailconeRaw();
	void sendCircuitRemote(int circuit);
	void sendCircuitBatchRemote();
	void sendCircuitLocal(ModemMessage* mm);
	void sendCircuitBatchLocal(ModemMessage* mm);
	void sendCircuitCurrent(int circuit);
	void sendCircuitCurrentBatch();
	void sendCircuitInfo();
	void sendGroundFaultCurrent(int fault);
	void sendGroundFaultCurrentBatch();
	void sendTemperature(int temperature);
	void sendTemperatureBatch();
	void sendWaterAlarm(int number);
	void sendWaterAlarmBatch();
	void sendServerAlarm(int server);
	void sendServerAlarmBatch();
	void sendDropWeightReleaseLocal(ModemMessage* mm);
	void sendDropWeightReleaseBatchRemote();
	void sendDynamicControlCommandLocal(ModemMessage* mm);
	void sendDynamicControlCommandRemote();
	void sendDynamicControlCommandFullLocal(ModemMessage* mm);
	void sendDeviceInfo();
	void sendAhrs();
	void sendMultiLeica();
	void sendSeacat();
	void sendSeabirdSBE25();
	void sendSas21();
	void sendDepthSensor();
	void sendBluefinBatteryInfo();
	void sendBluefinBatteryGlobal();
	void sendWatchdogCommand(ModemMessage* mm);
	void sendDvl();
	void sendDvlBeamVelocities();
	void sendDvlBeamRanges();
	void sendDvlAttTemp();
	void sendHoming();
	void sendGps();
	void sendNmea();
	void sendExternalPosFix(ModemMessage* mm);
	void sendAbortMission();
	void sendKillMission();
	void sendRtcmMessage(ModemMessage* mm);
	void sendUSBLFixMessage(ModemMessage* mm);
	void serverMessage(ModemMessage* mm);
	void sendMissionInfo(ModemMessage* mm);
	void sendDriverStatus();
	void sendLogDirName();
	void sendPhins();
	void sendEnvironmental();
	void sendFluorometer();

	void sendControlExecute();

	void pack(const char * target);
	// Drop weight enum conversion
	BluefinPowerSystemIF::Weight getBluefinPowerSystemIF(MMDropWeightRelease::Weight weight);
	MMDropWeightRelease::Weight getDropWeightMM(BluefinPowerSystemIF::Weight weight);

	// Internal counter
	long m_count;

	//mission change counters
	short _misCounter;

	//internal attributeChange counter
	short _attCounter;

	//to hold things waiting for acknowledgements
	short _singleAck;
	LayeredControlIF::AckData _ackData;
	short* _attNums;
	short* _attDone;
	short _ackArraySize;

	MMMissionName::MissionType m_misType;

	//a couple flags
	Boolean m_ackSingle;
	Boolean m_ackArray;
	Boolean m_ackMis;

	// Server stubs
	NavigationIF *m_navigation;
	LayeredControlIF *m_layeredControl;
	BluefinTailconeIF *m_tailcone;
	BluefinPowerSystemIF *m_power;
	DynamicControlIF *m_dynamicControl;
	VehicleConfigurationIF *m_vehicleConfiguration;
	AhrsIF *m_ahrs;
	CrossbowIF *m_crossbow;
	MicrostrainIF *m_microstrain;
	MultiLeicaIF *m_multiLeica;
	SeacatSBE19IF *m_seacat;
	SBE25IF *m_seabirdSBE25;
	DepthSensorIF *m_depthSensor;
	BluefinBatteryIF *m_battery;
	RdiadcpIF *m_dvl;
	ApogeeHomingIF *m_homing;
	GpsIF *m_gps;
	ExternalPosFixIF *m_externalPosFix;
	RtcmIF *m_rtcm;
	SupervisorIF *m_supervisor;
	RangeFinderIF *m_oas;
	SVSIF *m_svs;
	AvtrakIF *m_avtrak;
	Ln250IF *m_ln250;
	LUSBLFilterIF *m_lusbl;
	Sas21IF *m_sas21;
	PhinsIF *m_phins;
	BluefinEnvIF *m_env;
	FluorometerIF *m_flu;

	typedef void (RemoteAgentDriver::* rF)();
	typedef void (RemoteAgentDriver::* hF)(ModemMessage* mm);

	rF m_requestFunctionList[66];
	hF m_handleFunctionList[66];

	char m_flagList[2][66];
	short m_periodList[2][66];
	int m_speed;

	TaskInterface * m_serverList[32];

	char* m_serverNameList[32];
	int m_numServers;

	virtual int spawnAuxTasks( void ) {return 1;};
 private:
	////////////////////////////////////////////////////////////////////
	// signal handler
	static void signalHandler(int signalNo);

	////////////////////////////////////////////////////////////////////
	// Destroy latest ras object
	static void cleanup();

	// For debug printing
	debug_t debug;

	//to allow modem to be used or not
	Boolean _allowComs;

	ModemBroker* _modemBroker;

	const char* _remoteSocketIP;   // text version of the target socket IP
	const char* _serialPort1;      // serial port for serial modem 1
	const char* _serialPort2;      // serial port for serial modem 2
	long _baudRate1;	       // baud rate for serial modem 1
	long _baudRate2;	       // baud rate for serial modem 2

	long _connectionSpeed;

	static RemoteAgentDriver* _gpRemoteAgentDriver;

};

#endif



