//////////////////////////////////////////////
// EventHandler Object VERSION_0.8
//////////////////////////////////////////////
//
// The new mSpaceApplication object is the main
// controller for the mSpace application
//
// Ali Russell 10.2006
//
//////////////////////////////////////////////

var EventHandlerInterface = Class.create();
EventHandlerInterface.prototype = {
//
// Member Variables
eventControlObject: null,

//
// Constructor
initialize: function()
	{
		this.eventControlObject = new Object();
	},
	
//
// Subscribe event, to allow a component to subscribe to a
// named event.  The sourceControl object needs to implement the 
// Notify(string eventName, Arraly eventParams) method
Subscribe: function(eventName, sourceControl)
	{
		//Only add the event if the sourceControl implements
		//Notify method
		if ((this.eventControlObject) && (sourceControl.Notify))
		{
			if (!this.eventControlObject[eventName])
			{
				this.eventControlObject[eventName] = new Array();
				
			}
			this.eventControlObject[eventName].push(sourceControl);
		}
	},
	
	
//
// UnSubscribe event, to allow a component to unsubscribe from
// a subscribed event
UnSubscribe: function(eventName, sourceControl)
	{
		//Check to see if the event exists
		if ((this.eventControlObject) && (this.eventControlObject[eventName]))
		{
			var newListeners = new Array();
			var listeners = this.eventControlObject[eventName];
			for (var i=0;i<listeners.length;i++)
			{
				//Call the listener objects Notify method
				var listenerControl = listeners[i];
				if (listenerControl!=sourceControl)
				{
					newListeners.push(listenerControl);
				}
			}
			this.eventControlObject[eventName] = newListeners;
		}
	},	

//
// Fire event, called by controls wishing to fire
// and event off to and subscribed listeners
FireEvent: function(eventName, eventParams)
	{
		//Check if any controls are listening to event
		if ((this.eventControlObject) && (this.eventControlObject[eventName]))
		{
			//loop through all the listeners
			var listeners = this.eventControlObject[eventName];
			for (var i=0;i<listeners.length;i++)
			{
				//Call the listener objects Notify method
				var listenerControl = listeners[i];
				listenerControl.Notify(eventName, eventParams);
			}
		}
		
		return false;
	}
	
	
};







/////////////////////////////////////////////////////////
////////////// STATIC FUNCTIONS /////////////////////////
/////////////////////////////////////////////////////////


function RegisterEvent(element, name, object, observer, cancelBubble, useCapture, parameter)
{
	useCapture = useCapture || false;
	cancelBubble = cancelBubble || false;
	
	if (element.addEventListener)
	{
		element.addEventListener(name,
		function(e)
		{
			e.X = e.pageX;
			e.Y = e.pageY;			
			e.AbsX = e.X + findPosX(element);
			e.AbsY = e.Y + findPosY(element);
			e.RelX = e.X - findPosX(element);
			e.RelY = e.Y - findPosY(element);			
			if (cancelBubble)
				stopEventBubble(e);
				
			return object[observer](e, element, name, parameter);
		}
		, useCapture);
	}
	else if (element.attachEvent)
	{
		element.attachEvent('on' + name,
		function(e)
		{
			if(window.event)
				e = window.event;
			
			e.keyCode = (window.event) ? e.keyCode : e.which;
				
			e.X = e.clientX;
			e.Y = e.clientY;
			e.AbsX = e.X + findPosX(element);
			e.AbsY = e.Y + findPosY(element);		
			e.RelX = e.X - findPosX(element);
			e.RelY = e.Y - findPosY(element);		
			if (cancelBubble)
				stopEventBubble(e);			
						
			return object[observer](e, element, name, parameter);
		});
	}	
}

function RegisterClosureEvent(element, name, observer, cancelBubble, useCapture, parameter)
{
	useCapture = useCapture || false;
	cancelBubble = cancelBubble || false;
	
	if (element.addEventListener)
	{
		element.addEventListener(name,
		function(e)
		{
			e.X = e.pageX;
			e.Y = e.pageY;			
			e.AbsX = e.X + findPosX(element);
			e.AbsY = e.Y + findPosY(element);
			e.RelX = e.X - findPosX(element);
			e.RelY = e.Y - findPosY(element);			
			if (cancelBubble)
				stopEventBubble(e);
				
			return observer(e, element, name, parameter);
		}
		, useCapture);
	}
	else if (element.attachEvent)
	{
		element.attachEvent('on' + name,
		function(e)
		{
			if(window.event)
				e = window.event;
			
			e.keyCode = (window.event) ? e.keyCode : e.which;
				
			e.X = e.clientX;
			e.Y = e.clientY;
			e.AbsX = e.X + findPosX(element);
			e.AbsY = e.Y + findPosY(element);		
			e.RelX = e.X - findPosX(element);
			e.RelY = e.Y - findPosY(element);		
			if (cancelBubble)
				stopEventBubble(e);			
						
			return observer(e, element, name, parameter);
		});
	}	
}

function propagateEvent(e, element)
{
	var evObj = document.createEvent('MouseEvents');
	evObj.initEvent(e.type, e.bubbles, e.cancelable, window,  e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
	element.dispatchEvent(evObj);
}



function stopEventBubble(e)
{
	if (browserDetails[0]=="msie")
	{
		e.cancelBubble = true;
		e.returnValue  = false;
	}
	else
	{
		e.stopPropagation();
		e.preventDefault();
	}	
}
