#include "EventBase.h"
#include "EventManager.h"
#include "Logging.h"

namespace Engine {

EventManager* EventManagerInstance = NULL;

int EventManager::OnInit (int argc, char* argv[]) {
	EventManagerInstance = this;

	return 0;
}

void EventManager::OnDestroy() {
	EventManagerInstance = NULL;
}

bool EventManager::RegisterListener (Module *listener_module, const int event_type) {
	LogDebug ("Registering Event listener %x for event type %d", listener_module, event_type);

	mEventTypeListeners[event_type].push_back(listener_module);
	return true;
}

void EventManager::Process () {
	while (mQueuedEvents.size() > 0) {
		TriggerEvent (mQueuedEvents.front());
		mQueuedEvents.pop();
	}
}

bool EventManager::QueueEvent (const EventBasePtr &event) {
	if (!HasEventTypeListener(event->mEventType))
		return false;

	mQueuedEvents.push (event);

	return true;
}

bool EventManager::TriggerEvent (const EventBasePtr &event) {
	if (!HasEventTypeListener (event->mEventType))
		return false;

	std::vector<Module*>::iterator listener_iter = mEventTypeListeners[event->mEventType].begin();
	for ( ; listener_iter != mEventTypeListeners[event->mEventType].end(); listener_iter++) {
		if ((*listener_iter)->SendEvent (event))
			return true;
	}

	return false;
}

/*
 * Global Functions
 */
/** \brief Registers a listener to a given event type */
bool RegisterListener (Module *listener_module, const int event_type) {
	if (!EventManagerInstance) {
		LogError ("Could not register Module: EventManager not initialized!");
		return false;
	}

	return EventManagerInstance->RegisterListener (listener_module, event_type);
}

/** \brief Calls all event listeners to handle the events */
bool QueueEvent (const EventBasePtr &event) {
	if (!EventManagerInstance) {
		LogError ("Could not queue event: EventManager not initialized!");
		return false;
	}

	return EventManagerInstance->QueueEvent (event);
}

/** \brief Calls the listener handlers immediately */
bool TriggerEvent (const EventBasePtr &event) {
	if (!EventManagerInstance) {
		LogError ("Could not trigger event: EventManager not initialized!");
		return false;
	}

	return EventManagerInstance->TriggerEvent (event);
}

};

