﻿Ext.ns("AV");

// CSS/JS loader ======================================================================================
AV.Loader =  
{
	oScripts			: null,
	iNumScripts		: -1, 
	iScriptIdx		: 0, 
	fCallback			: null, 
	oScope				: null, 
	
	/// loadMultiple
	/// description			:	loads css and js files specified in the objLoad object in order. Upon completion,
	///										the function specified by callback will be called with the passed in scope
	/// scripts
	///			src - URL for script or Ajax Call
	///			type - 'script' - Creates a script tag using the URL as the source
	///							'ajax' - retrieves the JSON from the URL via ajax
	///			objStr -	for type = 'script', objStr is a javascript obj in the script being loaded that is checked
	///								for type = 'ajax', objStr is the javascript obj (string) that the returned JSON is assigned to. The object string
	///																		does not have to be initialized 
	///	objLoad format	:
	/// { scripts: 
	/// 		[ 
	/// 			{ src: 'Global/Ext/ext-2.1/ux/RowActions/Ext.ux.grid.RowActions.js', type: 'script', objStr: 'Ext.ux.grid' }, 
	/// 			{ src: 'Global/Ext/ext-2.1/ux/GridDDReorder/GridReorderDropTarget.js', type: 'ajax', objStr: 'Ext.ux.dd.GridReorderDropTarget' } 
	/// 		],
	/// 	css:
	/// 		[
	/// 			{ src: 'Global/Ext/ext-2.1/ux/RowActions/Ext.ux.grid.RowActions.css' }, 
	/// 			{ src: 'Global/Ext/ext-2.1/ux/GridDDReorder/GridReorderDropTarget.css' } 
	/// 		] 
	/// }
	loadWindowContent: function() {
		if (this.fCallback) { this.fCallback.call((this.oScope ? this.oScope : this)); }
		this.fCallback = null;
		this.oScope = null;
	},

	loadMultiple: function(objLoad, callBack, scope)
	{
		// all scripts loaded, reset vars and execute callback
		if (this.iScriptIdx == this.iNumScripts)
		{
			this.oScripts = null;
			this.iNumScripts = -1;
			this.iScriptIdx = 0;
			
			this.loadWindowContent();
			
			return;
		}
		
		// first call, set the object props and load css
		if (!this.oScripts) 
		{ 
			this.oScripts = objLoad;
			this.iNumScripts = objLoad.scripts.length;
			this.fCallback = callBack;
			this.oScope = scope;
			
			if (typeof(objLoad.css) === 'object' && objLoad.css.length > 0)
			{
				for (var i=0; i<objLoad.css.length; i++)
				{
					this.load(objLoad.css[i].src, 'css');
				}
			}
		}	
		
		var curScript = this.oScripts.scripts[this.iScriptIdx];
		this.iScriptIdx = this.iScriptIdx + 1;
		this.load(curScript.src, curScript.type, curScript.objStr, this.loadMultiple, this);
	},
	
	load: function (strUrl, strType, strObj, callBack, scope)
	{
		var numTries = 0;
		var numObjParts = 0;
		var arObjParts = [];
		
		switch (strType)
		{
			case 'ajax':		loadJSAjax(strUrl, strObj, callBack, scope); break;
			case 'css':			loadCSS(strUrl); break;
			default:				loadJS(strUrl, strObj, callBack, scope); break;
		}
		
		function loadCSS(strUrl)
		{
			var arCss = document.getElementsByTagName("link");
			var intScriptLen = strUrl.length;
			
			for (var i=0; i<arCss.length; i++)
			{
				var strScript = arCss[i].href.toLowerCase();
				var iLen = strScript.length;	
				if (iLen > 0 && iLen > intScriptLen) { strScript = strScript.substr(iLen -	intScriptLen); }
				if (strScript == strUrl.toLowerCase()) { return; }
			}
			 
			var e = document.createElement("link");
			e.href = strUrl;
			e.type = "text/css";
			e.rel = "stylesheet";
			document.getElementsByTagName("head")[0].appendChild(e);
		}
		
		function loadJSAjax(strUrl, strObj, callBack, scope)
		{
			//var self = this;
			Ext.Ajax.request(
			{
				url							: strUrl,
				method					: "GET",
				disableCaching	: true,
				callback: function(request,success,response) 
									{
										var json = Ext.decode(response.responseText.replace(new RegExp("\\n","g")," "));
										if (success && !json.err) 
										{
											var arParts = strObj.split('.');
											var numParts = arParts.length;
											var sBaseObj = '';
											for (var i=0; i<(numParts - 1); i++) 
											{ 
													sBaseObj += (i > 0 ? '.' : '') + arParts[i];
											}
											var o = Ext.ns(sBaseObj);
											o[arParts[numParts - 1]] = json; //Ext.decode(response.responseText);
											callBack.call((scope ? scope : this	), o[arParts[numParts - 1]]); 
										} 
										else 
										{
											scope.oScripts = null;
											scope.iNumScripts = -1;
											scope.iScriptIdx = 0;

											Ext.Msg.alert("Error",json.err,function() {	
												if (AV.ContentWindowTS) { AV.ContentWindowTS.closeWindow(null, true);	}
											});
										}
									}
			});
		}
		
		function loadJS(strUrl, strObj, callBack, scope)
		{
			var arLoadedScripts = document.getElementsByTagName("script");
			var intScriptLen = strUrl.length;
			
			for (var i=(arLoadedScripts.length - 1); i >= 0; i--)
			{
				var strScript = arLoadedScripts[i].src.toLowerCase();
				var iLen = strScript.length;	
				if (iLen > 0 && iLen > intScriptLen) { strScript = strScript.substr(iLen -	intScriptLen); }
				if (strScript == strUrl.toLowerCase())
				{
					if (strObj && callBack) { checkLoad(); }
					return;
				}
			}

			var e = document.createElement("script");
			e.src = strUrl;
			e.type = "text/javascript";
			document.getElementsByTagName("head")[0].appendChild(e); 
			
			if (strObj && callBack) { checkLoad(); }
		}
		
		function checkLoad()
		{
			var sObj = '';
			if (numObjParts == 0) 
			{ 
				arObjParts = strObj.split('.'); 
				numObjParts = arObjParts.length;
			}
			
			// Test each part of the object w/o using eval 
			var oTest = window;
			for(var i = 0; i < numObjParts; i++)
			{
				//sObj += (i > 0 ? '.' : '') +  arObjParts[i];
				if (!oTest[arObjParts[i]] && numTries < 50)
				{
					//console.log('Retry: ' + sObj);
					numTries++;
					setTimeout(function() { checkLoad(); }, 100); 
					return;
				}
				else { oTest = oTest[arObjParts[i]]; }
				//console.log(sObj);	
			}
			
			/* Now doing the check above because Zach's mods were not good
			if (typeof eval(sObj) !== "function" && numTries < 50) {
				numTries++;
				setTimeout(function() { checkLoad(); }, 100); 
				return;
			}
			*/
			// All parts of the object exist
			callBack.call((scope ? scope : this), window[sObj]); 
		}
		
	}
};
