#include "context/DefaultContextEventListener.h"
#include "expression/Evaluator.h"
#include "expression/ReferenceResolver.h"
#include "event/EventHandlingException.h"
#include  "AggreGateException.h"

DefaultContextEventListener::DefaultContextEventListener()
{
    this->listenerCode = 0;
    this->acceptEventsWithoutListenerCode = false;
}

DefaultContextEventListener::DefaultContextEventListener(CallerControllerPtr callerController)
{
    this->listenerCode = 0;
    this->acceptEventsWithoutListenerCode = false;
    this->callerController = callerController;
}

DefaultContextEventListener::DefaultContextEventListener(CallerControllerPtr callerController, int  listenerCode)
{
    this->listenerCode = listenerCode;
    this->acceptEventsWithoutListenerCode = false;
    this->callerController = callerController;
}

DefaultContextEventListener::DefaultContextEventListener(CallerControllerPtr callerController, int  listenerCode, ExpressionPtr filter)
{
    this->listenerCode = listenerCode;
    this->acceptEventsWithoutListenerCode = false;
    this->callerController = callerController;
    this->filter = filter;
}

DefaultContextEventListener::DefaultContextEventListener(int  listenerCode)
{
    this->listenerCode = listenerCode;
    this->acceptEventsWithoutListenerCode = false;
}

bool DefaultContextEventListener::shouldHandle(EventPtr ev)
{
    if (filter != NULL)
    {
        if (evaluator == NULL) {
            evaluator = EvaluatorPtr(new Evaluator(NULL, NULL, ev->getData(), callerController));
        }else {
            evaluator->getDefaultResolver()->setDefaultTable(ev->getData());
        }

        try {
            if (!evaluator->evaluateToBoolean(filter)) {
                return false;
            }
        }catch (AggreGateException ex) {
            throw EventHandlingException(ex.getMessage(), ex.getDetails());
        }
    }

    if (listenerCode) {
        if (ev->getListener() && (listenerCode != ev->getListener())) {
            return false;
        }

        if (!ev->getListener() && !acceptEventsWithoutListenerCode) {
            return false;
        }
    }

    return true;
}

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

int DefaultContextEventListener::getListenerCode()
{
    return listenerCode;
}

void DefaultContextEventListener::setCallerController(CallerControllerPtr callerController)
{
    this->callerController = callerController;
    if(evaluator != 0) {
        evaluator->getDefaultResolver()->setCallerController(callerController);
    }
}

void DefaultContextEventListener::setAcceptEventsWithoutListenerCode(bool acceptEventsWithoutListenerCode)
{
    this->acceptEventsWithoutListenerCode = acceptEventsWithoutListenerCode;
}

void DefaultContextEventListener::setFilter(ExpressionPtr filter)
{
    this->filter = filter;
}

ExpressionPtr DefaultContextEventListener::getFilter()
{
    return filter;
}

AgString DefaultContextEventListener::toString()
{
    return "DefaultContextEventListener";
}

bool DefaultContextEventListener::equals(AgObject *obj)
{
    if (obj == NULL)
        return false;

    if (obj == this)
        return true;

    /*DefaultContextEventListener *other = dynamic_cast<DefaultContextEventListener *>(obj);
    if (!other)
    {
        return false;
    }*/

    return false;//value == other->value;
}
