//-------------------------------------------------------------------------------------------------
// <copyright file="LWConcreteCmd.h" company="LiquidRobotics">
//  Copyright (c) Liquid Robotics Corporation, confidential and proprietary.  All rights reserved. 
// </copyright>
//
// <summary>
//	Declarations for the following classes:
//
//	- LWControllerBase0, which acts as an abstract base class from which the
//	  controller class derives (commands access the controller through this base
//	  class)
//
//	- LWConcreteCmd, the base class for all commands in this module (typedef'd)
// </summary>
//
// <owner>Mike Cookson</owner>
//-------------------------------------------------------------------------------------------------

#ifndef __LWConcreteCmd_h__
#define __LWConcreteCmd_h__

#include "LqrSMACSerialListener.h"
#include "LqrSMACSerialPort.h"
#include "LqrSMACSharedLib.h"
#include "IEventBase.h"
#include "SensorCommandBase.h"
#include "SensorConcreteCommand.h"
#include "SensorControllerBase.h"
#include "SensorControllerBaseCmdID.h"
#include "SensorControllerExceptions.h"
#include <string>
#include <vector>

namespace LiquidRobotics {

namespace EventLib {
	class EventPropertyValue;
}

namespace SMACFramework {
	class ByteArray;
	class LuaInstance;
}

namespace LuaWrapper {

typedef EventLib::SensorControllerBaseCommandID LWCmdID;
typedef EventLib::SensorCommandBase<LWCmdID> LWControllerCommand;
typedef EventLib::SensorControllerBase<LWControllerCommand,LWCmdID> LWControllerBase0Base;

class SHARED_LIB_PUBLIC LWControllerBase0
: public LWControllerBase0Base
{
public:

	typedef LiquidRobotics::SMACFramework::ByteArray ByteArray;
	typedef LiquidRobotics::EventLib::EventPropertyValue EventPropertyValue;
	typedef LiquidRobotics::EventLib::IEventBase IEventBase;
	typedef LiquidRobotics::SMACFramework::ISerialPort ISerialPort;
	typedef LiquidRobotics::SMACFramework::LuaInstance LuaInstance;
	typedef boost::shared_ptr<LuaInstance> LuaInstancePtr;
	typedef LiquidRobotics::SMACFramework::SerialListener SerialListener;
	typedef std::string string;
	typedef std::vector<string> StringArray;

	// Closes and deallocates a lua instance of the given name; throws invalid_argument in the case that there is no
	// such instance name
	virtual void CloseLua(const string& instanceName) = 0;

	// Marks the configuration as no longer used
	virtual void CloseSerialPortConfig(const string& configName) = 0;

	// Creates a telemetry event
	virtual IEventBase::Ptr CreateTelemetryEvent(const string& eventName, const string& eventTypeName, const string& eventDomainName) = 0;

	// forwards data to indicate lua instance and script (buffers the data in the thread command queue)
	virtual void ForwardSerialData(const string& instanceName, const string& portInstanceName, const ByteArray& data) = 0;

	//virtual void ForwardSerialDataImmediate(const string& instanceName, const string& portInstanceName, const ByteArray& data) = 0;

	// forwards a timeout event to lua instance
	virtual void ForwardTimeout(const string& instanceName, const string& timerName) = 0;

	// retrieves the latitude and longitude values, returns a flag indicating if any location has been received
	virtual bool GetLocation(double& latVar, double& lonVar) const = 0;

	// returns the lua instance for the given name
	virtual LuaInstancePtr GetLuaInstance(const string& instanceName) = 0;

	// returns the names of all lua instances and the command file for each
	virtual void GetLuaInstanceReport(StringArray& result) = 0;

	// looks up the server name and type for a board address
	virtual void GetServerDetails(unsigned boardAddress, string& serverName, string& serverTypeName) = 0;

	// invokes a remote command; returns true if completed, false if waiting for asynch completion
	virtual bool InvokeSendCommand(const string& serverName, const string& serverType, EventPropertyValue& epvCommand,
			EventPropertyValue& epvResponse, string& asynchronousResponseTag, bool asynch) = 0;

	// opens a lua file and assigns the given instance name, throws invalid argument if there is already an instance name as specified
	// or if the file cannot be opened or if there are any errors throws in the parsing process
	virtual void OpenLua(const string& instanceName, const string& luaFileName, int traceOpt = 0) = 0;

	// opens/creates a serial port listener immediately, throws invalid argument if the port cannot be opened or there is no such
	// config name
	virtual void OpenSerialPortConfig(const string& configName, ISerialPort::Ptr& resultingPort, SerialListener::Ptr& resultingListener) = 0;

	// publishes data set via event
	virtual void PublishDataSet(const string& instanceName, const string& eventName, const string& eventType, const string& eventDomain,
			const string& dataSetName, const string& content) = 0;

	// runs a single lua command object and waits for completion
	virtual string RunLuaCommand(CommandPtr cmdp, bool awaitResult = true) = 0;

	// configures trace options for an instance
	virtual void SetTraceOptions(const string& instanceName, int traceOpt) = 0;

	// configures trace options for an instance (from internal command)
	virtual void SetTraceOptionsInternal(const string& instanceName, int traceOpt) = 0;

	// transmits an event
	virtual void TransmitEvent(IEventBase& evt) = 0;

	/*virtual void CloseSerialConfig(const string& name) = 0;
	virtual bool IsLuaOpened() const = 0;
	virtual void OpenSerialConfig(const string& configName) = 0;
	virtual void TransmitSerial(const string& name, const ByteArray& data);*/
};

typedef EventLib::SensorConcreteCommand<LWControllerBase0,
										EventLib::SensorCommandBase<LWCmdID>,
										LWCmdID,
										EventLib::SensorControllerExceptions> LWConcreteCmd;

}
}

#endif
