/** 
 * @fileoverview DHTML Widgets base object for the JSPOOP library
 * @author James Palmer james@phoenixlondon.co.uk
 * @version 0.1 
 */

/**
 * Construct the Phoenix.Widgets object.
 * @class Base class for DHTML widgets in the Phoenix library.
 * @constructor
 * @requires Phoenix
 */
Phoenix.Widgets = function()
{
};
//registerNamespace("Phoenix.Widgets");

/*
	registerThisWidget()
	
	1. Register this widget's namespace identifier
	2. Register the widget in Phoenix.Widgets._InstantiatedControls, so its presence will be discoverable by other controls/general javascript on any page it's included in.
*/

Phoenix.Widgets.registerThisWidget = function (fullyqualifiedidentifier, controlobj)
{
	// Given the desired fully-qualified namespace identifier as a text string ("x.y.z"), register this control's namespace object (along with any necessary parent identifiers)
	var widgetindexonpage = 0;
	
	registerNamespace(fullyqualifiedidentifier);	// I can't think how or why anyone would be registering a widget unless they'd already defined the namespace for it (even implicitly), but it won't hurt to check just in case

	if(typeof(controlobj) != "undefined")
	{
		// Define list of instantiated controls to allow inter-widget communication
		if(typeof(Phoenix.Widgets._InstantiatedControls) == "undefined")	// If not already done, define the array to hold all instantiated controls on page
			Phoenix.Widgets._InstantiatedControls = new Array();
			
		widgetindexonpage = Phoenix.Widgets._InstantiatedControls.length;
		Phoenix.Widgets._InstantiatedControls.push(controlobj);					// and append this control to it
	}

	// Now we need a reference to the control's newly-created namespace *object* ("z", in the example above)
	var nsParts = fullyqualifiedidentifier.split(".");
	var root = window;
	for(var i=0; i<nsParts.length; i++)
		root = root[nsParts[i]];
	
	// Now, save the passed-in Javascript object reference (IMPORTANT: this is the difference between Phoenix.Widgets.registerThisWidget() and Phoenix.Controls.registerThisControl()) that's a reference to the HTML element object this widget represents.
	//root.rootElement = rootelementobjref;
	
	return(widgetindexonpage);	// Finally, return this widget's index number in the global widgets array (Phoenix.Widgets._InstantiatedControls) in case it ever needs to refer to itself from the window scope (eg, from an asynchronous callback like setTimeout() in IE)
};



// Run on window.onload, to initialise widgets ONCE THE DOM HAS LAID THEM OUT CORRECTLY.
// Initialising them synchronously when they're defined in code means different browsers may return misleading values for their dimensions (eg, if the page must be re-flowed when later content is loaded, the value returned while initialising will become incorrect), or simply return "0".

var doop = "";

Phoenix.Widgets.initWidgets = function ()
{
//	debugger
	if(!namespaceDefined("Phoenix.Widgets._InstantiatedControls"))	// Could have used requireNamespace() here, but if no controls defined we want it to exit quietly, not throw a noisy exception
		return(false);	// No controls defined on page, so exit silently
	for(var i=0; i<Phoenix.Widgets._InstantiatedControls.length; i++)
	{
		if(Phoenix.Widgets._InstantiatedControls[i]._render) {
			Phoenix.Widgets._InstantiatedControls[i]._render();
			//doop += Phoenix.Widgets._InstantiatedControls[i].nsIdentifier+" ";
		}
	}
	
	//if(!Phoenix.Widgets.textSize)
	//	Phoenix.Widgets.initTextSizeMonitor();
		
	return(Phoenix.Widgets._InstantiatedControls.length);
}

// Set all widgets to render on page-load and window-resize.
requireNamespace("Phoenix.Util.Event");


Phoenix.Util.Event.addEventHandler("load", window, Phoenix.Widgets.initWidgets);	// Initialise the widgets on page load
Phoenix.Util.Event.addEventHandler("resize", window, function (e) {

	e = e || window.event;
	var currentwidth = document.body.clientWidth;

	if(window.brokenIEResizeEvent_PreviousWidth != currentwidth) {
		//alert(currentwidth);
		window.brokenIEResizeEvent_PreviousWidth = currentwidth;
		Phoenix.Widgets.initWidgets();
	}
	else {
		if(typeof(e.cancelBubble) != 'undefined')
			e.cancelBubble = true;
		if(e.stopPropagation)
			e.stopPropagation();
		if(e.preventDefault)
			e.preventDefault();
	}

	
});	// And reinitialise them on window-resize (as in liquid/elastic layouts their dimensions may have changed)

// Problem - we also want widgets to be able to re-render themselves when the user's browser's text-size or zoom-level changes.
// The trouble is, the W3C event model specifies the "resize" event only fires when the user's *viewport* size changes, not when an *element's* size changes.
// Hence we have to add our own invisible div with a space in it, and monitor it at regular intervals to see if its dimensions have changed.
// If so then the user's text-size has changed, and we should re-render the page's widgets appropriately.

Phoenix.Widgets.initTextSizeMonitor = function()
{
	var bodyelement = document.documentElement.lastChild;	// Body element
	var textresizedetector = bodyelement.lastChild;			// Last child of body element
	
	// Look for hidden text-size span at end of page, creating it if not found
	if(!textresizedetector || !textresizedetector.tagName || textresizedetector.tagName.toLowerCase() != "div")
	{
		textresizedetector = document.createElement("div");
		textresizedetector.innerHTML = "&nbsp;";
		textresizedetector.style.position="relative";
		textresizedetector.style.height="1em";
		textresizedetector.style.visibility="hidden";
		bodyelement.appendChild(textresizedetector);
	}

	window.setInterval("Phoenix.Widgets._textSizeMonitor()", 250);	// Check for text-size changes roughly every quarter-second
}

Phoenix.Widgets._textSizeMonitor = function()
{
	// Grab last element of body (added to DOM by initTextSizeMonitor
	var textsize = document.documentElement.lastChild.lastChild.offsetHeight;
	
	if(textsize != Phoenix.Widgets.textSize)
	{
		//alert("Text size changed from "+Phoenix.Widgets.textSize+" to "+textsize);
		Phoenix.Widgets.textSize = textsize;
		Phoenix.Widgets.initWidgets();
	}
}

