function makeReqObj()
{
	if (window.XMLHttpRequest) return new XMLHttpRequest();
	else return new ActiveXObject("Microsoft.XMLHTTP");
}

function deserialise(text)
{
	return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
	       text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
	       eval('(' + text + ')');
}

// for debugging
function dump(obj)
{
	var s = "";
	for (var a in obj) s += a + ": " + obj[a] + ",";
	alert("{" + s + "}");
}

// Assigns event handlers and unhooks them on unload
var handle = function() {
	var events = [];
	window.onunload = function() {
		for (var i in events)
			events[i][0][events[i][1]] = null;
		events = null;
	}
	return function(target, event, func) {
		target[event] = func;
		events[events.length] = [target, event];
	}
}();

/*function addonload(f) {
	var x = window.onload;
	if (x) window.onload = function() { x(); f(); }
	else handle(window, "onload", f);
}*/
addonload = function() {
	var events = [];
	
	function init() { // "onload" handler -- may be called multiple times due to the overlapping tests below
		var ecopy = events;
		events = [];
		for (var i in ecopy) ecopy[i]();
	}
	
	var first = true;
	return function(f) {
		if (first) {
			if (/WebKit/i.test(navigator.userAgent)) { // Safari
				var _timer = setInterval(function() {
					if (/loaded|complete/.test(document.readyState)) {
						clearInterval(_timer);
						init(); // call the onload handler
					}
				}, 10);
			}
			if (document.addEventListener) { // Firefox, Opera, others?
				document.addEventListener("DOMContentLoaded", init, false);
			} 
			/*@cc_on @*/
			/*@if (@_win32)
				// IE for Windows
				document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
				var script = document.getElementById("__ie_onload");
				script.onreadystatechange = function() {
					if (this.readyState == "complete") {
						init(); // call the onload handler
					}
				};
			/*@end @*/
			handle(window, "onload", init);
			first = false;
		}
		events.push(f);
	}
}();



function absLocate(obj)
{
	var left = 0, top = 0;
	do
	{
		left += obj.offsetLeft;
		top += obj.offsetTop;
	}
	while (obj = obj.offsetParent);
	return [left, top];
}

function isAncestorOrSelfOf(x, y)
{
	while (y)
	{
		if (x == y) return true;
		y = y.parentNode;
	}
	return false;
}

function getOwnerPostString(elem, additional)
{
	elem = elem.form;
	var vals = additional || [];
	var types = ["input", "select", "textarea"];
	for (var typeIndex in types)
	{
		var type = types[typeIndex];
		var inputs = elem.getElementsByTagName(type);
		for (var i = 0; i < inputs.length; ++i)
			vals.push(escape(inputs[i].name) + "=" + escape(inputs[i].value));
	}
	return vals.join("&");
}

function showTempMessageAt(obj, message, pos, duration, d)
{
	if (duration == undefined) duration = 3000;
	
	var xy = absLocate(obj);
	var div = document.body.appendChild(document.createElement("div"));
	div.appendChild(document.createTextNode(message));
	div.className = "popup-msg";
	div.style.position = "absolute";
	
	if (pos == undefined || pos == "right")
	{
		div.style.left = (xy[0] + obj.offsetWidth + (d ? d[0] : 0)) + "px";
		div.style.top = xy[1] + (d ? d[1] : 0) + "px";
	}
	else if (pos == "under")
	{
		div.style.left = xy[0] + (d ? d[0] : 0) + "px";
		div.style.top = (xy[1] + obj.offsetHeight + (d ? d[1] : 0)) + "px";
	}
	
	var obj = {div: div, alive: true, kill: function() { if (obj.alive) { document.body.removeChild(obj.div); } obj.alive = false; }};
	if (duration != -1) window.setTimeout(obj.kill, duration);
	return obj;
}

function mousePos(e)
{
	if (e.pageX || e.pageY) return [e.pageX, e.pageY];
	return [e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft,
	        e.clientY + document.body.scrollTop + document.documentElement.scrollTop];
}

function addClass(obj, className)
{
	obj.className += " " + className;
}

function delClass(obj, className)
{
	obj.className = obj.className.replace(new RegExp("\\b"+className.replace("-", "\\-")+" ?"), "");
}

function hasClass(obj, className)
{
	return obj.className.search(new RegExp("\\b"+className.replace("-", "\\-")+"\\b")) != -1;
}

function disableTextSelection()
{
	document.documentElement.ondrag = function () { return false; };
	document.documentElement.onselectstart = function () { return false; };
	addClass(document.body, "no-select");
}

function enableTextSelection()
{
	document.documentElement.ondrag = null;
	document.documentElement.onselectstart = null;
	delClass(document.body, "no-select");
}

function removedefaultonfocus(sender, msg)
{
	if (sender.value == msg) sender.value = "";
}
function adddefaultonblur(sender, msg)
{
	if (sender.value == "") sender.value = msg;
}
