/*!
*	TContentPreload v1.0
*	by Toni Rantanen 2011-11-10 www.kotimaanetti.fi
*/

/*
options:
- json events: (js callback function)
	onload, upon receiving responce
	onset, after setting html (insivible)
	onvisible, when html 100% visible
	onclear, before clearing html
- json dynamic loading: (string or array of strings)
	loadjs, loadcss
*/

var TContentPreload = new Class(
{
	Implements: Options,
	
	loaded: null,
	toLoadCount: 0,
	toLoadCss: [],
	toLoadJs: [],
	preloadCallback: null,
	
	options:
	{
		html: null,
		loadcss: null,
		loadjs: null,
		onload: null,
		onset: null,
		onvisible: null,
		onclear: null
	},
		
	initialize: function(options)
	{
		// prep and set options
		
		if(typeOf(options.loadcss) === 'string')
			options.loadcss = new Array(options.loadcss);
		else if(typeOf(options.loadcss) !== 'array')
			options.loadcss = new Array();
		
		if(typeOf(options.loadjs) === 'string')
			options.loadjs = new Array(options.loadjs);
		else if(typeOf(options.loadjs) !== 'array')
			options.loadjs = new Array();
		
		if(typeOf(options.onset) !== 'string')
			options.onset = '';
		
		if(typeOf(options.onvisible) !== 'string')
			options.onvisible = '';
		
		if(typeOf(options.onclear) !== 'string')
			options.onclear = '';
		
		this.setOptions(options);
		
		/*
		// get scripts
		this._parseHtml();
		*/
		
		// setup to loads
		this.toLoadCss = options.loadcss;
		this.toLoadJs = options.loadjs;
		this.toLoadCount = this.toLoadCss.length + this.toLoadJs.length;
	},
	
	/*
	_parseHtml: function()
	{
		var scripts = new Array();
		var regex, matches;
		var typeRegex = /<script[^>]+type=["']?(?:text\/)?javascript/i;
		
		// urls
		regex = /<script[^>]+src=['"]([^'"]*)['"][^>]*>(?:.|[\n\r])*?<\/script>/gi;
		while(matches = regex.exec(this.options.html))
		{
			if(typeRegex.exec(matches[0]))
				this.options.loadjs.push(matches[1]);
		}
		this.options.html = this.options.html.replace(/<script[^>]+src=['"][^'"]*['"][^>]*>(?:.|[\n\r])*?<\/script>/gi, '');
		
		// scripts
		regex = /<script[^>]*>((?:.|[\n\r])*?)<\/script>/gi;
		while(matches = regex.exec(html))
		{
			if(typeRegex.exec(matches[0]))
				options.onset += " \n"+ matches[1];
		}
		this.options.html = this.options.html.replace(/<script[^>]*>(?:.|[\n\r])*?<\/script>/gi, '');
		
		// cleanup
		this.options.html = this.options.html.replace(/<script[^>]*\>/gi, '');
	},
	*/
	
	preload: function(callback)
	{
		this.preloadCallback = callback;
		this.loaded = false;
		
		// continue or dynamic preload
		if(this.toLoadCount < 1)
			this._preloadFinished();
		else
		{
			this._preloadCss();
			this._preloadJs();
		}
	},
	
	_preloadFinished: function()
	{
		if(this.toLoadCount > 0 || this.loaded)
			return;
		this.loaded = true;
		this.preloadCallback(this);
	},
	
	// no preloading, just add links and continue
	//   because: Asset.css doesn't support onLoad
	_preloadCss: function()
	{
		// done?
		if(this.toLoadCss.length > 0)
		{
			// get loaded
			var loaded = [];
			$$('link').each(function(el) {
				if(el.href != '')
					loaded.push(el.href);
			});
			var item = null;
			while(item = this.toLoadCss.shift())
			{
				if(!loaded.contains(getURIFull(item)))
					new Asset.css(item);
				this.toLoadCount--; // update loaded
			}
		}
		this._preloadFinished(); // continue
	},
	
	// preload and continue
	_preloadJs: function()
	{
		// done?
		if(this.toLoadJs.length < 1)
			return this._preloadFinished();
		// get loaded
		var loaded = [];
		$$('script').each(function(el) {
			if(el.src != '')
				loaded.push(el.src);
		});
		// load or continue
		var item = this.toLoadJs.shift();
		if(loaded.contains(getURIFull(item)))
		{
			this.toLoadCount--; // update loaded
			this._preloadJs(); // continue
		}
		else
			new Asset.javascript(item, {
				onLoad: function(){
					this.toLoadCount--; // update loaded
					this._preloadJs(); // continue
				}.bind(this)
			});
	},
	
	_runStrCallback: function(selfName, selfVar, callback)
	{
		if(typeof(callback) != 'undefined')
		{
			try
			{
				(new Function(selfName, callback))(selfVar);
				return true;
			}
			catch(err)
			{
				if(typeof(console.log) != 'undefined')
				{
					console.log(err);
					console.trace();
					console.log('ERROR IN:\n'+ callback);
				}
			}
		}
		return false;
	},
	
	// on set event
	getContent: function()
	{
		return this.options.html;
	},
	
	// on set event
	runOnLoad: function(selfName, selfVar)
	{
		this._runStrCallback(selfName, selfVar, this.options.onload);
	},
	
	// on set event
	runOnSet: function(selfName, selfVar)
	{
		this._runStrCallback(selfName, selfVar, this.options.onset);
	},
	
	// on visible event
	runOnVisible: function(selfName, selfVar)
	{
		this._runStrCallback(selfName, selfVar, this.options.onvisible);
	},
	
	// on clear event
	runOnClear: function(selfName, selfVar)
	{
		this._runStrCallback(selfName, selfVar, this.options.onclear);
	}
});

