/*
 * Confidential and Proprietary for Oracle Corporation
 *
 * This computer program contains valuable, confidential, and
 * proprietary information.  Disclosure, use, or reproduction
 * without the written authorization of Oracle is prohibited.
 * This unpublished work by Oracle is protected by the laws
 * of the United States and other countries.  If publication
 * of this computer program should occur, the following notice
 * shall apply:
 *
 * Copyright (c) 2003-2006 Stellent, Inc.
 * All rights reserved.
 * Copyright (c) 2007-2010 Oracle Corp.
 * All rights reserved.
 *
 * $Id: crossBrowser.js 87769 2010-08-23 15:48:19Z kjorisse $
 */

/*
 *	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));
	}
}

/*
 *	Method hasValidWindowOpener() is needed because IE has strange behavior when
 *      the child window has or becomes a different domain in the "opener" window. In such
 *      a case, IE will have an object instance for 'window.opener' and for
 *	'window.opener.location' but any attempt to access other properties will result
 *	in an access error. [E.g. even though window.opener.location exists,
 *      attempting to access window.opener.location.href or window.opener.crossBrowserCommunicationNode
 *      will result in an undetectable access error.] Firefox has more sane behavior and will have
 *      window.opener == null in the same situation.
 */
/* REMOVE hasValidWindowOpener() TO FIX  Bug 9883071 - crossBrowser.js is needed due to RM dependencies

function hasValidWindowOpener()
{
	var hasOpener = false;
	if (window.opener)
	{
		var loc = "";
		try 
		{
			loc = window.opener.location;
		} catch (e) {}
		hasOpener = loc.length > 0;
	}
	return hasOpener;
}
*/

/*
 *	Setup the current browser instance whenever this script is loaded
 *	If there is a parent, create a notifier for it
 */

/* REMOVE below code because of references to hasValidWindowOpener() TO FIX  Bug 9883071 - crossBrowser.js is needed due to RM dependencies

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 ( hasValidWindowOpener() )
	{
		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*
 */


