/* (c) 1999-2000 Tino Schwarze, see COPYING for details */
/**@pkg events.cEventDispatcher*/
/**
 * the event dispatcher - the brain behind the event system
 *
 * #include "cEventDispatcher.hh"
 *
 *@pkgdoc events.cEventDispatcher
 */

#ifndef cEventDispatcher_hh
#define cEventDispatcher_hh

// aquire STL's multimap
#include <map>

#include "cEvent.hh"
#include "cEventConsumer.hh"

/**
 * The event dispatching class.
 *
 * This is the core of the event system.
 *
 * There should usually be no need to derive from this class.
 *
 * Take care to destroy all cEventProducer's before destroying this
 * class! They've got no way to know whether the dispatcher they want
 * to send their events to has been destroyed.
 *
 * @see cEventProducer
 */
class cEventDispatcher
{
//LIFETIME
public:
	/**
	 * default constructor
	 	*/
	cEventDispatcher ();

	/**
	 * destructor
	 	*/
	virtual ~cEventDispatcher ();

	/**
	 * register an event consumer for receiving of an event
	 	* @param event a "template" of an cEvent to receive
		* @param consumer the cEventConsumer to call upon receiption of the
		* event
		*/
	virtual void SubscribeToEvent (
		const cEvent &event,
		cEventConsumer *consumer);

	/**
	 * unregister an event consumer for receiving of an event
	 	* @param event a "template" of an cEvent
		* @param consumer the cEventConsumer to deregister from receiption
		* of events of type event.
		*/
	virtual void UnsubscribeFromEvent (
		const cEvent &event,
		cEventConsumer *consumer);

	/**
	 * unregister a whole consumer
	 	*
		* Delete all subscriptions of this consumer (e.g. because it has
		* been destroyed).
		*
	 	* @param consumer cEventConsumer to unregister
	 	*/
	virtual void UnregisterConsumer (
		const cEventConsumer *consumer);

	/**
	 * send an event
	 	*
		* The event is sent to all subscribers of this event type until
		* one accepts it.
		*
	 	* @param event cEvent (or descendant) to send
	 	* @param global is this a global event? - Send it until someone
		* accepts it or send it to everyone who's subscribed?
		* (optional, default: non-global)
	 	*/
	virtual void SendEvent (
		const cEvent &event,
		bool global = false);

	/**
	 * for debugging purposes only: display list of registered events
	 	*
		* sends the list of registered events to cout
		*/
	void DisplayRegistered ();

protected:
	typedef multimap<const cStorableEvent, cEventConsumer *> tRegisteredEvents;
	tRegisteredEvents mRegisteredEvents;
};


#endif	//ifndef cEventDispatcher_hh

