// $Id$

var it_boot_status = "boot";
var it_panictimer = window.setTimeout("it_panic({reason:it_boot_status})", 31337), it_domtimer;
var it_starttime = new Date().getTime();

function it_stacktrace()
{
	var stacktrace = "";
	var callstack_done = false;

	try { i.dont.exist += 0; } // does not exist - that's the point
	catch (e)
	{
		if (e.stack) // Firefox
		{
			stacktrace = e.stack.replace(/^[^\n]*\n/,'').replace(/(\n@)?\s+$/,'$1').replace(/^\(/g,'{anonymous}(') + ';';
			callstack_done = true;
		}
		else if (window.opera && e.message) // Opera
		{
			var entry, lines = e.message.split("\n");
			for (var i=1, len=lines.length; i < len; i++)
			{
				if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/))
				{
					entry = lines[i];
					// append next line also since it has the file info
					if (lines[i+1])
					{
						entry += " at " + lines[i+1];
						i++;
					}
					stacktrace += entry + ',';
				}
			}
			callstack_done = true;
		}
	}

	if (!callstack_done) // IE and Safari
	{
		var fname, current_func = arguments.callee.caller;
		while (current_func)
		{
			fname = /function\s*([\w\-$]+)?\s*\(/.test(current_func.toString()) ? RegExp.$1 || 'anonymous' : 'anonymous';
			stacktrace += fname + ',';
			current_func = current_func.caller;
		}
	}

	return stacktrace;
}

function it_catcherr(msg, url, line)
{
	var stacktrace = it_stacktrace();

	if (typeof it_boot.sequence != 'undefined')
	{
		// trigger it_boot retry if error occured while evaluating loaded script
		if (it_boot.sequence == 'ble' && it_boot.file)
		{
			it_boot(it_boot.file, true);
			return true;
		}

		stacktrace += "it_boot=" + it_boot.sequence + ";it_boot_file=" + it_boot.file;
	}
	if (typeof window.it_loader != 'undefined' && it_loader.sequence)
		stacktrace += "it_loader=" + it_loader.sequence + ";";

	it_boot_report({msg:msg, url:url, line:line, stacktrace:stacktrace});

	return !window.env || !!window.env.is_live_server;	// No env or live server -> suppress error
}

window.onerror = it_catcherr;

function it_boot_addparam(url, param)
{
	return url + (url.match(/\?/) ? "&" : "?") + param;
}

function it_panic(p)
{
	if (!document.location.href.match(/[?&]static=/))	// Avoid loop
		window.setTimeout("document.location.href = it_boot_addparam(document.location.href, 'static=" + p.reason + "')", 500);

	p.type = "panic";
	p.stacktrace = it_stacktrace();
	return it_boot_report(p);
}

function it_boot_report(p)
{
	window.clearTimeout(window.it_domtimer);
	window.clearTimeout(window.it_panictimer);
	var loader = null;
	var data = "";
	var postdata = p.data;
	delete p.data;
	p.time = new Date().getTime() - it_starttime;

	for (var k in p)
		data += (data ? '&' : '') + k + "=" + escape(p[k]).replace(/\+/g, "%2B");

	var url = "/itjs/error.gif?" + data;

	if (postdata)
	{
		loader = it_boot_getloader();
		for (var k in postdata)
			data += (data ? '&' : '') + k + "=" + escape(postdata[k]).replace(/\+/g, "%2B");
	}

	try
	{
		loader.open('POST', url);
		loader.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		loader.send(data);
	}
	catch (e)
	{
		new Image().src = url;
	}
}

function it_boot_checkcss(style, key, value)
{
	return navigator.userAgent.match(/konqueror/i) || (style && style.getPropertyValue && (style.getPropertyValue(key) == value));
}

function it_boot_init()
{
	it_boot.sequence += "i";
	window.it_domtimer = null;
	var konqueror = navigator.userAgent.match(/konqueror/i);
	var doc = document;
	var dom = doc && (dom = doc.getElementById('it_boot_dom'));	// HTML has been rendered
	var view = dom && doc.defaultView;	// We can check if stylesheet is active
	var style = view && view.getComputedStyle && view.getComputedStyle(dom, '');
	var css = window.it_boot_checkcss(style, "visibility", "hidden"); // CSS active (inline style on tag)
	var stylesheet = window.it_boot_checkcss(style, "display", "none");	// External stylesheet loaded

	if (!(doc || !(it_boot_status = "doc")) || !(dom || !(it_boot_status = "dom")) || (style && !(stylesheet || !(it_boot_status = "stylesheet"))))
	{
		window.it_domtimer = window.setTimeout("it_boot_init()" , 42);

		if (style && !css)
			it_panic({reason:"css"});

		return;
	}

	window.clearTimeout(window.it_panictimer); 
	it_boot.sequence += "s";
	window.it_boot_start();
	it_boot.sequence = "";
}

function it_boot_getloader()
{
	var result = null;

	if (!navigator.userAgent.match(/iPhone|iP.d/))	// Do not use XMLHttpRequest on iOS devices as it does not use cache
	{
		try
		{
			result = new XMLHttpRequest();
		}
		catch (e)
		{
			var classnames = [ 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP' ];

			for (var i in classnames)
				try { result = new ActiveXObject(classnames[i]); break; } catch (e) {}
		}
	}

	return result;
}

function it_boot(file, isretry)
{
	it_boot.file = file;
	it_boot.sequence = isretry ? "r" : "b";
	var loader = it_boot_getloader();

	if (loader)
	{
		it_boot.sequence += "l";
		loader.open("GET", it_boot_addparam(file, "boot=1" + (isretry ? "&retry=1" : "")));
		loader.onreadystatechange = function()
		{
			var error = "", code = "";

			if (loader.readyState == 4)
			{
				if (loader.status < 400)	// Opera gives back 304 if from cache
				{
					// check length cookie
					var ln = String(loader.responseText).match(/\*sln:([0-9]+)[^\n]*\n([\s\S]*\n)\/\*eln:\1/);
					code = ln ? unescape(ln[2]) : loader.responseText;
					if (ln && ln[1]-0 == code.length)
					{
						it_boot.sequence += "e";
						if (!window.env || !!window.env.is_live_server)
							code = "try {" + code + "} catch (e) { it_catcherr(e.message, it_boot.file, -1); }";	// Wrapped in try/catch as Konqueror does not support window.onerror
						if (window.execScript)
							window.execScript(code, "javascript");	// IE work-around to get script executed in global scope
						else
							window.setTimeout(code, 0);	// Standard compliant version
					}
					else
						error = (ln ? "length mismatch: " + ln[1] + " != " + code.length : "no length cookie");
				}
				else
					error = loader.statusText;

				if (error)
				{
					if (isretry)
						it_panic({reason:'load', error:error, data:{code:code}});
					else
						it_boot(file, true);
				}
			}
		}
		loader.send(null);
	}
	else
	{
		var doc = document;
		var dom = doc && (dom = doc.getElementById('it_boot_dom'));	// HTML has been rendered
		it_boot.sequence += "n";

		if (window.opera || (document.all && navigator.platform.indexOf("Mac") >= 0))
			document.write('<sc'+'ript type="text/javascript" src="'+it_boot_addparam(file, 'boot=1&script=1')+'"><\/sc'+'ript>');
		else if (dom)
		{
			var tag = doc.createElement("script");
			tag.src = it_boot_addparam(file, 'boot=1&script=1&retry=1');
			dom.appendChild(tag);
		}
		else
			window.it_domtimer = window.setTimeout("it_boot('" + file + "')" , 42);
	}
}

if (document.documentElement)
	document.documentElement.className += ' js';