var zi = 100;

String.prototype.trim = function ()
{
	return this.replace(/^\s*(.+?)\s*$/, "$1");
}

var dims = {
	viewport: {
		width: function ()
		{
			return document.body.clientWidth;
		},
		height: function ()
		{
			return document.body.clientHeight;
		}
	},
	page: {
		width: function ()
		{
			return document.documentElement.clientWidth;
		},
		height: function ()
		{
			return document.documentElement.clientHeight;
		},
		scrolltop: function ()
		{
			return Math.max(document.documentElement.scrollTop, document.body.scrollTop); //webkit is dumb
		},
		scrollleft: function ()
		{
			return Math.max(document.documentElement.scrollLeft, document.body.scrollLeft); //webkit is dumb
		}
	}
};

function listen(elem, type, callback)
{
	if (elem.addEventListener)
	{
		if (type == "click" || type == "mousedown" || type == "mouseup")
		{
			elem.addEventListener(type, function (evt) { if ((!document.all && evt.button == 0) || ((document.all || window.navigator.userAgent.match(/KHTML\/3\.5/)) && evt.button <= 1)) { callback(evt, evt.target); } }, false);
		}
		else
		{
			elem.addEventListener(type, function (evt) { callback(evt, evt.target); }, false);
		}
	}
	else if (elem.attachEvent)
	{
		if (type == "click" || type == "mousedown" || type == "mouseup")
		{
			elem.attachEvent("on" + type, function (evt) { if ((!document.all && evt.button == 0) || (document.all && evt.button <= 1)) { callback(evt, evt.srcElement); } });
		}
		else
		{
			elem.attachEvent("on" + type, function (evt) { callback(evt, evt.srcElement); });
		}
	}
}

function unlisten(elem, type, callback)
{
	if (elem.removeEventListener)
	{
		elem.removeEventListener(type, callback, false);
	}
	else if (elem.detachEvent)
	{
		elem.detachEvent(type, callback);
	}
}

function init()
{
	listen(document, "click", handledialogs);
	listen(document, "mousedown", handledragdrop)
	listen(document, "mouseup", handledragdrop)

	var iform = document.getElementById("inventoryform");
	if (iform != null)
	{
		listen(iform, "click", handleinventory);
	}

	var itemlist = document.getElementById("itemlist");
	if (itemlist != null)
	{
		listen(itemlist, "click", handlemultibuy);
	}

	var fiddlebox = document.getElementById("fiddlebox");
	if (fiddlebox != null)
	{
		listen(fiddlebox, "click", handlefiddle);
	}

	var chath3 = sel(document.getElementById("chatcontainer"), "div > h3");
	var c = document.cookie.split("; ");
	var cookies = {chatpos: "0:10"};
	for (var i in c)
	{
		var tmp = c[i].split("=");
		cookies[tmp[0]] = decodeURIComponent(tmp[1]);
	}
	if (chath3 != null)
	{
		var chatpos = cookies["chatpos"].split(":");
		adjustchat(chath3.parentNode.parentNode, chatpos[0] - -50, chatpos[1] - -60);
		listen(document, "resize", handleresize);
		listen(window, "resize", handleresize);
	}

	parsetimestamp(document.body);
	document.body.usertimestamp = time();
}

function handleresize(evt, target)
{
	var chat = document.getElementById("chatcontainer");
	var bottom = chat.style.bottom.replace(/px$/, "");
	var right = chat.style.right.replace(/px$/, "");

	adjustchat(chat, bottom, right);
	storechatpos(bottom, right);
}

function handledragdrop(evt, target)
{
	if (evt.type == "mousedown")
	{
		if (target.nodeName == "H3")
		{
			listen(document, "mousemove", handledragdrop)

			var target = target.parentNode.parentNode;
			if (typeof(target.className) != "undefined" && target.className == "pop")
			{
				if (target.style.right.match(/^-?\d+px$/))
				{
					target.style.left = target.offsetLeft + "px";
					target.style.right = "";
				}
				if (target.style.bottom.match(/^-?\d+px$/))
				{
					target.style.top = target.offsetTop + "px";
					target.style.bottom = "";
				}
			}

			handledragdrop.target = target;
			handledragdrop.startx = evt.clientX;
			handledragdrop.starty = evt.clientY;
			handledragdrop.startscrolltop = dims.page.scrolltop();
			handledragdrop.startscrollleft = dims.page.scrollleft();
			handledragdrop.starttop = target.style.top.replace(/px$/, "");
			handledragdrop.startleft = target.style.left.replace(/px$/, "");

			if (typeof(target.id) != "undefined" && target.id == "chatcontainer")
			{
				handledragdrop.startbottom = target.style.bottom.replace(/px$/, "");
				handledragdrop.startright = target.style.right.replace(/px$/, "");
			}

			cancelevent(evt);
		}
	}
	else if (evt.type == "mouseup" || evt.type == "mousemove")
	{
		var target = handledragdrop.target;
		if (typeof(target) == "undefined" || target === null)
		{
			return;
		}

		if (typeof(target.className) != "undefined" && target.className == "pop")
		{
			var newtop = handledragdrop.starttop - -((evt.clientY - handledragdrop.starty) + (dims.page.scrolltop() - handledragdrop.startscrolltop));
			var newleft = handledragdrop.startleft - -(evt.clientX - handledragdrop.startx);
			adjust(target, newtop, newleft);
		}
		else if (typeof(target.id) != "undefined" && target.id == "chatcontainer")
		{
			var newbottom = handledragdrop.startbottom - (evt.clientY - handledragdrop.starty);
			var newright = handledragdrop.startright - (evt.clientX - handledragdrop.startx);
			adjustchat(target, newbottom, newright);

			if (evt.type == "mouseup")
			{
				storechatpos(newbottom, newright);
			}
		}

		if (evt.type == "mouseup")
		{
			handledragdrop.target = null;
			target = null;

			unlisten(document, "mousemove", handledragdrop)
		}

		cancelevent(evt);
	}
}

function storechatpos(newbottom, newright)
{
	var expire = new Date();
	expire.setHours(expire.getHours() + 24*90);
	document.cookie = "chatpos=" + encodeURIComponent((newbottom - 50) + ":" + (newright - 60)) + "; expires=" + expire.toGMTString() + "; path=/";
}

function adjust(target, newtop, newleft)
{
	var minleft = (document.body.id == "index-game" ? 132 : 5);

	newtop = Math.min(Math.max(dims.viewport.height(), dims.page.height()) - 52 - target.offsetHeight, Math.max(32, newtop));
	newleft = Math.min(dims.viewport.width() - 50 - target.offsetWidth, Math.max(minleft, newleft));
	target.style.left = newleft + "px";
	target.style.top = newtop + "px";
}

function adjustchat(target, newbottom, newright)
{
	newbottom = Math.min(dims.page.height() - 32 - target.offsetHeight, Math.max(50, newbottom));
	newright = Math.min(dims.page.width() - 132 - target.offsetWidth, Math.max(50, newright));
	target.style.right = newright + "px";
	target.style.bottom = newbottom + "px";
}

function handledialogs(evt, target)
{
	if (typeof(target.href) != "undefined" && target.href.match(/\/(?:item|set|player)\.php\?/))
	{
		sendrequest(target, evt) || cancelevent(evt);
	}
}

function handleinventory(evt, target)
{
	if (target.nodeName == "LI")
	{
		toggleli(target);
	}
	else if (target.id.match(/^s\d+$/))
	{
		togglesel(target, evt);
	}
	else if (target.className.match(/\bsell\b/))
	{
		multibuysell(target, evt) || cancelevent(evt);
	}
}

function handlemultibuy(evt, target)
{
	if (target.className.match(/\bbuy\b/))
	{
		multibuysell(target, evt) || cancelevent(evt);
	}
}

function cancelevent(evt)
{
	if (evt.preventDefault)
	{
		evt.preventDefault();
	}
	else
	{
		evt.returnValue = false;
	}
}

function qm(context, q)
{
	var e = sel(context.parentNode, "input");
	e.value = e.value - q*(-1);
	if (e.value <= 0)
	{
		e.value = 1;
	}
}

function multibuysell(target, evt)
{
	stopevent(evt);
	if (typeof(target.dialog) != null && target.dialog != null)
	{
		return false;
	}

	var q = sel(target.parentNode.parentNode, "span.q");
	if (q != null && parseInt(q.innerHTML, 10) <= 1)
	{
		return true;
	}

	var action = target.href.replace(/^.+a=(-?\d+).*$/, "$1");
	var type = "buy";
	if (action.match(/^-/))
	{
		type = "sell";
	}
	var item = sel(target.parentNode.parentNode, "a").innerHTML;

	var newe = document.createElement("div");
	newe.className = "buyselldialog";
	newe.style.visibility = "hidden";
	newe.innerHTML = document.getElementById("buyselltemplate").innerHTML;
	sel(newe, "form > fieldset > div." + type + " > span.itemtitle").innerHTML = item;
	sel(newe, "form > fieldset > input.itemid").value = action;

	document.body.appendChild(newe);

	setposition(target.parentNode, newe);

	initmultiform(target, newe);

	return false;
}

function multicc(e)
{
	if (typeof(e.dialog) != "undefined" && e.dialog != null)
	{
		return false;
	}

	var newe = document.getElementById("ctemplate").cloneNode(true);
	newe.id = "";
	var li = e.parentNode.parentNode;
	sel(newe, "form > fieldset > div.template > span.itemtitle").innerHTML = li.innerHTML.replace(/^.+>\s*([^:]+)\s*\(\d+\):.+$/, "$1");

	document.body.appendChild(newe);

	setposition(e.parentNode, newe);

	initmultiform(e, newe);

	return false;
}

function multicast(e)
{
	if (typeof(e.dialog) != "undefined" && e.dialog != null)
	{
		return false;
	}

	var newe = document.getElementById("ctemplate").cloneNode(true);
	newe.id = "";
	var text = e.parentNode.nextSibling;
	text = (typeof(text.textContent) != "undefined" ? text.textContent : text.nodeValue);
	sel(newe, "form > fieldset > div.template > span.spelltitle").innerHTML = text;

	document.body.appendChild(newe);
	
	setposition(e.parentNode, newe);

	initmultiform(e, newe);

	return false;
}

function initmultiform(e, newe)
{
	newe.animate = {
		targetwidth: newe.offsetWidth,
		targetheight: newe.offsetHeight,
		endfunc: null
	};
	newe.style.width = "0";
	newe.style.height = "0";
	newe.style.visibility = "";
	newe.style.zIndex = zi++;
	e.parentNode.dialog = newe;
	animate(newe);
	newe.origin = e;
	e.dialog = newe;
}

function domc(e)
{
	window.location = e.parentNode.origin.href + "&q=" + e.q.value;

	return false;
}

function docc(e)
{
	window.location = e.parentNode.origin.href + "&qc=" + e.q.value + "&q=" + e.q.value;

	return false;
}

function animate(e)
{
	e.animate.startwidth = e.offsetWidth;
	e.animate.startheight = e.offsetHeight;
	e.animate.width = e.offsetWidth;
	e.animate.height = e.offsetHeight;
	e.animate.lasttime = microtime();
	if (typeof(e.animate.setopacity) == "undefined")
	{
		e.animate.setopacity = true;
	}
	if (typeof(e.animate.duration) == "undefined")
	{
		e.animate.duration = 300;
	}
	if (typeof(e.animate.endfunc) == "undefined")
	{
		e.animate.endfunc = null;
	}

	e.animate.timer = setTimeout(function () { _animate(e) }, 0);
}

function _animate(e)
{
	var now = microtime();
	var diff = now - e.animate.lasttime;

	if (e.animate.targetwidth != e.animate.width)
	{
		e.animate.width += (diff/e.animate.duration)*(e.animate.targetwidth - e.animate.startwidth);
		e.animate.width = clamp(e.animate.width, e.animate.targetwidth, e.animate.startwidth);
		e.style.width = Math.round(e.animate.width) + "px";
	}

	if (e.animate.targetheight != e.animate.height)
	{
		e.animate.height += (diff/e.animate.duration)*(e.animate.targetheight - e.animate.startheight);
		e.animate.height = clamp(e.animate.height, e.animate.targetheight, e.animate.startheight);
		e.style.height = Math.round(e.animate.height) + "px";
	}

	if (e.animate.setopacity)
	{
		var size = Math.max(e.animate.targetwidth, e.animate.startwidth) + Math.max(e.animate.targetheight, e.animate.startheight);
		var current = e.animate.width + e.animate.height;

		var op = current/size;
		e.style.opacity = op;
		e.style.filter = "alpha(opacity=" + Math.round(op*100) + ")";
	}

	e.animate.lasttime = now;

	var remaining = Math.round(Math.abs(e.animate.width - e.animate.targetwidth)) + Math.round(Math.abs(e.animate.height - e.animate.targetheight));
	if (remaining != 0)
	{
		e.animate.timer = setTimeout(function () { _animate(e); }, 0);
	}
	else if (e.animate.endfunc != null)
	{
		e.animate.endfunc();
	}
}

function clamp(v, min, max)
{
	if (min > max)
	{
		var tmp = min;
		min = max;
		max = tmp;
	}
	return (v < min ? min : (v > max ? max : v));
}

function microtime()
{
	var d = new Date();
	return Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds());
}

function time()
{
	return Math.round(microtime()/1000, 0);
}

function servertime()
{
	return (document.body.timestamp + (time() - document.body.usertimestamp));
}

function putmarket(prefix)
{
	var a = document.getElementById(prefix + "a");
	var pr = document.getElementById(prefix + "pr");

	if (a.value == 0)
	{
		alert("Try picking an item first");
		return false;
	}

	if (pr.value <= 0 || pr.value == "")
	{
		alert("Try entering a price first");
		return false;
	}
}

function popprice(prefix)
{
	var a = document.getElementById(prefix + "a");
	var pr = document.getElementById(prefix + "pr");

	if (a.value != 0)
	{
		if (typeof(itemprices[-a.value]) != "undefined")
		{
			pr.value = itemprices[-a.value];
		}
		else
		{
			var gold = parseInt(a[a.selectedIndex].innerHTML.replace(/^.+\((\d+) gold\)$/, "$1"), 10);
			if (markuptype == "gold")
			{
				gold += markup;
			}
			else if (markuptype == "percent")
			{
				gold *= 1 + (markup/100.0);
				gold = Math.round(gold);
			}
			pr.value = gold;
		}
	}
	else
	{
		pr.value = "";
	}
}

function resort(pid, zid, n)
{
	var e = document.getElementById("sortby" + (n == 2 ? "2" : ""));
	parent.location = "index.php?p=" + pid + "&z=" + zid + "&s" + (n == 2 ? "2" : "") + "=" + e.value;
}

function useitemg(pid, zid)
{
	var e = document.getElementById("useitem");
	if (e.value != 0)
	{
		parent.location = "index.php?p=" + pid + "&z=" + zid + "&a=u" + e.value;
	}
}

function combine()
{
	var f = document.getElementById("c1");
	var g = document.getElementById("c2");
	if (f.value != 0 && g.value != 0)
	{
		return true;
	}
	else
	{
		alert("You need to have two items selected first.");
		return false;
	}
}

function getxmlrequest()
{
	var ret = false;
	if (typeof XMLHttpRequest != "undefined")
	{
		ret = new XMLHttpRequest();
	}
	else if (window.ActiveXObject) //stupid IE
	{
		try
		{
			ret = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e)
		{
			try
			{
				ret = new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch (e)
			{
				ret = false;
			}
		}
	}

	return (ret ? {req: ret} : ret);
}

function checkresponse(r, t, evt)
{
	if (r.req.readyState == 4)
	{
		var newe = document.createElement("div");

		newe.innerHTML = r.req.responseText;
		newe.style.position = "absolute";
		newe.origin = r.origin;
		newe.className = "pop";

		var types = {
			item: "620px",
			set: "230px",
			player: "550px"
		};
		newe.style.width = types[t];
		newe.style.zIndex = zi++;
		newe.style.visibility = "hidden";
		newe.style.overflow = "hidden";
		document.body.appendChild(newe);
		r.origin.infobox = newe;

		setposition(r.origin, newe, evt);

		newe.animate = {
			targetwidth: newe.offsetWidth,
			targetheight: newe.offsetHeight
		};
		newe.style.width = "0";
		newe.style.height = "0";
		newe.style.visibility = "";
		newe.style.zIndex = zi++;
		animate(newe);
	}
}

function setposition(origin, dialog, evt)
{
	var fakeorigin = {
		offsetTop: origin.offsetTop,
		offsetLeft: origin.offsetLeft,
		offsetHeight: origin.offsetHeight,
		offsetWidth: origin.offsetWidth
	};

	var par = origin;
	do
	{
		if (par.id == "chatouter" || par.className == "pop" || par.className == "hasbar" || (par.className != null && par.className.match(/\btavernbox\b/)) || par.id == "userlist")
		{
			fakeorigin.offsetTop += par.offsetTop;
			fakeorigin.offsetLeft += par.offsetLeft;
			if (evt && par.id == "chatouter")
			{
				fakeorigin.offsetTop = evt.pageY || (evt.clientY + dims.page.scrolltop());
				fakeorigin.offsetLeft = evt.pageX || (evt.clientX + dims.page.scrollleft());
				fakeorigin.offsetHeight = 0;
				fakeorigin.offsetWidth = 0;
			}

			if (par.id != "userlist")
			{
				break;
			}
		}
	} while ((par = par.parentNode) != null);

	var topspace = fakeorigin.offsetTop - dims.page.scrolltop();
	var leftspace = fakeorigin.offsetLeft - dims.page.scrollleft();
	var bottomspace = ((dims.page.scrolltop() + dims.page.height()) - fakeorigin.offsetTop);
	var rightspace = ((dims.page.scrollleft() + dims.page.width()) - fakeorigin.offsetLeft);

	if (bottomspace - 52 > dialog.offsetHeight || bottomspace - 52 > topspace - 32)
	{
		var extra = Math.max(dialog.offsetHeight - bottomspace + 52, 0);
		if (fakeorigin.offsetTop - extra <= 32)
		{
			dialog.style.top = "32px";
		}
		else
		{
			dialog.style.top = (fakeorigin.offsetTop - extra) + "px";
		}
	}
	else
	{
		var ie6hack = (document.all && !window.opera && typeof(XMLHttpRequest) == "undefined" ? 0 : dims.page.scrolltop());
		if ((fakeorigin.offsetTop + fakeorigin.offsetHeight) - dialog.offsetHeight < dims.page.scrolltop() + 32)
		{
			dialog.style.bottom = (bottomspace - (dialog.offsetHeight - topspace + 32)) - ie6hack + "px";
		}
		else
		{
			dialog.style.bottom = bottomspace - ie6hack + "px";
		}
	}

	if (rightspace > dialog.offsetWidth + 50 || rightspace > leftspace)
	{
		if (dims.page.width() - (leftspace + dialog.offsetWidth) <= 50)
		{
			dialog.style.left = dims.page.width() - (50 + dialog.offsetWidth) + "px";
		}
		else
		{
			dialog.style.left = fakeorigin.offsetLeft + "px";
		}
	}
	else
	{
		if (dims.page.width() - (rightspace + dialog.offsetWidth) <= 130)
		{
			dialog.style.right = dims.page.width() - (130 + dialog.offsetWidth) + "px";
		}
		else
		{
			dialog.style.right = rightspace + "px";
		}
	}
}

function sendrequest(e, evt)
{
	stopevent(evt);

	if (typeof(e.req) != "undefined" && e.req != null)
	{
		e.infobox.style.zIndex = zi++;
		document.documentElement.scrollTop = e.infobox.offsetTop - 32;
		document.body.scrollTop = e.infobox.offsetTop - 32;
		return false;
	}

	var url = e.href.replace(/^(?:.+?\/)?([^\/]+)$/, "$1");
	var type = url.replace(/^(item|set|player)\.php.+$/, "$1");

	var request;
	if (request = getxmlrequest())
	{
		e.req = request;
		request.origin = e;

		//ie7 hack, the event properties go null in the ajax handler otherwise
		var evtcopy = {
			clientX: evt.clientX,
			clientY: evt.clientY,
			srcElement: evt.srcElement,
			target: evt.target
		};

		request.req.open("GET", url + "&d=1", true);
		request.req.onreadystatechange = function () { checkresponse(request, type, evtcopy) };
		request.req.send(null);
	}
	else
	{
		var sizes = {
			item: "600",
			set: "300",
			player: "500"
		};

		window.open(url, 'itemwindow', 'width=' + sizes[type] + ', height=350');
	}

	return false;
}

function hidedesc(e, cl)
{
	var re = new RegExp("\\b" + cl + "\\b");
	while (typeof(e.className) == "undefined" || !e.className.match(re))
	{
		e = e.parentNode;
	}

	if (typeof(e.animate) != "undefined" && e.animate.timer != null)
	{
		clearTimeout(e.animate.timer);
	}

	e.animate = {
		targetwidth: 0,
		targetheight: 0,
		endfunc: function ()
		{
			e.animate.timer = null;
			e.origin.dialog = null;
			e.origin.req = null;
			e.parentNode.removeChild(e);
		}
	};

	animate(e);
}

function togglechat(elem)
{
	var e = document.getElementById(elem);
	if (typeof(togglechat.maxw) == "undefined")
	{
		var copy = e.cloneNode(true);
		e.style.width = "";
		e.style.height = "";

		togglechat.maxw = e.clientWidth;
		togglechat.maxh = e.clientHeight;

		e.style.width = copy.style.width;
		e.style.height = copy.style.height;
	}

	if (typeof(e.animate) != "undefined" && e.animate.timer != null)
	{
		clearTimeout(e.animate.timer);
	}

	e.animate = {
		targetwidth: 0,
		targetheight: 0,
		endfunc: function ()
		{
			e.animate.timer = null;
			setchatstate(e);
		}
	};

	if (e.offsetWidth != togglechat.maxw)
	{
		e.animate.targetwidth = togglechat.maxw;
		e.animate.targetheight = togglechat.maxh;
	}

	animate(e);
}

function togglesectionv(elem, type)
{
	var e = sel(elem.parentNode.parentNode, "div.content > div");
	var ul = sel(e, "ul");

	var c = 0;
	for (var i = 0; i < e.parentNode.childNodes.length; i++)
	{
		var tmp = e.parentNode.childNodes[i];
		if (tmp.nodeName == "DIV")
		{
			c++;
		}
	}

	if (c != 1)
	{
		return;
	}

	if (typeof(ul.naturalheight) == "undefined")
	{
		ul.naturalheight = ul.offsetHeight;
	}

	var original = e;
	e = original.cloneNode(true);
	original.style.display = "none";
	original.parentNode.appendChild(e);

	e.animate = {
		targetwidth: e.offsetWidth,
		targetheight: 0,
		endfunc: function()
		{
			e.animate.timer = null;

			original.style.height = e.style.height;
			original.style.display = "";
			if (original.style.height != "0px")
			{
				original.className += " open";
				original.style.height = "";
			}
			else
			{
				original.className = e.className.replace(/ open$/, "");
			}
			e.parentNode.removeChild(e);

			if (document.all)
			{
				var el = original.parentNode.parentNode.parentNode.parentNode;
				el.innerHTML = el.innerHTML;
			}
		}
	};

	var newstate = 0;
	if (e.offsetHeight == 0)
	{
		e.animate.targetheight = ul.naturalheight;
		newstate = 1;
	}

	var request;
	if (request = getxmlrequest())
	{
		var group = elem.parentNode.parentNode.id.replace(/^g_/, "");
		if (group == "")
		{
			group = type;
			type = "bh";
		}
		request.req.open("GET", "ajax.php?p=" + pid + "&s=" + newstate + "&g=" + group + "&y=" + type + "&r=" + Math.random(), true);
		request.req.send(null);
	}

	animate(e);
}

function setchatstate(e)
{
	var request;
	if (request = getxmlrequest())
	{
		var chatting = (e.offsetWidth == 0 ? 0 : 1)
		if (chatting)
		{
			msgcount = 0;
			othercount = 0;
			snapwindow();
		}
		request.req.open("GET", "ajax.php?p=" + pid + "&a=" + chatting + "&y=c&r=" + Math.random(), true);
		request.req.send(null);
	}
}

function alerthc()
{
	var e = document.getElementById("hardcore");
	if (e.checked == true)
	{
		if (!confirm("You have selected *hardcore* mode!\n\nIf you die while playing in hardcore mode, you cannot be revived!\n\nAre you sure you want to select hardcore mode?"))
		{
			e.blur();
			e.checked = false;
		}
	}
}

var timer = 0;
function sendtext(p, elem)
{
	var text = "";
	if (elem != "")
	{
		if (timer != 0)
		{
			clearTimeout(timer);
			timer = 0;
		}
		var e = document.getElementById(elem);
		text = e.value;
		e.value = "";
	}
	var request;
	if (request = getxmlrequest())
	{
		request.req.open("POST", "chat.php", true);
		request.req.onreadystatechange = function () { snagtext(request); };
		request.req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		var str = "p=" + p + (elem != "" ? "&c=" + encodeURIComponent(text) : "");
		request.req.send(str);
	}
	else
	{
		alert("Your browser lacks the capabilities to use this feature, please upgrade to a newer version, or try another browser such as Firefox.");
	}
}

function parsetimestamp(elem)
{
	var regs = /\bt-(\d+)$/.exec(elem.className);
	if (regs != null)
	{
		elem.timestamp = parseInt(regs[1], 10);
		elem.className = elem.className.replace(/ t-\d+$/, "");
	}
}

function snagtext(request)
{
	if (request.req.readyState == 4)
	{
		var e = document.getElementById("chatbox");
		if (request.req.responseText != null && request.req.responseText.length > 2)
		{
			var doc = document.createElement("div");
			doc.innerHTML = request.req.responseText;
			var reply = sel(doc, "div.tavernresponse");
			if (reply != null && reply.innerHTML.length > 2)
			{
				var line;
				var container = document.getElementById("chatcontainer");
				while ((line = sel(reply, "div")) != null)
				{
					parsetimestamp(line);
					if (container != null && container.offsetWidth == 0)
					{
						switch (line.className)
						{
							case "message":
							case "emote":
							case "death":
								msgcount++;
								break;
							case "joinpart":
								othercount++;
								break;
							default:
								break;
						}
					}
					if (line.className == "joinpart")
					{
						updateuserlist(line);
					}
					e.appendChild(line);
				}
				snapwindow();
				if (timer == 0)
				{
					timer = setTimeout(refresht, 5000);
				}
			}
		}

		try
		{
			request.req.onreadystatechange = null;
			request.req = null;
		}
		catch (ex)
		{
			request.req.onreadystatechange = function () {};
		}
		request = null;

		var now = servertime();
		var msg = e.firstChild;
		if (typeof(snagtext.lastchecked) != "undefined" && snagtext.lastchecked != null)
		{
			msg = snagtext.lastchecked;
		}
		while (msg != null)
		{
			if (msg.nodeName == "DIV" && msg.className.match(/^joinpart/))
			{
				if (msg.timestamp + 120 < now)
				{
					(function (msg)
					{
						msg.animate = {
							targetwidth: msg.offsetWidth,
							targetheight: 0,
							endfunc: function ()
							{
								document.getElementById("chatbox").removeChild(msg);
								othercount--;
								snapwindow();
								msg = null;
							}
						};
						msg.style.overflow = "hidden";
						animate(msg);
					})(msg);
					snagtext.lastchecked = msg.nextSibling;
				}
				else
				{
					snagtext.lastchecked = msg;
					break;
				}
			}
			else
			{
				snagtext.lastchecked = msg;
			}
			msg = msg.nextSibling;
		}
	}
}

function setchatboxhandler()
{
	var chatbox = document.getElementById("chatbox");
	listen(chatbox, "mouseover", handlechatboxmouse);
}

function handlechatboxmouse(evt, target)
{
	target = ascend(target, "div");
	if (target !== null && target.nodeName == "DIV" && target.className.match(/^(message|joinpart|death|emote)/))
	{
		var elem = sel(target, "span.timestamp");
		if (elem == null)
		{
			elem = document.createElement("span");
			elem.className = "timestamp";
			target.appendChild(elem);
		}
		elem.innerHTML = "(" + reltime(servertime() - target.timestamp) + ")";
	}
}

function reltime(seconds)
{
	if (seconds <= 1)
	{
		return "just now";
	}

	var scales = {
		"minute": 60,
		"hour": 60,
		"day": 24
	};

	var scale = "second";
	for (var unit in scales)
	{
		var div = scales[unit];
		if (seconds/div < 1)
		{
			break;
		}
		seconds /= div;
		scale = unit;
	}
	seconds = Math.round(seconds, 0);

	return seconds + " " + scale + (seconds == 1 ? "" : "s") + " ago";
}

function updateuserlist(line)
{
	var userlist = document.getElementById("userlist");
	var regs = /^\*\*\* (.+) has (entered|left) the Tavern$/.exec(line.innerHTML);
	if (regs != null && regs[2] == "entered")
	{
		var newuser = document.createElement("div");
		newuser.className = "nick";
		newuser.innerHTML = regs[1];
		var newusertext = (newuser.innerText || newuser.textContent).toLowerCase();
		var found = false;
		for (var i = 0; i < userlist.childNodes.length; i++)
		{
			var elem = userlist.childNodes[i];
			if (elem.nodeName == "DIV" && elem.className == "nick")
			{
				var tmp = (elem.innerText || elem.textContent).toLowerCase();
				if (newusertext < tmp)
				{
					userlist.insertBefore(newuser, elem);
					found = true;
					break;
				}
			}
		}
		if (!found)
		{
			userlist.appendChild(newuser);
		}
	}
	else if (regs != null && regs[2] == "left")
	{
		var goneuser = regs[1].replace(/<[^>]+>/g, "").toLowerCase();
		for (var i = 0; i < userlist.childNodes.length; i++)
		{
			var elem = userlist.childNodes[i];
			if (elem.nodeName == "DIV" && elem.className == "nick")
			{
				var tmp = (elem.innerText || elem.textContent).toLowerCase();
				if (goneuser == tmp)
				{
					userlist.removeChild(elem);
					break;
				}
			}
		}
	}
}

function setlistusers(e)
{
	var userlist = document.getElementById("userlist");
	userlist.animate = {
		targetwidth: (e.checked ? 120 : 0),
		targetheight: userlist.offsetHeight,
		setopacity: false
	};
	animate(userlist);

	var request;
	if (request = getxmlrequest())
	{
		request.req.open("GET", "ajax.php?p=" + pid + "&a=" + (e.checked ? 1 : 0) + "&y=lu&r=" + Math.random(), true);
		request.req.send(null);
	}
}

function updatehistory()
{
	var chatbox = document.getElementById("chatbox");

	var msg = chatbox.firstChild;
	while (msg != null)
	{
		if (msg.nodeName == "DIV")
		{
			var regs = null;
			if (msg.className.match(/history$/))
			{
				break;
			}
			else
			{
				parsetimestamp(msg);
			}
		}
		msg = msg.nextSibling;
	}
}

var msgcount = 0;
var othercount = 0;
function snapwindow()
{
	if (typeof(snapwindow.title) == "undefined")
	{
		snapwindow.title = document.title;
	}

	document.title = (msgcount + othercount > 0 ? "(" + msgcount + ", " + othercount + ") " : "") + snapwindow.title;
	var count = document.getElementById("chatcount");
	if (count != null)
	{
		count.innerHTML = (msgcount + othercount > 0 ? "(<abbr title=\"The number of unseen messages (regular, /me and death).\">" + msgcount + "</abbr>, <abbr title=\"The number of unseen player entries and exits.\">" + othercount + "</abbr>) " : "&nbsp;");
	}
	if (document.getElementById("autoscroll").checked == true)
	{
		if (document.getElementById("chatcontainer") != null)
		{
			var chatbox = document.getElementById("chatbox");
			chatbox.scrollTop = chatbox.scrollHeight;
		}
		else
		{
			window.location = "#bottom";
			document.getElementById("content").focus();

			document.getElementById("userlist").style.maxHeight = document.getElementById("chatbox").offsetHeight + "px";
		}
	}
}

function refresht()
{
	if (typeof(refresht.doneinit) == "undefined")
	{
		var chat = document.getElementById("chatouter");
		var chatbox = document.getElementById("chatcontainer");
		if (chatbox != null && chatbox.currentStyle && chatbox.currentStyle.position != "fixed")
		{
			window.onscroll = function ()
			{
				var w = 60 + dims.page.scrolltop();
				chat.bottom = w + "px";
				chat.innerHTML = chat.innerHTML;
			};
		}
		refresht.doneinit = true;
	}

	sendtext(pid, "");
	timer = setTimeout(refresht, 5000);
}

function castspellg(pid, zid)
{
	var e = document.getElementById("castspell");
	if (e.value != 0)
	{
		parent.location = "index.php?p=" + pid + "&z=" + zid + "&a=s" + e.value;
	}
}

function zeropad(s)
{
	if (s <= 9)
	{
		return "0" + s;
	}
	else
	{
		return s;
	}
}

function updatetime()
{
	var e = document.getElementById("time");
	if (e != null)
	{
		e.innerHTML = (curtime.getHours() + ":" + zeropad(curtime.getMinutes()) + ":" + zeropad(curtime.getSeconds()));
	}
	curtime.setSeconds(curtime.getSeconds() + 1);

	setTimeout("updatetime()", 1000);
}

function fillidiv(e)
{
	if (typeof(fillidiv.idiv) == "undefined")
	{
		fillidiv.idiv = 1;
	}
	var target = document.getElementById("idiv");
	fillidiv.idiv++;

	var elem = sel(target, "div").cloneNode(true);

	sel(elem, "label").htmlFor = "s" + fillidiv.idiv;
	var dropdown = sel(elem, "select");
	dropdown.id = "s" + fillidiv.idiv;
	dropdown.name = "s" + fillidiv.idiv;
	dropdown.value = 0;
	var quantity = sel(elem, "input");
	quantity.name = "q" + fillidiv.idiv;
	quantity.value = 1;

	target.insertBefore(elem, target.firstChild);
}

function useskillg(pid, zid)
{
	e = document.getElementById("useskill");
	if (e.value != 0)
	{
		parent.location = "index.php?p=" + pid + "&z=" + zid + "&a=k" + e.value;
	}
}

function doraid()
{
	if (document.getElementById("a").value != 0)
	{
		document.getElementById("raidform").submit();
	}
}

function checksure()
{
	e = document.getElementById("pvp");
	f = document.getElementById("pvpsure");
	if (!(e.checked == f.checked && f.checked == true))
	{
		alert("You don't seem to be sure.");
		return false;
	}
}

function reply(pid)
{
	e = document.getElementById("to");

	e.value = pid;
	parent.location = "#msgsend";
	document.getElementById("mcontent").focus();
}

function marketbuy(e, domore)
{
	var request;
	if (request = getxmlrequest())
	{
		var elem = e;
		do
		{
			elem = elem.parentNode;
		} while (elem.nodeName != "LI");

		var iid = e.href.replace(/^.+i=(\d+).*$/, "$1");
		var youhave = e.parentNode.parentNode;
		var external = false;
		if (sel(e.parentNode.parentNode, "a") == null)
		{
			external = true;
		}
		e.parentNode.innerHTML = "<span class=\"fade\">" + e.innerHTML + "</span>";

		request.req.open("GET", "ajax.php" + e.href.replace(/^[^?]+/, "") + "&y=mb", true);
		request.req.onreadystatechange = function ()
		{
			if (request.req.readyState == 4)
			{
				elem.innerHTML = "";

				var doc = document.createElement("div");
				var text = request.req.responseText;
				doc.innerHTML = text;
				document.getElementById("pgold").innerHTML = sel(doc, "span.gold").innerHTML;
				if (external)
				{
					youhave = prev(youhave, "li");
					if (youhave != null)
					{
						var regs = /^You have: (\d+)$/.exec(youhave.innerHTML);
						var quantity = parseInt(regs[1], 10) + parseInt(sel(doc, "span.q").innerHTML, 10);
						youhave.innerHTML = youhave.innerHTML.replace(/\d+$/, quantity);
					}
				}
				if (new String(document.location).match(/z=-7/) && external && youhave != null)
				{
					sel(document.getElementById("s" + iid).parentNode, "span.q").innerHTML = quantity;
				}

				var more = sel(doc, "div.more > ul > li");
				if (more != null && domore)
				{
					var action = document.createElement("div");
					action.className = "action";
					var actionlink = document.createElement("a");
					actionlink.appendChild(document.createTextNode("[ " + sel(doc, "div.moreq").innerHTML + " more ]"));
					if (external)
					{
						var gold = sel(more, "div.right");
						more.removeChild(gold);
						gold = gold.innerHTML.replace(/^([0-9,]+) Gold pieces/, "$1");
						more.removeChild(sel(more, "a"));
						more.innerHTML = more.innerHTML.replace(/\s*\([^)]+\)\s*$/, "");
						more.innerHTML += "Available at the Market for " + gold + " gold.";
					}
					actionlink.more = more;
					actionlink.href = "javascript: void(0);";
					actionlink.onclick = function ()
					{
						var li = actionlink.parentNode.parentNode;
						li.parentNode.replaceChild(actionlink.more, li);

						return false;
					};
					action.appendChild(actionlink);

					elem.appendChild(action);
				}
				var message = document.createElement("span");
				message.innerHTML = sel(doc, "li").innerHTML;
				elem.appendChild(message);
			}
		};
		request.req.send(null);

		return false;
	}

	return true;
}

function forgetprice(e)
{
	var request;
	if (request = getxmlrequest())
	{
		var li = e.parentNode.parentNode;
		e.parentNode.innerHTML = "<span class=\"fade\">" + e.innerHTML + "</span>";
		request.req.open("GET", "ajax.php" + e.href.replace(/^[^?]+/, "") + "&y=fp", true);
		request.req.onreadystatechange = function ()
		{
			if (request.req.readyState == 4)
			{
				li.style.overflow = "hidden";
				li.style.borderTop = "0"; //ie7 hack
				li.animate = {
					targetwidth: li.offsetWidth,
					targetheight: 0,
					endfunc: function ()
					{
						var ul = li.parentNode;
						li.parentNode.removeChild(li);
						if (sel(ul, "li") == null)
						{
							var ulbox = ul.parentNode;
							while (ulbox.className != "clearhack")
							{
								ulbox = ulbox.parentNode;
							}
							removeanimate(ulbox);
						}
					}
				};
				animate(li);
			}
		}
		request.req.send(null);
		
		return false;
	}

	return true;
}

function marketstats(e)
{
	var request;
	if (request = getxmlrequest())
	{
		var newstats = null;

		var oldstats = sel(e.parentNode, "div > div.content");
		oldstats.style.overflow = "hidden";
		oldstats.style.position = "relative"; //ie hack
		oldstats.animate = {
			targetwidth: oldstats.offsetWidth,
			targetheight: 0,
			endfunc: function ()
			{
				if (newstats == null)
				{
					var interval = setInterval(function () { if (newstats != null) { updatemarketstats(newstats); clearInterval(interval); } }, 50);
				}
				else
				{
					updatemarketstats(newstats);
				}
			}
		};
		animate(oldstats);

		request.req.open("GET", "ajax.php?p=" + pid + "&s=" + e.value + "&y=ms&r=" + Math.random(), true);
		request.req.onreadystatechange = function ()
		{
			if (request.req.readyState == 4)
			{
				newstats = request.req.responseText;
			}
		}
		request.req.send(null);
	}
	else
	{
		var loc = new String(parent.location);
		parent.location = loc.replace(/&s=\d+/, "") + "&s=" + e.value;
	}
}

function updatemarketstats(newstats)
{
	var e = document.createElement("div");
	e.innerHTML = newstats;
	e = sel(e, "div#marketstats > div");
	var marketstats = document.getElementById("marketstats");
	marketstats.replaceChild(e, sel(marketstats, "div"));

	var newcontent = sel(e, "div.content");
	var newcontentcopy = newcontent.cloneNode(true);
	var targetheight = newcontent.offsetHeight;
	newcontent.style.height = "0";
	newcontent.style.overflow = "hidden";
	newcontent.style.position = "relative"; //ie hack

	newcontent.animate = {
		targetwidth: newcontent.offsetWidth,
		targetheight: targetheight,
		endfunc: function ()
		{
			newcontent.style.overflow = "";
			newcontent.parentNode.replaceChild(newcontentcopy, newcontent);
		}
	};
	animate(newcontent);
}

function sel(context, expr)
{
	if (context === null)
	{
		return null;
	}

	var elems = expr.split(">");

	var nodes = [];
	for (var i = 0; i < elems.length; i++)
	{
		var node = {};
		var tmp = elems[i].split(".");
		if (tmp.length > 1)
		{
			node.matchclassName = tmp[1].trim();
			elems[i] = tmp[0];
		}

		tmp = elems[i].split("#");
		if (tmp.length > 1)
		{
			node.matchid = tmp[1].trim();
			elems[i] = tmp[0];
		}

		node.matchnodeName = elems[i];
		nodes.push(node);
	}

	return _sel(context, nodes);
}

function _sel(context, nodes)
{
	var node = nodes.shift();
	for (var i = 0; i < context.childNodes.length; i++)
	{
		var elem = context.childNodes[i];
		var count = 0;
		var matched = 0;
		//alert(elem.nodeName);
		for (var prop in node)
		{
			if (prop.match(/^match/))
			{
				count++;
				var val = elem[prop.replace(/^match/, "")];
				if (typeof(val) != "undefined" && val.toLowerCase().trim() == node[prop].trim())
				{
					matched++;
				}
				else
				{
					break;
				}
			}
		}

		if (count == matched)
		{
			if (nodes.length == 0)
			{
				return elem;
			}
			else
			{
				var ret = _sel(elem, nodes);
				if (ret != null)
				{
					return ret;
				}
			}
		}
	}

	return null;
}

function stopevent(evt)
{
	if (typeof(evt) != "undefined" && evt != null && evt.stopPropagation)
	{
		evt.stopPropagation();
	}
	else if (window.event)
	{
		window.event.cancelBubble = true;
	}
}

function togglesel(target, evt)
{
	setsel(target, target.checked == true);
	updatecitems();
	stopevent(evt);
}

function setsel(elem, value)
{
	var sid = elem.id;
	var type = itemtypes[sid];
	do
	{
		elem = elem.parentNode;
	} while (elem.nodeName != "LI");

	var before = (itemsels[type] == itemcounts[type]);
	if (value)
	{
		elem.className = elem.className.replace(/ ?(hl)?$/, " hl");
		itemsels[type]++;
	}
	else
	{
		elem.className = elem.className.replace(/ ?hl$/, "");
		itemsels[type]--;
	}
	var after = (itemsels[type] == itemcounts[type]);

	if (before != after)
	{
		do
		{
			elem = elem.parentNode;
		} while (elem.nodeName != "DIV" || !elem.className.match(/\bgamebox\b/));

		sel(elem, "h3 > input").checked = after;
	}
}

function updatecitems()
{
	var selected = [];
	for (var i in itemtypes)
	{
		if (document.getElementById(i).checked)
		{
			selected.push(i);
			if (selected.length == 2)
			{
				break;
			}
		}
	}

	var len = selected.length;
	var citems = document.getElementById("citems");
	if (len == 0)
	{
		citems.className = "fade";
		citems.innerHTML = "(nothing)";
	}
	else if (len == 1)
	{
		citems.className = "";
		citems.innerHTML = iname(selected[0]) + " with itself";
	}
	else if (len == 2)
	{
		citems.className = "";
		citems.innerHTML = iname(selected[0]) + " with " + iname(selected[1]);
	}
}

function iname(sid)
{
	if (typeof(iname.names) == "undefined")
	{
		iname.names = {};
	}

	if (typeof(iname.names[sid]) == "undefined")
	{
		var name = sel(document.getElementById(sid).parentNode, "a").innerHTML;
		iname.names[sid] = name;
		return name;
	}
	else
	{
		return iname.names[sid];
	}
}

function toggleli(elem)
{
	var input = sel(elem, "input");
	input.checked = !input.checked;
	setsel(input, input.checked);
	updatecitems();
}

function togglesection(elem, type)
{
	var value = (elem.checked == true);
	for (var i in items[type])
	{
		var e = document.getElementById(i);
		if (e.checked != value)
		{
			e.checked = value;
			setsel(e, value);
		}
	}
	updatecitems();
}

function multifocus(e)
{
	sel(e.parentNode.parentNode, "input").checked = true;
}

function selall(value)
{
	for (var i in itemtypes)
	{
		var elem = document.getElementById(i);
		if (elem.checked != value)
		{
			elem.checked = value;
			setsel(elem, value);
		}
	}
	updatecitems();
}

function setgift(value)
{
	document.getElementById("gid").value = value;
	window.location = "#giftform";

	return false;
}

function checkemail(e)
{
	var elem = sel(e.parentNode, "input");
	elem.style.display = (e.value == -1 ? "" : "none");
	if (e.value == -1)
	{
		elem.focus();
	}
}

function checkgift(e)
{
	if (!(e.g.value > 0))
	{
		e.g.focus();
		alert("You should pick a gift package first.");
		return false;
	}
	else if (!(e.r.value > 0))
	{
		if (e.r.value == -1)
		{
			if (e.re.value.length < 6)
			{
				e.re.focus();
				alert("You should enter an email address first.");
				return false;
			}
		}
		else
		{
			e.r.focus();
			alert("You should pick a recipient first.");
			return false;
		}
	}

	return true;
}

function showall(e)
{
	var request;
	if (request = getxmlrequest())
	{
		request.req.open("GET", "ajax.php?" + e.href.replace(/^.+\?/, "") + "&y=md&r=" + Math.random(), true);
		request.req.onreadystatechange = function ()
		{
			if (request.req.readyState == 4)
			{
				var doc = document.createElement("div");
				doc.innerHTML = request.req.responseText;
				var ul = sel(doc, "div > div > div > ul");
				if (ul != null)
				{
					var oldul = ascend(e, "ul");
					oldul.parentNode.replaceChild(ul, oldul);
				}
			}
		}
		request.req.send(null);

		return false;
	}

	return true;
}

function ascend(e, type)
{
	type = type.toUpperCase();

	while (e != null && e.nodeName != type)
	{
		e = e.parentNode;
	}

	return e;
}

function next(e, type)
{
	type = type.toUpperCase();

	do
	{
		e = e.nextSibling;
	} while (e != null && e.nodeName != type);

	return e;
}

function prev(e, type)
{
	type = type.toUpperCase();

	do
	{
		e = e.previousSibling;
	} while (e != null && e.nodeName != type);

	return e;
}

function isort(e)
{
	var request;
	if (request = getxmlrequest())
	{
		request.req.open("GET", "ajax.php?p=" + pid + "&s=" + e.value + "&y=is&r=" + Math.random(), true);
		request.req.onreadystatechange = function ()
		{
			if (request.req.readyState == 4)
			{
				var orders = document.createElement("div");
				orders.innerHTML = request.req.responseText;
				var elem;
				while (elem = sel(orders, "div"))
				{
					var sorting = elem.innerHTML.split(/,/);
					var bottom = document.getElementById("s" + sorting[0]).parentNode;
					var ul = bottom.parentNode;
					bottom.parentNode.removeChild(bottom);
					ul.insertBefore(bottom, ul.firstChild);
					for (var i = 1; i < sorting.length; i++)
					{
						var cur = document.getElementById("s" + sorting[i]).parentNode;
						cur.parentNode.removeChild(cur);
						ul.insertBefore(cur, bottom.nextSibling);
						bottom = cur;
					}
					orders.removeChild(elem);
				}
			}
		}
		request.req.send(null);
	}
	else
	{
		this.form.submit();
	}
}

function deletemessage(e)
{
	var request;
	if (request = getxmlrequest())
	{
		request.req.open("GET", "ajax.php?" + e.href.replace(/^.+\?/, "") + "&y=dm&r=" + Math.random(), true);
		request.req.send(null);

		var div = e.parentNode.parentNode;
		removeanimate(div);

		return false;
	}
}

function bankactivity(e)
{
	var request;
	if (request = getxmlrequest())
	{
		var link = e;
		e = e.parentNode;

		var tmp = document.createElement("span");
		tmp.className = "fade";
		tmp.appendChild(document.createTextNode("[ more ]"));
		e.replaceChild(tmp, link);

		request.req.open("GET", "ajax.php?" + link.href.replace(/^.+\?/, "") + "&y=ba&r=" + Math.random(), true);
		request.req.onreadystatechange = function ()
		{
			if (request.req.readyState == 4)
			{
				var oldul = ascend(e, "ul");
				var doc = document.createElement("div");
				doc.innerHTML = request.req.responseText;
				oldul.parentNode.replaceChild(sel(doc, "div > div.content > div > ul"), oldul);
			}
		}
		request.req.send(null);

		return false;
	}
}

function handlefiddle(evt, target)
{
	var container = ascend(target, "div");
	if (target.nodeName == "A" && container != null && container.className.match(/\baction\b/) && !target.href.match(/void\(0\)/))
	{
		var request;
		if (request = getxmlrequest())
		{
			var link = target;

			request.req.open("GET", "ajax.php?" + link.href.replace(/^.+\?/, "") + "&y=fi&r=" + Math.random(), true);
			request.req.onreadystatechange = function ()
			{
				if (request.req.readyState == 4)
				{
					var li = ascend(target, "li");
					var doc = document.createElement("div");
					doc.innerHTML = request.req.responseText;
					var text = sel(doc, "div.text");
					li.style.display = "none";

					var newli = document.createElement("li");
					var okdiv = document.createElement("div");
					okdiv.className = "action";
					var ok = document.createElement("a");
					ok.href = "javascript:void(0);";
					ok.onclick = function ()
					{
						li.style.display = "";
						if (li.parentNode == null)
						{
							removeanimate(newli);
						}
						else
						{
							newli.parentNode.removeChild(newli);
							newli = null;
						}
						li = null;

						return false;
					}
					ok.appendChild(document.createTextNode("[ ok ]"));
					okdiv.appendChild(ok);
					newli.appendChild(okdiv);
					newli.appendChild(document.createTextNode(text.innerText || text.textContent));
					li.parentNode.insertBefore(newli, li);

					var newq = null;
					while ((newq = sel(doc, "div.quantity")) != null)
					{
						var arr = newq.innerHTML.split(/,/);
						var iid = arr[0];
						var q = arr[1];

						var qli = document.getElementById("i" + iid)
						sel(qli, "span.q").innerHTML = q;
						if (q == 0)
						{
							removeanimate(qli);
						}

						doc.removeChild(newq);
					}

					var newitems = sel(doc, "ul.newitems");
					var newitem = null;
					while ((newitem = sel(newitems, "li")) != null)
					{
						var olditem = document.getElementById(newitem.id);
						if (olditem != null)
						{
							olditem.parentNode.replaceChild(newitem, olditem);
						}
						else
						{
							var pos = next(newli, "li");
							while (pos != null && pos.style.display == "none")
							{
								pos = next(pos, "li");
							}
							if (pos == null)
							{
								li.parentNode.appendChild(newitem);
							}
							else
							{
								li.parentNode.insertBefore(newitem, pos);
							}

							(function (newitem)
							{
								newitem.animate = {
									targetwidth: newitem.offsetWidth,
									targetheight: newitem.offsetHeight,
									endfunc: function ()
									{
										newitem.style.height = "";
										newitem.style.overflow = "";
									}
								};
							})(newitem);
							newitem.style.height = "0";
							newitem.style.overflow = "hidden";
							animate(newitem);
						}
						//newitems.removeChild(newitem); //moved, not copied
					}
				}
			}
			request.req.send(null);

			cancelevent(evt);
		}
	}
}

function removeanimate(e)
{
	e.style.overflow = "hidden";
	e.animate = {
		targetwidth: 0,
		targetheight: 0,
		endfunc: function ()
		{
			e.parentNode.removeChild(e);
		}
	};
	animate(e);
}
