/*
 *	This script defines two objects
 *	CrossBrowserCommunicationNode - Handles notification events for current instance
 *	CrossBrowserCommunicationNotifier - Sends notifications to a specific browser instance
 *
 *	It also sets up default objects
 *	1 node for the current browser instance
 *	1 notify for the parent instance if it loaded this script
 *
 *	See notes at the end about expandability
 */

/*
 *	CrossBrowserCommunicationNode is an object responsible for communication to a browser instance
 *	Only the browser instance that initializes this object should call into its methods
 */
function CrossBrowserCommunicationNode()
{
	this.listeners=new Array();
	this.CONTINUE=0;
	this.BREAK=1;
}
/*
 *	addListener registers a function for notifications
 */
CrossBrowserCommunicationNode.prototype.addListener=function(tag,func)
{
	var tagListeners=this.listeners[tag];
	if (tagListeners==null)
	{
		tagListeners=new Array();
		this.listeners[tag]=tagListeners;
	}
	tagListeners[tagListeners.length]=func;
}
/*
 *	removeListener deregisters a function for notifications
 */
CrossBrowserCommunicationNode.prototype.removeListener=function(tag,func)
{
	var tagListeners=this.listeners[tag];
	if (tagListeners)
	{
		for (var i=0;i < tagListeners.length; i++)
		{
			if (tagListeners[i]==func)
			{
				tagListeners.splice(i,i);
			return(true);
			}
		}
	}
	return(false);
}
/*
 *	notify is called whenever an event has just occurred that the associated browser instance needs to be aware of.
 *	This should not ever be called directly
 */
CrossBrowserCommunicationNode.prototype.notify=function(tag,notifier,args)
{
	var tagListeners=this.listeners[tag];
	if (tagListeners!=null)
	{
		for (var i=0;i < tagListeners.length; i++)
		{
			var sb=new Array();
			sb[sb.length]="tagListeners[i](notifier";
			for (var j=0; j < args.length; j++)
			{
				sb[sb.length]=",args["+j+"]";
			}
			sb[sb.length]=")";
			var val=eval(sb.join(""));
			if (val==this.BREAK)
			{
				return(val);
			}
		}
		//Propagate it up the parents
		if (parentCrossBrowserCommunicationNotifier)
		{
			var val=parentCrossBrowserCommunicationNotifier.notifyWithOriginating(tag,notifier,args);
			if (val==this.BREAK)
			{
				return(val);
			}
		}
	}
}

/*
 *	CrossBrowserCommunicationNotifier object is called by other browser instances so that notification can occur
 */
function CrossBrowserCommunicationNotifier(node)
{
	this.node=node;
}
/*
 *	notify sends an event to the target browser instance
 */
CrossBrowserCommunicationNotifier.prototype.notify=function(tag)
{
	var args=new Array();
	for (var i=1; i < arguments.length; i++)
	{
		args[args.length]=arguments[i];
	}
	return(this.notifyWithOriginating(tag,crossBrowserCommunicationNotifier,args));
}
/*
 *	this method should not be called directly
 */
CrossBrowserCommunicationNotifier.prototype.notifyWithOriginating=function(tag,notifier,args)
{
	if (this.node && typeof this.node!="undefined")
	{
		return(this.node.notify(tag,notifier,args));
	}
}

/*
 *	Setup the current browser instance whenever this script is loaded
 *	If there is a parent, create a notifier for it
 */
if (window.parent!=null || window.opener!=null)
{
	if (window.parent!=null && window!=window.parent)
	{
		if (window.parent.crossBrowserCommunicationNode)
		{
			var parentCrossBrowserCommunicationNotifier=new CrossBrowserCommunicationNotifier(window.parent.crossBrowserCommunicationNode);
		}
	}
	else if (window.opener)
	{
		if (window.opener.crossBrowserCommunicationNode)
		{
			var parentCrossBrowserCommunicationNotifier=new CrossBrowserCommunicationNotifier(window.opener.crossBrowserCommunicationNode);
		}
	}
	else if (window.dialogArguments)
	{
		if (window.dialogArguments.crossBrowserCommunicationNode)
		{
			var parentCrossBrowserCommunicationNotifier=new CrossBrowserCommunicationNotifier(window.dialogArguments.crossBrowserCommunicationNode);
		}
	}
}

window.crossBrowserCommunicationNode=new CrossBrowserCommunicationNode();
crossBrowserCommunicationNotifier=new CrossBrowserCommunicationNotifier(crossBrowserCommunicationNode);

/*
 *	NOTE: What should really happen is that the should be a CrossBrowserCommunicationManager.
 *	Of which there should be only one instance of it regardless of the number of browsers open.
 *	If the browser that contains the manager is closed the other browser should choose another
 *	to contain the manager
 *	As it is for the time being our communication will be limited to parent child communication.
 *	
 *	There should be an Communication Node instance per browser *this is what should talk to the CommunicationManager and not have any guts*
 */

