//-------------------------------------------------------------------------------------------------
// <copyright file="SEController.h" company="LiquidRobotics">
//  Copyright (c) Liquid Robotics Corporation, confidential and proprietary.  All rights reserved. 
// </copyright>
//
// <summary>
// 	Declarations for the SEController class, which implements the controller
//  role business logic for an example controller
// </summary>
//
// <owner>Mike Cookson</owner>
//-------------------------------------------------------------------------------------------------

#ifndef __SEController_H__
#define __SEController_H__

#include "SEClassConfig.h"
#include "SEControllerSettings.h"
#include "SensorController.h"
#include "LqrSMACSerialPort.h"
#include "LqrSMACSerialListener.h"
#include <boost/thread.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <map>
#include <set>

namespace LiquidRobotics {

namespace EventLib {
	class GPSSampleEvent;
};

namespace SMACFramework {
	class ByteArray;
	class CmdOutputFormatter;
}

namespace SensorExample {

typedef EventLib::SensorController<SEControllerBase0,SEControllerCommand,SECmdID,EventLib::SensorControllerExceptions> SEControllerBase;

class SHARED_LIB_PUBLIC SEController
: public SEControllerBase
{
public:

	typedef boost::shared_ptr<CommandQueue> CommandQueuePtr;
	typedef SEControllerBase Base;
	typedef std::string string;
	typedef boost::signals2::signal<void (const string& data, timeval& time, double lat, double lon)> ReportedTagSignalType;

	SEController(const SEControllerSettings& _settings, IObjectBroker& _broker, Logger& _logger, GPSSignalSubscriber::Ptr _gpsSubscriber, ShutdownSignalSubscriber::Ptr _shutdownSubscriber);
	virtual ~SEController();

	void Initialize();
	void Shutdown();

	ScopedConnectionPtr SubscribeReportedTag(ReportedTagSignalType::slot_type slot);

protected:

	typedef LiquidRobotics::SMACFramework::ByteArray ByteArray;
	typedef LiquidRobotics::EventLib::GPSSampleEvent GPSSampleEvent;
	typedef LiquidRobotics::SMACFramework::SerialListener SerialListener;

	virtual void OnGPSSampleEvent(const GPSSampleEvent& sample);
	virtual void OnSerialReceive(SerialListener& sender, const ByteArray& receivedData);
	virtual void OnShutdownEvent();
	virtual CommandPtr ParseCommand(TCon::ParsingContext& context, bool internalCmd = false);

private:

	typedef boost::recursive_mutex Mutex;
	typedef boost::unique_lock<Mutex> MutexLock;
	typedef LiquidRobotics::SMACFramework::SerialPort SerialPort;
	typedef SerialPort::Ptr SerialPortPtr;
	typedef SerialListener::Ptr SerialListenerPtr;
	typedef std::set<string> StringSet;

	Mutex mutex;
	const SEControllerSettings& settings;
	double lat, lon;
	double hasGPS;
	SerialPortPtr serialPort;
	ReportedTagSignalType reportedTagSignal;
	SerialListenerPtr serialListener;
	ScopedConnectionPtr serialListenerConnection;
};

typedef boost::shared_ptr<SEController> SEControllerPtr;

}
}

#endif
