﻿/// Append a eventhandler to the window.onload event
function AppendToWindowOnload(onloadDelegate)
{
	if(window.onload == undefined)
	{
		window.onload = onloadDelegate;
	}
	else
	{
		var tmp = window.onload;
		window.onload = function() { 
			tmp();
			onloadDelegate();
		}
	}
}


/// Given a (default) event argument, return the source of the event
function GetSource(e)
{
	if (!e) var e = window.event;
	if (e.target) return e.target;
	else if (e.srcElement) return e.srcElement;
	if (targ.nodeType == 3) return targ.parentNode; // defeat Safari bug
	return null;		
}



/*****************************************************************************/
/*
 * An ApplicationEvent contains a set of listeners which can be notified
 * through a callback method
 */
function ApplicationEvent()
{
	this.listeners = new Array();
	this.activeNotificationQueue = null;
}

ApplicationEvent.prototype.AddListener = function(listener)
{
	this.listeners.push(listener);
}

ApplicationEvent.prototype.RemoveListener = function(listener)
{
	for(var i=this.listeners.length -1; i>=0; i--)
	{
		if(this.listeners[i] != listener) continue;
		
		this.listeners.splice(i, 1);
	}
}

ApplicationEvent.prototype.NotifyListeners = function() // any parameters will passthrough to the delegates
{
	if(this.activeNotificationQueue != null)
	{
		//
		// this.NotifyListeners is called recursively if the activeNotifaticationQueue != null
		// make sure the events are still chronological; append to the queue and exit
		//
		for(var i=0; i<this.listeners.length; i++)
		{
			this.activeNotificationQueue.push({ func : this.listeners[i], args : arguments });
		}
		return;
	}
	
	
	this.activeNotificationQueue = new Array();
	for(var i=0; i<this.listeners.length; i++)
	{
		this.activeNotificationQueue.push({ func : this.listeners[i], args : arguments });
	}
	for(var i=0; i<this.activeNotificationQueue.length; i++)
	{
		//
		// if you were to do this.listeners[i](arguments) then
		// your delegate would receive not a variable amount of arguments
		// but a single argument containing an array. Using .apply()
		// works around this. The first parameter to apply is the object
		// instance that the delegate should attach to. We don't use that here.
		//
		//this.activeNotificationQueue[i].apply(null, arguments);
		var funcObject = this.activeNotificationQueue[i];
		funcObject.func.apply(null, funcObject.args);
	}
	this.activeNotificationQueue = null;
	
}
