var DEBUG = false;

function RouteEntry( framename )
{
  this.$framename = framename;
}			

/*
The broadcasting-function is made so that all linking pages 
can broadcast a message to all related windows, either parents
or it's own frames, or other pages indirectly available from
the current page. 

All pages in a chain must link to a file containing this function
in order for the message to arrive to all destinations.
*/
var Broadcasting = false;

function Broadcast( message, value, fromparent )
{
  //If the page is not already broadcasting, meaning that it is in the middle of
  //a broadcast, we broadcast the message related pages.
  if( Broadcasting == false )
  {    
    Broadcasting = true;
    
    //Traverse all frames and broadcast the message to them
    if( window.frames && window.frames.length > 0 )
	  {
			 //If the frame has imported the MessageFramework, meaning it has a Broadcast-function
		  //we send the message to the frame, responsible for routing it to it's frames.		  
		  for( var j=0; j<window.frames.length; j++ )
		  {		
				try
				{		  				
					if( window.frames[j].UpdateObserver )
					{						
						window.frames[j].UpdateObserver( message, value );
					}					
			  
					if( window.frames[j].Broadcast )
					{			  
						//alert("Broadcasting to frame: " + j);
						window.frames[j].Broadcast( message, value, true );
					}			  
			  }
			  catch(exception)
				{
					if( DEBUG == true )
					{
						alert("Exception caught during broadcast of message " + message);
					}        
				}
		  }
    }
    
    try
    {
			//If the message did not come from the parent, we send it to the parent frame.
			if( !fromparent || fromparent == false )
			{
				if( parent && parent.Broadcast )
				{
					//alert("Sending message to parent.");
					parent.Broadcast( message, value );  
				}
			}  
	  }
	  catch(e)
	  {
			//No action
	  }
	  	  
	  var hasUpdateObserver = true;
	  try
	  {
			if( UpdateObserver )
				hasUpdateObserver = true;
		}
		catch(e)
		{
			//Exception is thrown if method is not available.
			hasUpdateObserver = false;
		}
		
		//Considering that we run the updateobserver function from the 
		//parent frame, any root frames will not have it's updateobserver function
		//called. This is what we do here, if the hasParent value is false and the
		//hasUpdateObserver value is true.
		try
		{
			if( hasParent == false && hasUpdateObserver == true )
			{	
				UpdateObserver( message, value );
			}
	  }
	  catch(e)
	  {
			//Do nothing, this indicates the the current document does not contain var hasParent,
			//or that the UpdateObserver threw an exception.
	  }
	  
	  //The broadcasting is finished, we make the page available for other broadcasts.
	  Broadcasting = false;
	}
}

function SendRequest( name, message, fromparent )
{
  if( DEBUG == true )
  {
    alert("SendRequest(" + name + "," + message + "," + fromparent + ")" );
  }
  
  if( name == '#root' && (!hasParent || hasParent == false) )
	{
		try
		{
			if( Request )
			{
				return Request(message);
			}
			else
			{
				alert("SendRequest to root failed, root page has no Request-function");
				return null;
			}
		}
		catch(e){}
	} 
  
  var returnvalue = "";
	  
  var frame = null;
  
  try
  {
		if( window.frames )
			frame = window.frames[name];
	}
	catch(e){}
  
  //First, if this page contains a frame with 
	//the destination frame, we call the frames DoAction-method
	//provided that this exists. If it doesn't it's an error.
	if( frame && frame != null && !((typeof frame) == "BarProp") )
	{	
	
		try
		{
			//alert("document has frame with name " + name);
			if( frame.Request )
			{		  
				try
				{
					return frame.Request(message);			
				}
				catch(exception)
				{
					if( DEBUG == true )
					{
						alert("Failed to retrieve response from " + name);
					}
					return "";
				}
			}
			else
			{
				//We can end up here using firefox 1.0.1, even though no frames are available with that
				//name, we must let the function continues..
				//alert("Error: The frame with name/id " + name + " does not contain function DoAction.");			
			}
		}
		catch(e){}
	}
  
  //otherwise we send the message further on
	if( routeTable && routeTable != null && routeTable.length > 0 )
	{	  
	  //alert(routeTable);
	  for( var i=0; i<routeTable.length; i++ )
		{
		  
		  //This page contains a frame with id/name eqal to name according to the XML
			if( routeTable[i].$framename == name )
			{			  
			  if( window.frames && window.frames.length > 0 )
			  {
			    //The page claims to route to the destination, we traverse all the frames
			    //and send routemessage.
			    for( var j=0; j<window.frames.length; j++ )
			    {
						try
						{
							if( window.frames[j].SendRequest )
							{			        
								returnvalue = window.frames[j].SendRequest( name, message, true );
				        
								if( returnvalue != "" )
								{
									return returnvalue;
								}
							}
						}
						catch(e){}
			    }
			  }			  
  			
  			//alert("Burde vi endt opp her?");
			  //We do not call parent, because this page was routing to the destination.
			  return null;
			}
		} //end for(i)
	} //end if
  
  //The page does not contain a frame with id/name equal to the
	//parameter name, and does not directly route to the destination.
	//The parent might still do, so we call the parents SendRequest
	if( hasParent && hasParent == true && parent.SendRequest && !(fromparent==true) )
	{
		try
		{
			//alert("routing to parent");
			return parent.SendRequest( name, message );			    
		}
		catch(e){}
	}
  
  return "";
}

function SendMessage( name, message, value, fromparent )
{   
	if( name == '#root' && (!hasParent || hasParent == false) )
	{
		try
		{
			if( DoAction )
			{
				DoAction(message, value);
			}
			else
			{
				alert("SendMessage to root failed, root page has no DoAction-function");
				return null;
			}
		}
		catch(e)
		{}
	} 

	var frame = null;
	
	if(window.frames)
		frame = window.frames[name];
  
  //First, if this page contains a frame with 
	//the destination frame, we call the frames DoAction-method
	//provided that this exists. If it doesn't it's an error.
	if( frame && frame != null && !((typeof frame) == "BarProp") )
	{	
		try
		{
			//alert("document has frame with name " + name);
			if( frame.DoAction )
			{		  
				try
				{
					frame.DoAction(message, value);
					return null;
				}
				catch(exception)
				{
					if( DEBUG == true )
					{
						alert("MessageFramework->SendMessage: exception thrown when executing method DoAction on '" + name + "'." + exception);
					}
				}
				return null;
			}
			else
			{
				//We can end up here using firefox 1.0.1, even though no frames are available with that
				//name, we must let the function continues..
				//alert("MessageFramework->SendMessage - Error:\nThe frame with name/id '" + name + "' does not contain function DoAction.");
			}
		}
		catch(e)
		{
			if( DEBUG == true )
			{
			  alert("MessageFramework->SendMessage - Exception:" + e);
			}
		}
	}
  
  //otherwise we send the message further on
	if( routeTable && routeTable != null && routeTable.length > 0 )
	{
	  for( var i=0; i<routeTable.length; i++ )
		{
		  //alert(routeTable);
		  //This page contains a frame with id/name eqal to name according to the XML
			if( routeTable[i].$framename == name )
			{			  
			  if( window.frames && window.frames.length > 0 )
			  {
			    //The page claims to route to the destination, we traverse all the frames
			    //and send routemessage.
			    for( var j=0; j<window.frames.length; j++ )
			    {
						try
						{
							if( window.frames[j].SendMessage )
							{			        
								window.frames[j].SendMessage( name, message, value, true );
							}
						}
						catch(e){}
			    }
			  }			  
  			
			  //We do not call parent, because this page was routing to the destination.
			  return null;
			}
		} //end for(i)
  	
  	
	} //end if
  
  //The page does not contain a frame with id/name equal to the
	//parameter name, and does not directly route to the destination.
	//The parent might still do, so we call the parents SendMessage
	try
	{
		if( (hasParent || hasParent == true) && parent.SendMessage && !(fromparent==true) )
		{
			parent.SendMessage( name, message, value );			    
		}
	}
	catch(e){}
  
	//If we get this far, this page does not directly route to
	//or have a parent that routes to the destination frame. 
	//We quietly end the function.
	return null;
}
