function splitFiles(file_string)
{
	if (file_string == '')
	{
		return [];
	}
	else
	{
		return file_string.split(/##/);
	}
}

function fileLoader(xone_responder, callback_object)
{
	if (xone_responder != null)
	{
		this.xone_responder = xone_responder;

		this.js_files = splitFiles(xone_responder.xone_result.xone_params['js_files']);
		this.css_files = splitFiles(xone_responder.xone_result.xone_params['css_files']);

		this.static_style = xone_responder.xone_result.xone_params['static_style'];
		this.static_style_md5 = xone_responder.xone_result.xone_params['static_style_md5'];
		this.static_script = xone_responder.xone_result.xone_params['static_script'];
		this.load_events = xone_responder.xone_result.xone_params['load_events'];
	}
	else
	{
		this.js_files = [];
		this.css_files = [];

		this.static_style = '';
		this.static_script = '';
		this.load_events = '';

		this.xone_responder = callback_object;
	}

	this.loaded_files = this.getCurrentlyLoadedFiles();
	this.files_added = Array();
}

fileLoader.prototype.getCurrentlyLoadedFiles = function()
{
	var head = document.getElementsByTagName('head')[0];

	var scripts = get(head, CHILDREN_BY_TAG, 'script');
	var file_sources = Array();
	for (var i = 0; i < scripts.length; i++)
	{
		if (scripts[i].src.length > 0)
		{
			file_sources.push(scripts[i].src);
		}
	}

	var sheets = get(head, CHILDREN_BY_TAG, 'link');
	for (var i = 0; i < sheets.length; i++)
	{
		if (sheets[i].href.length > 0)
		{
			file_sources.push(sheets[i].href);
		}
	}
	return file_sources;
}

fileLoader.prototype.hasSS = function(file_source)
{
	return in_array(this.loaded_files, file_source);
}

fileLoader.prototype.loadFiles = function()
{
	// load the css files
	for (i in this.css_files)
	{
		var file_split = this.css_files[i].split(/::/);

		var file = file_split[0];
		var media_type = file_split[1];

		this.addCSSFile(file, media_type);
	}

	// load the js files
	this.loadNextJS();
}

fileLoader.prototype.addJSFile = function(file_src)
{
	var head = document.getElementsByTagName('head')[0];
	var script = document.createElement('script');

	script.src = file_src;
	script.type = "text/javascript";
	script.language = "javascript";

	if (!this.hasSS(script.src))
	{
		script.onload = loadJSDone; // for fox de feu
		script.onreadystatechange = loadJSReadyState; // for ie

		script.file_loader = this;

		this.files_added.push(file_src);
		head.appendChild(script);
	}
	else
	{
		this.loadNextJS();
	}
}

fileLoader.prototype.addCSSFile = function(file_src, media)
{
	var head = document.getElementsByTagName('head')[0];
	var css = document.createElement('link');
	css.href = file_src;
	css.rel = 'stylesheet';
	css.type = 'text/css';
	css.media = media;

	if (!this.hasSS(css.href))
	{
		this.files_added.push(file_src);
		head.appendChild(css);
	}
}

fileLoader.prototype.loadNextJS = function()
{
	var next_source = this.js_files.shift();
	if (!next_source)
	{
		this.complete();
	}
	else if (next_source.length > 0)
	{
		this.addJSFile(next_source);
	}
	else
	{
		this.loadNextJS();
	}
}

fileLoader.prototype.complete = function()
{
	this.addStaticStyle(this.static_style, this.static_style_md5);
	this.addStaticScript(this.static_script);
	this.xone_responder.reply();
	this.addStaticScript(this.load_events);
}

fileLoader.prototype.addStaticStyle = function(style, md5)
{
	if (style.length > 0 && !this.hasStatic(md5))
	{
		var is_ie = (document.all) ? true : false;

		var style_elem = document.createElement('style');
		style_elem.type = 'text/css';
		style_elem.media = 'screen';
		style_elem.id = "s_" + md5;

		var head = document.getElementsByTagName("head")[0];
		head.appendChild(style_elem);

		if (is_ie)
		{
			var rules = this.parseStyleString(style);
			var sheet = document.styleSheets[document.styleSheets.length - 1];
			this.addRulesToSheet(sheet, rules);
		}
		else
		{
			style_elem.innerHTML = style;
		}
	}
}

/**
 * For IE only, styles can be added directly to a style element otherwise.
 */
fileLoader.prototype.addRulesToSheet = function(sheet, rules)
{
	for (var i = 0; i < rules.length; i++)
	{
		var selector = rules[i][0];
		var rule = rules[i][1].split(/,/);

		// if selector and rule are there, and no first child selector operator (ff hack) in selector
		if (selector.length > 0 && rule.length > 0 && (selector.indexOf('>') < 0))
		{
			// IE8 RC1 doesn't allow trailing spaces in selectors (probably bug)
			rules[i][0] = rules[i][0].replace(/^\s+|\s+$/g, "");
			
			sheet.addRule(rules[i][0], rules[i][1]);
		}
	}
}

fileLoader.prototype.parseStyleString = function(style_string)
{
	var styles = style_string.split('}');
	var parsed = Array();
	for (var i = 0; i < styles.length; i++)
	{
		var style = styles[i].split('{');
		// selectors may be comma-separated
		var selectors = (style[0]) ? style[0].split(/,/) : "";
		var rules = (style[1]) ? style[1] : "";

		// have to make separte entry for each target, or sheet.addRule() will fail
		for (j in selectors)
		{
			if (selectors[j] && rules)
			{
				parsed.push(Array(selectors[j], rules));
			}
		}
	}

	return parsed;
}

fileLoader.prototype.addStaticScript = function(script)
{
	if (script.length > 0)
	{
		var script_elem = document.createElement('script');
		script_elem.type = 'text/javascript';
		script_elem.language = 'javascript';
		script_elem.text = script;

		var head = document.getElementsByTagName('head')[0];
		head.appendChild(script_elem);
	}
}

fileLoader.prototype.hasStatic = function(md5)
{
	if (get("s_" + md5) != null)
	{
		return true;
	}
	else
	{
		return false;
	}
}

/* end fileLoader class */


function loadJSDone(script)
{
	var script = (this.src) ? this : script;
	script.file_loader.loaded_files.push(script.src);
	script.file_loader.loadNextJS();
}

function loadJSReadyState()
{
	if (this.readyState == 'complete' || this.readyState == 'loaded')
	{
		loadJSDone(this);
	}
}

/* for debugging */
function out(string)
{
	var out = document.createElement('div');
	out.appendChild(document.createTextNode(string));
	document.body.appendChild(out);
}
