function ud(enc)
{
	var dec = "";
	var ln = enc.length;
	var i = 0;
	var ch, high, low;
	while (i < ln)
	{
		ch = enc.charAt(i);
		if (ch == '+')
		{
			dec += " ";
			++i;
		}
		else if (ch == '%')
		{
			if (i < ln - 2)
			{
				high = enc.charCodeAt(i + 1);
				low = enc.charCodeAt(i + 2);
				if (high >= 48 && high <= 57)
					high -= 48;
				else if (high >= 65 && high <= 90)
					high -= 55;
				else if (high >= 97 && high <= 122)
					high -= 87;
				if (low >= 48 && low <= 57)
					low -= 48;
				else if (low >= 65 && low <= 90)
					low -= 55;
				else if (low >= 97 && low <= 122)
					low -= 87;
				dec += String.fromCharCode((high << 4) + low);
				i += 3;
			}
			else
			{
				dec += "%";
				++i;
			}
		}
		else
		{
			dec += ch;
			++i;
		}
	}
	return dec;
}

function ue( plaintext )
{
	var SAFECHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.!~*'()";	// RFC2396 Mark characters
	var HEX = "0123456789ABCDEF";
	
	var encoded = "";
	for (var i = 0; i < plaintext.length; i++ ) 
	{
		var ch = plaintext.charAt(i);
		if (ch == " ") 
		{
			encoded += "+";	// x-www-ued, rather than %20
		}
		else if (SAFECHARS.indexOf(ch) != -1) 
		{
			encoded += ch;
		}
		else 
		{
			var charCode = ch.charCodeAt(0);
			if (charCode > 255) 
			{
				encoded += "+";
			} 
			else 
			{
				encoded += "%";
				encoded += HEX.charAt((charCode >> 4) & 0xF);
				encoded += HEX.charAt(charCode & 0xF);
			}
		}
	}
	
	return encoded;
}

function ajax(url, postdata)
{
	var method = "GET";
	if (postdata)
		method = "POST";
	
	var req = 0;
	if (window.XMLHttpRequest)
		req = new XMLHttpRequest();
	else
		req = new ActiveXObject("Microsoft.XMLHTTP");
		
	req.onreadystatechange = function() {
		if (req.readyState == 4 && req.status != 200)
			alert("An error occured while processing request. Please try again.");
		else if (req.readyState == 4 && req.responseText.length > 0)
		{
			if (req.responseText.search(/error/i) != -1)
				alert(req.responseText);
			else
				eval(req.responseText);
		}
	}

	var ts = (new Date()).getTime();
	if (url.indexOf("?") == -1)
		url += "?ts=" + ts;
	else
		url += "&ts=" + ts;
	
	req.open(method, url, true);
	if (postdata)
		req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");    
	req.send(postdata);
}

timedAjaxes = new Array();

function timedAjax(timeout, timeoutName, url)
{
	cancelTimedAjax(timeoutName);
	timedAjaxes[timeoutName] = setTimeout("ajax(\"" + url + "\");timedAjaxes[\"" + timeoutName + "\"] = false;", timeout);
}

function cancelTimedAjax(timeoutName)
{
	if (timedAjaxes[timeoutName])
	{
		clearTimeout(timedAjaxes[timeoutName]);
		timedAjaxes[timeoutName] = false;
	}
}

function clearDiv(el)
{
	while (el.firstChild)
		el.removeChild(el.firstChild);
}

function reuseDiv(id, cls, parentid)
{
	var el = document.getElementById(id);
	if (!el)
	{
		el = document.createElement("div");
		el.id = id;
		el.className = cls;
		if (parentid)
			document.getElementById(parentid).appendChild(el);
	}
	return el;
}
