#ifndef AbstractDeviceControllerH
#define AbstractDeviceControllerH

#include "communication/CommandParserListener.h"
#include "communication/AsyncCommandProcessor.h"
#include "communication/Command.h"
#include "communication/CommandParser.h"
#include "communication/CommandProcessorStatistics.h"
#include "protocol/AggreGateDeviceController.h"
#include <boost/thread/recursive_mutex.hpp>

class AbstractDeviceController : public AgObject, public CommandParserListener

{
private:
	int64_t commandTimeout;
	bool resetTimeoutsOnData;
	CommandParserPtr commandParser;
	AsyncCommandProcessorPtr processor;

	bool connecting;
	bool connected;
	bool loggingIn;
	bool loggedIn;

    boost::recursive_mutex mutex;

public:
    virtual bool connectImpl() = 0;
    virtual bool loginImpl() = 0;
    virtual void disconnectImpl() = 0;
    virtual void send(CommandPtr cmd) = 0;

    virtual void processAsyncCommand(CommandPtr cmd);
    void resetCommandTimeouts();
    void startCommandProcessor();
    virtual void setCommandParser(CommandParserPtr commandParser);
    void setConnected(bool connected);
    CommandParserPtr getCommandParser();

public:
    void connect();
	void login();
    void disconnect();
	CommandPtr sendCommand(CommandPtr cmd);
    bool isActive();
    void newDataReceived();
    virtual bool isConnected();

    bool isLoggedIn();
    void setLoggedIn(bool loggedIn);    

    void setResetTimeoutsOnData(bool resetTimeoutWhenDataReceived);
    std::list< ReplyMonitorPtr >  getActiveCommands();
    int64_t getCommandTimeout();
    CommandProcessorStatisticsPtr getStatistics();

    AbstractDeviceController(int64_t commandTimeout);
};

#endif
