#ifndef EVENTSMANAGER_H
#define EVENTSMANAGER_H

// #include "Module.h"

#include <boost/shared_ptr.hpp>

#include <string>
#include <map>
#include <vector>
#include <queue>

#include "EventBase.h"
#include "Module.h"

namespace Engine {

/** \brief Keeps track of all the Modules that registered for a given event type
 *
 */
class EventManager : public Module {
	public:
		virtual ~EventManager() {};

		/** \brief Registers a listener to a given event type */
		bool RegisterListener (Module *listener_module, const int event_type);
		/** \brief Calls all event listeners to handle the events */
		void Process ();
		/** \brief Queues the until Process() gets called */
		bool QueueEvent (const EventBasePtr &event);
		/** \brief Calls the listener handlers immediately */
		bool TriggerEvent (const EventBasePtr &event);

		/** \brief Returns true if there is a listener for a given event type */
		bool HasEventTypeListener (const int event_type) {
			return mEventTypeListeners.find(event_type) != mEventTypeListeners.end();
		}
		/** \brief Returns the number of listeners for a given event type */
		unsigned int GetEventTypeListenerCount (const int event_type) {
			if (!HasEventTypeListener (event_type))
				return 0;

			return (mEventTypeListeners.find(event_type))->second.size();
		}
		unsigned int GetQueuedEventCount () {
			return mQueuedEvents.size();
		}

	protected:
		virtual int OnInit (int argc, char* argv[]);
		virtual void OnDestroy();

	private:
		/** \brief Contains for each event type the list of listeners */
		std::map <int, std::vector<Module*> > mEventTypeListeners;
		std::queue <EventBasePtr> mQueuedEvents;
};

}

#endif /* EVENTSMANAGER_H */
