/*
This file should be included into the 'Master' page...

The purpose for this script is to allow for a mechanism whereby javascripts are added to the DOM.

Script availablity is checked, to provide a pre-cache method for ensuring scripts never get unneccessarily loaded.

Work in progress......
*/


//=============================================================================
// GLOBAL HELPERS... If you are heavily reliant on globals which need to be used 
// by multiple js files, then here is the place to define your globals. This file 
// is required for any page in our site and is loaded before any anycronous 
// opperation... which is why this is the best place to be defining those silly 
// inter-dependant globals, you strange person.
//=============================================================================

var queryString = new Object();
var CurrentlyOpen = new Object();

//=============================================================================


//Local Global String store for init.
var AppInitStore = new Object();
AppInitStore.CSSFiles = new Array();
AppInitStore.JScripts = new Array();


/**
	Serialize a form's values into a JS object.
	@tparam string src The form element ID 
*/
$.extend({
	serializeForm: function(selector)
	{
		var formElements = new Object();
		var src=$(selector);
		for(var i = 0; i<src[0].elements.length; i++)
		{
			var currElmnt = src[0].elements[i];
			if(!(currElmnt.name==undefined||currElmnt.name==null||currElmnt.name==""))
				formElements[currElmnt.name] = currElmnt.value;
		}
		return formElements;
	}
});





//go-go jQuery PLUGIN!
$.extend({

	//getScriptCached_Debug uses the DOM injection method. The reason this method was chosen was to ensure that MS script debugger and FireBug could display dynamically loaded scripts
	getScriptCached_Dom_Inject : function(url,CallBack)
	{
		//define the script tag
		var script=document.createElement('script');
		script.setAttribute("type","text/javascript");
		script.setAttribute("src", url);
		//add it
		$("head")[0].appendChild(script);
		
		// was a callback requested
		if (CallBack) 
		{
			//======================================================================
			//*Note, no support for Safari, and therefore probably not Chrome...
			//  Hopefully it will come soon. Timer method might be a replacement, 
			// or just ensure that on live, the getScriptCached_Release version is served. :'(
			//======================================================================
			
			// test for onreadystatechange to trigger callback (IE)
			script.onreadystatechange = function () 
			{
				if ((script.readyState == 'loaded') || (script.readyState == 'complete')) 
				{
					CallBack();
				}
			}
			
			// test for onload to trigger callback (FireFox,Opera)
			script.onload = function () 
			{
				CallBack();
				return;
			}
		}
	},
	
	/*
		getScriptCached_Compat has been included as a
	*/
	getScriptCached_Compat : function(url,CallBack)
	{
		$.ajax({
			type: "GET",
			url: url,
			success: CallBack,
			dataType: "script",
			cache: true
		});
	},

	//Edit this bit for compatibility issues...
	getScriptCached: function(url,CallBack)
	{
		//uncomment the 1st line and comment the 2nd if you want to debug.
		return this.getScriptCached_Dom_Inject(url,CallBack);
		//return this.getScriptCached_Compat(url,CallBack);
	}
	
});

//The plugins
$.fn.extend({
	/*
		function LoadComponent
		url - the init file for the component
		_data - data to pass to the component
		CallBack - fnction to call when LoadComponent is done
	*/
	LoadComponent : function(url,_data,CallBack)
	{
		function _GetNextNonCachedScript(Scripts)
		{
			do{//get a script which isn't cached
				var Script = Scripts.shift();
			}while((Script)&&(AppInitStore.JScripts.join(" ").indexOf(Script)!=-1))
			return Script;
		}
		
		
		function _LScript(Scripts,InitScript)
		{
			Script = _GetNextNonCachedScript(Scripts);
			if(Script)
			{
				AppInitStore.JScripts.push(Script);//push the script name onto list of loaded scripts.
				$.getScriptCached(Script,function(res){_LScript(Scripts,InitScript)});
			}
			else
			{
				eval(InitScript);
				if(CallBack!=undefined)
					CallBack("success");
			}
		}
		
		function loadcssfile(filename)
		{
			var fileref=document.createElement("link");
			fileref.setAttribute("rel", "stylesheet");
			fileref.setAttribute("type", "text/css");
			fileref.setAttribute("href", filename);
			$("head")[0].appendChild(fileref);
		}
		
		var Container = this;
		var safeURL = url;
		
		if(safeURL.indexOf("?") > 0){
			safeURL += "&GetJSON=true";
		}else{
			safeURL += "?GetJSON=true";
		}
		
		$.getJSON(safeURL,null,
			function(data, textStatus)
			{
				//load the css
				if(data.CSSFiles!=null)
				{
					for(var ind in data.CSSFiles)
					{
						if(AppInitStore.CSSFiles.join(" ").indexOf(data.CSSFiles[ind])==-1)
						{
							AppInitStore.CSSFiles.push(data.CSSFiles[ind]);
							loadcssfile(data.CSSFiles[ind]);
						}
					}
				}
				
				//Call the content, passing along GET variables.
				var Ind = window.location.href.indexOf("?");
				var GetVars = '';
				
				if(Ind>0)
				{
					GetVars = window.location.href.substr(Ind+1); //+1 to remove the '?' char
				}
				
				if(typeof(_data)=='object')
				{
					if(_data!=null)
						GetVars = $.param(_data)+"&"+GetVars;
				}
				else if(typeof(_data)=='string')
				{
					GetVars = _data+"&"+GetVars;
				}
				
				Container.load(data.ContentURL,GetVars,
					function(responseText, textStatus, XMLHttpRequest)
					{

						
						//run the init scripts.
						if((data.JScripts!=null)&&(data.JScripts!=""))
						{
							_LScript(data.JScripts,data.InitScript);
						}
						else
						{
							eval(data.InitScript);
							if(CallBack)
								CallBack("success");
						}
						
					});
			});
		},
	
	/*
		function LoadComponentOnce
		url - the init file for the component
		data - data to pass to the component
		CallBack - fnction to call when LoadComponent is done
	*/
	LoadComponentOnce : function(url,data,CallBack) 
	{
		if(!(this.hasClass('loaded')))
		{
			var Container = this; //storing for closure
			this.LoadComponent(url,data,function(textStatus)
			{
				CallBack(textStatus);
				Container.addClass('loaded');
			});
		}
	}
});

//Utility functions (These are pretty useless due to the single-threaded nature of javascript...re-design to maybe use events?)
//== These remain useful with AJAX calls

function beginWait() 
{ 
	document.documentElement.className = 'waitCursor'; 
}
function endWait() 
{ 
	document.documentElement.className =  ''; 
}

