/*
 * Javascript Loader
 *   by Zach Ashman
 *  Air Line Pilots Association
 */
if (typeof window.jsLoader === "undefined") jsLoader = window.jsLoader = (function() {
	
	var scripts = {
		jQuery: {
			key: "jQuery",
			store: "jQuery",
			url: "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",
			loadCheck: "jQuery"
		}
	};

	var jsStore = {};
	var meta = {};
	
	var log = function(text) {
		if (typeof ZCA !== "undefined" && typeof ZCA.Util !== "undefined" && typeof ZCA.Util.log === "function") {
			ZCA.Util.log(text, true, "jsLoader");
		}
	}
	
	var extend = function(extended, options) {
		if (typeof extended === "object" && typeof options === "object") {
			for (var i in options) {
				extended[i] = options[i];
			}
		}
		return extended;
	};

	var typeOf = function(value) {
		var s = typeof value;
		if (s === 'object') {
			if (value) {
				if (typeof value.length === 'number' && !(value.propertyIsEnumerable('length')) && typeof value.splice === 'function') {
					s = 'array';
				}
			} else {
				s = 'null';
			}
		}
		return s;
	};
	
	var saveGlobals = function(variables) {
		var saved = {};
		if (typeof variables === "string") {
			variables = [variables];
		}
		if (typeOf(variables) === "array") {
			for (var i = 0; i < variables.length; i++) {
				if (typeof variables[i] === "string") {
					saved[variables[i]] = window[variables[i]];
					//window[variables[i]] = undefined;
				}
			}
		}
		return saved;
	};
	
	var restoreGlobals = function(saved) {
		if (typeof saved !== "undefined") {
			for (var i in saved) {
				window[i] = saved[i];
			}
		}
	};
	
	var checkLoaded = function(variables) {
		if (typeof variables === "string") {
			variables = [variables];
		}
		var loadCheck = true;
		var segments, obj;
		for (var i = 0; i < variables.length; i++) {
			segments = variables[i].split(".");
			obj = window;
			for (var j = 0; j < segments.length; j++) {
				if (typeof obj[segments[j]] === "undefined") {
					loadCheck = false;
					break;
				}
				obj = obj[segments[j]];
			}
			if (!loadCheck) {
				break;
			}
		}
		return loadCheck;
	};
	
	var getStore = function(key) {
		if (typeof jsStore[key] !== "undefined") {
			var store = jsStore[key];
			var size = 0, i;
			for (i in store) {
				if (store.hasOwnProperty(i)) {
					size++;
				}
			}
			if (size === 1) {
				store = store[i];
			}
			return store;
		} else {
			return null;
		}
	};

	var fn = {
		scripts: scripts,
		load: function(options, extended) {
			log("Load called");
			if (typeof options === "string") {
				options = scripts[options];
			}
			
			if (typeof options === "undefined") {
				options = {};
			}
			
			if (typeof extended === "object") {
				options = extend(options, extended);
			}
			
			if (typeof options.key !== "string" || typeof options.url !== "string" || typeof options.loadCheck !== "string") {
				return;
			}
			log("Loading: " + options.key);
			log("(" + options.key + ") Url: " + options.url);
			
			if (typeof meta[options.key] === "undefined") {
				log("(" + options.key + ") First Load");
				meta[options.key] = {};
				meta[options.key].loading = true;
				meta[options.key].complete = [];
				if (typeof options.complete === "function") {
					meta[options.key].complete.push(options.complete);
				}
				if (typeof options.noConflict === "string") {
					options.noConflict = [options.noConflict];
				}
				var appended = false;
				if (typeof options.append === "string" && typeof jsStore[options.append] === "object") {
					options.noConflict = options.noConflict || [];
					for (var i in jsStore[options.append]) {
						options.noConflict.push(i);
					}
					appended = true;
				}
				var noConflict = saveGlobals(options.noConflict);
				if (appended) {
					restoreGlobals(jsStore[options.append]);
				}
				var head = document.getElementsByTagName("head")[0] || document.documentElement;
				var script = document.createElement("script");
				script.src = options.url;
				script.charSet = "utf-8";
				head.appendChild(script);
				
				var timeout = 500;
				log("(" + options.key + ") Timer Init");
				log("(" + options.key + ") Interval code: " + window.setInterval);
				var check = window.setInterval(function() {
					log("(" + options.key + ") Wait");
					if (checkLoaded(options.loadCheck)) {
						log("(" + options.key + ") Loaded");
						clearInterval(check);
						head.removeChild(script);
						if (typeof options.store === "string") {
							options.store = [options.store];
						}
						var store = {};
						if (typeOf(options.store) === "array") {
							for (var i = 0; i < options.store.length; i++) {
								if (typeof options.store[i] === "string") {
									store[options.store[i]] = window[options.store[i]];
								}
							}
						} else {
							store = true;
						}
						jsStore[options.key] = store;
						restoreGlobals(noConflict);
						
						log("(" + options.key + ") " + meta[options.key].complete.length + " Complete functions");
						for (var i = 0; i < meta[options.key].complete.length; i++) {
							meta[options.key].complete[i].call(jsStore[options.key], getStore(options.key));
						}
						log("(" + options.key + ") All functions called");
						meta[options.key].loading = false;
						meta[options.key].complete = [];
					}
					timeout--;
					if (timeout === 0) {
						log("(" + options.key + ") Timeout");
						meta[options.key].loading = false;
						meta[options.key].complete = [];
						clearInterval(check);
						head.removeChild(script);
						restoreGlobals(noConflict);
						jsStore[options.key] = false;
					}
				}, 10);
				log("(" + options.key + ") Interval Id: " + check);
			} else {
				log("(" + options.key + ") Already Defined");
				if (typeof options.complete === "function") {
					if (meta[options.key].loading === false) {
						options.complete.call(jsStore[options.key], getStore(options.key));
						log("(" + options.key + ") Loaded complete function called");
					}
					else {
						meta[options.key].complete.push(options.complete);
						log("(" + options.key + ") Added to complete stack");
					}
				}
			}
		},
		isLoaded: function(key) {
			return typeof meta[key] !== "undefined" && typeof meta[key].loading !== "undefined" && !meta[key].loading;
		},
		get: getStore
	};
	
	return fn;
})();