/** 
 * @fileoverview NavigationSelectBox Widget - turn a dropdown select box into a javascript navigation menu, where the value of each option is the URI to navigate to when the option is selected.
 *  
 * @author James Palmer james@phoenixlondon.co.uk
 * @version 0.1 
 */

// ***** Require External Dependencies *****
requireNamespace("Phoenix.Widgets", "Phoenix.Widgets.NavigationSelectBox");

/**
 * Construct the Phoenix.Widgets.NavigationSelectBox object.
 * @class Defines the Javascript Navigation Select Box object
 * @constructor
 * @requires Phoenix.Widgets
 */
 

Phoenix.Widgets.NavigationSelectBox = function(container, insertionmethod, selectbox)
{
	this.nsIdentifier = this.nsIdentifier || "Phoenix.Widgets.NavigationSelectBox";	// Protect in case of subclassed controls
	
	// ***** Require External Dependencies *****
	requireNamespace("Phoenix.Widgets", this.nsIdentifier);
	requireNamespace("Phoenix.DOM", this.nsIdentifier);
	
	// ***** Sanity-Check Passed Parameters *****
	
	if(!container) throw new Phoenix.Exception("Phoenix.Widgets.NavigationSelectBox.Constructor: First parameter must be a valid HTML element reference.");	// Can't survive without an element to bed ourselves down in
	insertionmethod = (insertionmethod == null || insertionmethod > 3 || insertionmethod < 0) ? 3: insertionmethod;			// If insertionmethod not specified or invalid, assume "unrender fallback elements and insert ourselves *before* them in the div"

	// ***** State Variables *****
	
	// Set up identifying properties of this widget
	this.globalWidgetIndex = Phoenix.Widgets.registerThisWidget(this.nsIdentifier, this);	// Grab a reference to the index of this particular instance of the control in the Phoenix.Widgets._InstantiatedControls array (in case we ever need to refer to ourself in the global scope)
	
	this.renderMethod = insertionmethod;	// How are we to render ourselves?  See Render() for explanation of values.
	this.rendered = false;					// Has this control been rendered yet?

	// ** "Child HTML Element" references **
	// Root element of this control:
	this.rootElement = container;						// Reference to the root element that this widget inhabits
	this.rootElement.owningControl = this;
	this.selectbox = selectbox;
	this.selectbox.owningControl = this;

	// ***** Do Initial "Pre-Rendering" Setup *****

	// Mark out this element's root container as a mapwidget (for styling purposes)
	Phoenix.DOM.addCSSClass(this.rootElement, "navigationselectboxwidget");

	// If appropriate, hide or unrender any DHTML fallback elements in the div
	// We do this here so that it'll be done while the DOM is still loading, rather than having them flicker by waiting for the entire page to load (exposing the fallback elements the whole time) and then blanking them out after a short delay
	if(this.renderMethod == 2 || this.renderMethod == 3)	// If hide/undisplay all fallback elements
	{
		if(container.hasChildNodes())
		{
			var removemethod = (this.renderMethod == 2) ? "hidden": "unrendered";	// Remove (display:none) the control or just hide (visibility:hidden) it?
	
			// Hide all "fallback" HTML elements (anything inside the div this control has been passed as its container)
			//var children = container.getElementsByTagName("*");
			var children = Phoenix.DOM.getElementsByClassName("dhtmlfallback", container);
			for(var i=0; i<children.length; i++)	// remove/hide old HTML elements
				Phoenix.DOM.addCSSClass(children[i], removemethod);
		}
	}
	
	
	// ***** Internal Functions *****
	
	/**
	 * Render this widget
	 * @private
	 */
	this._render = function()
	{
		// All we need to do is hide the DHTML fallback submit button, so we don't actually need to render the widget
		this.rendered = true;
	};
	
	// Internal functions:
	// None.
	
	// Attach event handlers
	
	this.selectbox.onchange = function (event)
	{
		var selectname = this.owningControl.selectbox.name;
		var selectedvalue = this.options[this.selectedIndex].value;
		var location = new String(window.location);
		var parentformaction = this.owningControl.rootElement.action;
		
		if(parseInt(selectedvalue, 10) == selectedvalue)	// If selected value is a numeric id, reload this page as if the form had been submitted
		{
			if(parentformaction)
				window.location = parentformaction+"?"+selectname+"="+selectedvalue;	// If possible, use the actual form action
			else
				window.location = location.substr(0, location.indexOf("?"))+"?"+selectname+"="+selectedvalue;	// Otherwise, take an educated guess (but beware: this will fail with "pretty" rewritten urls like /path/page/var1/var2 as there's no question-mark)
		}
		else
		{
			if(selectedvalue[0] == "/")														// Relative URL
				window.location = location.substr(0, location.indexOf("/", 7))+selectedvalue;
			else if(selectedvalue.indexOf("://") > 0)										// Absolute URL
				window.location = selectedvalue;
			else if(parentformaction)														// String ID (if possible, use the actual form action)
				window.location = parentformaction+"?"+selectname+"="+selectedvalue;
			else																			// String ID, no form action, so take an educated guess and try to work out from the current URL what the address should be (and pray it's using traditional?url=style rather than /pretty/url/style)
				window.location = location.substr(0, location.indexOf("?"))+"?"+selectname+"="+selectedvalue;
		}
	};
	
	// Member functions (methods)
	// None.
	
};