/*
	ELSEventManager.js
	
	The ELSEventManager class provides a common add-on for custom classes that
	wish to provide event management. This replicates the event handling from
	DOM/HTML elements for Javascript objects. Please note that the "events" are
	triggered manually in the client object and are not true DOM events (such as
	onLoad and onClick). This class is mostly designed as a tool to make
	inter-object communication easier for the many classes I have created.
*/

function ELSEventManager()
{
	// instance identifiers
	var instanceSelf = this;
	var instanceClass = instanceSelf.constructor.prototype;
	var instanceIdentifier;
	
	// public instance accessors
	instanceSelf.addEventListener = addEventListener;
	instanceSelf.removeEventListener = removeEventListener;
	instanceSelf.callEventListeners = callEventListeners;
	
	// instance members
	var eventListeners;
	
	function addEventListener(eventName, eventListener)
	{
		// make sure that the event listener array is setup
		if (eventListeners == null)
		{
			eventListeners = new Array();
		}
		
		// set up the event
		eventName = eventName.toLowerCase();
		
		// determine if the event type matches one of the supported events
		if (eventName != "")
		{
			// make sure the event array is set up
			if (eventListeners[eventName] == null)
			{
				eventListeners[eventName] = new Array();
			}
			
			// add a listener to the appropriate list
			// make sure this listener isn't already setup
			var eventListenerIndex = -1;
			for (var listenerIndex = 0; listenerIndex < eventListeners[eventName].length; listenerIndex++)
			{
				if (eventListeners[eventName][listenerIndex] == eventListener)
				{
					eventListenerIndex = listenerIndex;
					listenerIndex = eventListeners[eventName].length;
				}
			}
			if (eventListenerIndex == -1)
			{
				// add the event listener
				eventListeners[eventName][eventListeners[eventName].length] = eventListener;
			}
		}
	}
	function removeEventListener(eventName, eventListener)
	{
		// make sure that the event listener array is setup
		if (eventListeners != null)
		{
			// set up the event name
			eventName = eventName.toLowerCase();
			
			// determine if the event type matches one of the supported events
			if (eventName != "")
			{
				// make sure the event array is set up
				if (eventListeners[eventName] != null)
				{
					// remove all occurences of the event listener
					// there should only be one occurrence, but we'll check the
					//	whole array, just in case
					for (listenerIndex = eventListeners[eventName].length - 1; listenerIndex >= 0; listenerIndex--)
					{
						if (eventListeners[eventName][listenerIndex] == eventListener)
						{
							// remove this item from the list after we finish
							eventListeners[eventName].splice(listenerIndex, 1);
						}
					}
				}
			}
		}
	}
	function callEventListeners(eventName)
	{
		// make sure that the event listener array is setup
		if (eventListeners != null)
		{
			// set up the event name
			eventName = eventName.toLowerCase();
			
			// make sure the event array is set up
			if (eventListeners[eventName] != null)
			{
				// we'll work through the events like a stack (LIFO) so that we
				//	can remove any listeners that cause exceptions in real time
				for (listenerIndex = 0; listenerIndex < eventListeners[eventName].length; listenerIndex++)
				{
					// call this event listener
					try
					{
						eventListener = eventListeners[eventName][listenerIndex];
						eventListener();
					}
					catch (exception)
					{
						// remove this item from the list
						eventListeners[eventName].splice(listenerIndex, 1);
						
						// because we removed this item, the indicies will
						//	shift, so we'll need to decrement the index
						listenerIndex--;
					}
				}
			}
		}
	}
}