/**
To help with load bearing; we will dynamically load javascript, as 
requests are being passed; thus we will be able to save on the initial bandwidth

	@author Jacob Novero
	@version 4/20/2009
*/


	function ImportScript()
	{
		this.files = [];
		this.pointer=null;
		this.source = [];
		this.scripts = [];
		this.callback = [];
		this.request = [];
		this.head = null;
		this.queue = [];
		this.displayable = false;
		
		if(document.importScripts==null)
			document.importScripts = [];
		
		document.importScripts.push(this);
		objects.push(this); // marked for death.
	}
	
	ImportScript.prototype = 
	{
		getHead:function()
		{
			if(this.head==null)
				this.head = document.getElementsByTagName('head')[0];
			
			return this.head;
		},
		importFile:function(filename,params)
		{
			if(!this.scripts[filename])
			{
				this.scripts[filename] = new ScriptObject(filename,params,this);
				this.scripts[filename].fetchScript();
				
				return true;
			}
			else
				return false;
		},
		isLoaded:function(filename)
		{
			return this.scripts[filename]!=null?true:false;
		},
		importStyle:function(filename)
		{
			if(!this.scripts[filename])
				this.scripts[filename] = new StyleObject(filename,this);
			else
				return false;
		},
		importCode:function(code,label)
		{
			if(!this.scripts[label])
			{
				this.scripts[label] = new CodeObject(label,code,this);
			}
			else
			{
//				console.log("--" + label + ":already in document--");
			}
		},
		removeScript:function(label)
		{
			if(this.scripts[label])
			{
				this.scripts[label]._destruct();
				this.scripts[label] = null;
			}
		},
		queueScript:function(script)
		{
			//console.log("--" + script.filename + ":adding to queue--");
			if(script.inline)
			{
				script.runScript();
			}
			else
				this.queue.push(script);
		},
		isDisplayable:function(script)
		{
			if(script.async) // try to run it before the document is complete in this case.
				return true; 
			
			
			return (this.displayable?true:false);
		},
		loadScript:function(script)
		{
			if(this.isDisplayable(script))
				script.runScript();	
			else
				this.queueScript(script);
		},	
		loadQueuedScripts:function()
		{
			this.displayable = true;
			
			while(this.queue.length > 0)
				this.queue.pop().runScript();
		},
		_destruct:function()
		{
			for(var i in this.scripts)
				this.scripts[i]._destruct();
				
			for(var index in this)
				this[index] = null;
				
			killself(this);
		}
	}
	
	function ScriptObject(filename,params,mgr)
	{
		
		this.remote = false;
		this.mgr = mgr;
		var data = [];
		this.pointer = filename;
		this.inline = false;
		this.filename = filename;
		this.code = null;
			
		if(params!=null)
			for(var i in params)
				this[i] = params[i];
		
	}
	
	ScriptObject.prototype =
	{
		async:false,
		fetchScript:function()
		{
			var data = {};

			if(this.remote)
				this.loadScript('remote');
			else
			{
				this.request = new AjaxRequest(this.filename,{object:this,method:"loadScript"},data,"GET");
				this.request.makeRequest({noExec:1});
			}
		},
		runScript:function()
		{
			var script = document.createElement("script");
			script.async=true;
			script.type = "text/javascript";
					
			if(this.remote)
			{
				script.src = renderResourceLink(RSC.ASSET,this.filename);
			}
			else
			{
				var script = document.createElement("script");
				script.text = this.source;
			}
			
			if(this.inline)
			{
				var head = this.mgr.getHead();
				head.appendChild(script);
			}
			else 
			{
				// note::i saw this in google analytics code, where they insert it right after an existing script node.
				// i initially encountered an issue with IE output buffering that blew up the page, so we delay it, but the inclusion of the async 
				// attribute might actually fix it.				
			    var s = document.getElementsByTagName('script')[0]; 
			    
			    if(s!=null)
				    s.parentNode.insertBefore(script, s)
				else
					document.body.appendChild(script);
			}
			this.code = script;
			
			this.fireCallback();
			
		},
		fireCallback:function(script)
		{
			if(this.callback)
			{
				try
				{
					this.times=0;
					this.callbackWrapper(this.code);
				}
				catch(e)
				{
					konsole.log('imported script callback',e);
				}
			}
		},
		/** if script fails to run the callback, it is usually due to the code not being read in time, so we set a timeout **/
		callbackWrapper:function(params)
		{
			try
			{
				if(this.callback.object!=null)
					this.callback.object[this.callback.method](this.code);
				else if(this.callback.fnc!=null)
					this.callback.fnc(this.code);
				else if(this.callback.replace!=null)
					eval(this.callback + "(this.code)");

			}		
			catch(e)
			{
				if(this.times<20)
				{
					var ldr = this;
					setTimeout(function(){ldr.callbackWrapper()},200);
					this.times++;
				}
			}
			
		},
		loadScript:function(data)
		{
			this.source = data;
			this.mgr.loadScript(this);
		},
		_destruct:function()
		{
			if(this.code!=null)
				this.code.parentNode.removeChild(this.code);
				
			for(var i in this)
				if(i!="mgr")
					this[i]=null;	
		}
	}
	
	function CodeObject(label,code,mgr)
	{
		this.mgr = mgr;
		this.pointer = label;
		this.filename = label;
		this.loadScript(code);
	}
	CodeObject.prototype = new ScriptObject();
	
	
	function StyleObject(label,mgr)
	{
		this.mgr = mgr;
		this.pointer = label;
		this.filename = label;
		this.remote = true;
		this.runScript();
		
	}
	StyleObject.prototype = new ScriptObject();
	
	StyleObject.prototype.runScript=function()
	{
		//<link id="js-style" rel="stylesheet" href="/gym/10778/styles/dynamic.css" type="text/css">
		var script = document.createElement("link");
		script.href =  renderResourceLink(RSC.ASSET,this.filename); // now we send it to the resource url generator
		script.type="text/css";
		script.rel="stylesheet";
		document.body.appendChild(script);
	}
