#ifndef AbstractAggreGateDeviceControllerH
#define AbstractAggreGateDeviceControllerH

#include "communication/AbstractDeviceController.h"
#include "util/ThreadPool.h"
#include "util/Pointers.h"

#include "util/AgThreadPool.h"

class AbstractAggreGateDeviceController: public AbstractDeviceController
{
private:
    AggreGateDevice* device;
    ContextManager *contextManager;
    CallerControllerPtr callerController;
    UserSettingsPtr userSettings;
	bool avoidSendingFormats;
	FormatCachePtr formatCache;    
    AgThreadPoolPtr eventPreprocessor;

    void processEvent(IncomingAggreGateCommandPtr cmd);    

protected:
    void taskProcessEvent(IncomingAggreGateCommandPtr cmd);

public:
    AbstractAggreGateDeviceController(AggreGateDevice* dev);
    virtual ~AbstractAggreGateDeviceController();
    virtual ContextManager* getContextManager();
    void setContextManager(ContextManager* contextManager);
    void setDevice(AggreGateDevice* device);
    virtual AggreGateDevice* getDevice();
    virtual CallerControllerPtr getCallerController();
    FormatCachePtr getFormatCache();
    virtual UserSettingsPtr getSettings();
    ClassicEncodingSettingsPtr createClassicEncodingSettings(bool forSending);
    bool isAvoidSendingFormats();
    virtual void start() = 0;
    void destroy();
    IncomingAggreGateCommandPtr sendCommandAndCheckReplyCode(OutgoingAggreGateCommandPtr cmd);
    virtual AgString toString();
    DataTablePtr callRemoteFunction(const AgString& context, const AgString& name, TableFormatPtr outputFormat, DataTablePtr parameters);
    DataTablePtr decodeRemoteDataTable(TableFormatPtr format, AgString encodedReply);
    virtual bool connectImpl();
    virtual void disconnectImpl();

protected:
    void setCallerController(CallerControllerPtr callerController);
    void setAvoidSendingFormats(bool avoidSendingFormats);
    std::list<ProxyContext*> getProxyContexts(AgString path);
    virtual void processAsyncCommand(CommandPtr cmd);
    virtual void confirmEvent(Context* con, EventDefinitionPtr def, EventPtr event);
    virtual void setCommandParser(CommandParserPtr commandBuffer);    
};

#endif
