#include "AbstractClientController.h"
#include "context/CallerController.h"
#include "context/ContextManager.h"
#include "event/ContextEventListener.h"
#include "event/ContextEventListenerSet.h"

AbstractClientController::AbstractClientController()
{
}

AbstractClientController::AbstractClientController(ContextManager* contextManager)
{
    this->contextManager = contextManager;
}

AbstractClientController::AbstractClientController(ContextManager* contextManager, CallerControllerPtr callerController)
{
    this->contextManager = contextManager;
    this->callerController = callerController;
}

CallerControllerPtr AbstractClientController::getCallerController()
{
    return callerController;
}

void AbstractClientController::setCallerController(CallerControllerPtr callerController)
{
    this->callerController = callerController;
}

void AbstractClientController::addMaskListener(const AgString & context, const AgString & name, ContextEventListenerPtr cel, bool weak)
{
    contextManager->addMaskEventListener(context, name, cel, weak);
    if (weak) {
        boost::lock_guard<boost::mutex> lock(listenersMutex);

        std::map< AgString, std::map<AgString, ContextEventListenerSetPtr> >::iterator itListeners = listeners.find(context);
        if (itListeners == listeners.end())
        {
            listeners[context] = std::map<AgString, ContextEventListenerSetPtr>();
            itListeners = listeners.find(context);
        }

        std::map<AgString, ContextEventListenerSetPtr>::iterator itEventListener = itListeners->second.find(name);
        if (itEventListener == itListeners->second.end())
        {
            itListeners->second[name] = ContextEventListenerSetPtr(new ContextEventListenerSet());
            itEventListener = itListeners->second.find(name);
        }

        itEventListener->second->addListener(cel, false);
    }
}

void AbstractClientController::removeMaskListener(const AgString & context, const AgString & name, ContextEventListenerPtr cel)
{    
    contextManager->removeMaskEventListener(context, name, cel);

    {
        boost::lock_guard<boost::mutex> lock(listenersMutex);
        std::map< AgString, std::map<AgString, ContextEventListenerSetPtr> >::iterator itListeners = listeners.find(context);
        if (itListeners != listeners.end())
        {
            listeners.erase(itListeners);
        }
    }
}

ContextManager* AbstractClientController::getContextManager()
{
    return contextManager;
}

void AbstractClientController::shutdown()
{
    listeners.clear();
}

