/******************************************************************************

	Copyright (C) 2006-2007  John Ha

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

******************************************************************************/

if (!khanh) var khanh = {};
if (!khanh.loader) {
	khanh.loader = function() {
		this.url = '';
		this.tracker = '';
		this.stack = null;
		this.queue = null;
		this.onload = null;
	
		/*
			include: {
				type: 'js',
				files: 'file.js'
			},
			
			type: js or css
			files: string or array
		*/
		this.add = function(include) {
			this.push(include, 'stack');
		};

		this.then = function(include) {
			this.push(include, 'queue');
		};

		this.push = function(include, array) {
			if (!isArray(include['files']))
				if (include['files'])
					include['files'] = new Array(include['files']);
				else return;
	
			if (!this[array]) this[array] = [];
			this[array][this[array].length] = include;
		};

		this.load = function(file) {
			if (file) this.url = this.getURL(file);
			if (!this.stack && this.queue && this.queue.length)
				this.stack = this.queue.splice(0, 1);

			this.tracker = '';
			for (var i = 0; i < this.stack.length; i++) {
				var files = this.stack[i]['files'];
				if (isDefined(files))
					for (var j = 0; j < files.length; j++)
						this.tracker += this.url + files[j];
			}
			// this.stack changes due to multi-threading,
			// so we keep a local copy here to so it stays
			// constant.
			var stack = this.stack;
			this.stack = null;
			for (var i = 0; i < stack.length; i++) {
				var files = stack[i]['files'];

				var callback = null;
				if (stack[i]['type'] == 'js')
					callback = this.runJS;
				else if (stack[i]['type'] == 'css')
					callback = this.addCSS;

				if (isDefined(files) && callback)
					for (var j = 0; j < files.length; j++)
						this.loadURL(this.url + files[j], callback);
			}
		};
	
		this.loadURL = function(url, callback) {
			var xmlhttp = null;
	
			try {
				xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
			} catch (e) {
				try {
					xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
				} catch (E) {
					xmlhttp = null;
				}
			}
	
			// Fall through for Mozilla / Netscape / Opera
			if (!xmlhttp && isDefined(XMLHttpRequest))
				xmlhttp = new XMLHttpRequest();
	
			if (xmlhttp) {
				xmlhttp.open('GET', url, 1);
	
				// Prevent browser cache
				xmlhttp.setRequestHeader('If-Modified-Since', 'Sat, 1 Jan 2000 00:00:00 GMT');
	
				var that = this;
				// Load asynchronously
				xmlhttp.onreadystatechange = function() {
					if (xmlhttp.readyState == 4)
						callback(that, url, xmlhttp.responseText);
				};
	
				xmlhttp.send(null);
			}
		};
	
		this.runJS = function(that, url, jsText) {
			if (window.execScript) {
				window.execScript(jsText);
				that.checkDone(url);
			} else if (eval.call) {
				eval.call(window, jsText);
				that.checkDone(url);
			}
		};
	
		this.addCSS = function(that, url, cssText) {
			var style = document.createElement('style');
			style.type = 'text/css';
			if(style.styleSheet) style.styleSheet.cssText = cssText;		// IE
			else style.appendChild(document.createTextNode(cssText));		// W3C
			document.getElementsByTagName('head')[0].appendChild(style);
			that.checkDone(url);
		};
	
		this.checkDone = function(url) {
			this.tracker = this.tracker.replace(new RegExp(url), '');
			if (!this.tracker) {
				if (this.queue && this.queue.length) {
					this.stack = this.queue.splice(0, 1);
					if (!this.queue.length) this.queue = null;
					this.load();
				} else this.onload();
			}
		};
		
		this.getURL = function(file) {
			var scripts = document.getElementsByTagName('script');
			for (var i = scripts.length - 1; i  >= 0; i--) {
				if (new RegExp(file.replace(/\./g, '\.')).test(scripts[i].src)) {
					var core = /includes\/core\.php\?dir=/;
					if (core.test(scripts[i].src))
						return scripts[i].src.replace(/&?(file|type)=.+(&|$)/g, '').replace(core, '') + '/';
					else
						return scripts[i].src.replace(/[^\/]+$/, '');
				}
			}
		};
	};
}
