var enabledebug = false, xraroot = "/site.net/";

var stopevents = true, debug;
function startdebug() {
	if (enabledebug) {
		debug = open(xraroot+"XRA/admin/debug.htm", "xradebug");
	} else {
		debug = new Object();
		debug.log = function() {};
		debug.logln = function() {};
		debug.unindent = function() {};
		debug.flog = function() {};
		debug.flogln = function() {};
		debug.funindent = function() {};
		debug.lclear = function() {};
	}
	stopevents = enabledebug;
}

function debugEl(tit, el) {
	if (el) {
		debug.logln(tit+" "+el.nodeName, 1);
			debug.logln(el.id+"/"+el.className);
			debug.logln(el.offsetLeft+"/"+el.offsetTop);
			debug.logln(
				el.outerHTML
					.replace(/<([A-Z]+)[^>]*>/g, "<$1>")
					.replace(/</g, "&lt;")
					.replace(/>[\t\n\r]*</g, ""));
		debug.unindent();
	} else {
		debug.logln(tit+" "+el);
	}
}


function doload() {
	startdebug();
	if (typeof(xra_log) != "undefined") {
		/* not really relevant, and causes some flickering
		document.body.innerHTML += "<div id=xra_log>#LOADED "+new Date()+"</div>";
		*/
	}
	if (typeof(startedit) == "function") {
		startedit();
	}
}

function doevent(fn, el) {
	var ret = true;
	if (enabledebug && fn == "dodblclick" && el.nodeName == "BODY") {
		stopevents = !stopevents;
		if (!stopevents) debug.lclear();
		debug.flogln("toggle events: stopevents="+stopevents);
	}
	if (stopevents) return ret;
	var f;
	try { eval("f = "+fn); } catch (all) {}
	if (typeof(f) != "function") {
		debug.flogln("unknown "+fn+"("+el.nodeName+")");
	} else {
		debug.flogln("calling "+fn+"("+el.nodeName+")", 1);
		try {
			ret = f(el);
			if (typeof(ret) == "undefined") ret = true;
			debug.funindent();
		} catch (all) {
			debug.flogln("<b>ERROR:</b> "+all.description);
			debug.funindent();
			throw all;
		}
	}
	event.cancelBubble = !ret;
	return ret;
}

function dodblclick(el) {
	return true;
}

function domousedown(el) {
	pushButton(el, true, true);
	return true;
}
function domouseup(el) {
	pushButton(el, false, true);
	return true;
}

var link_bubbling = false;
function doclick(el) {
	enablePopup(el);
	if (el.nodeName == "A") {
		link_bubbling = true;
	} else if (hasClass(el, "xra_node")) {
		return link_bubbling;
	} else if (el.nodeName == "BODY") {
		link_bubbling = false;
		hideElements();
	}
	if (event.altKey) { // && event.ctrlKey
		if (typeof(xra_log) != "undefined") {
			var log = xra_log;
			if (isNaN(xra_log.length)) log = [log];
			var hide = log[0].style.display == "block";
			for (var i=0, sz=log.length; i<sz; i++) {
				log[i].style.display = hide ? "" : "block";
				if (!hide) log[i].scrollIntoView();
			}
		}
		return false;
	}
	return true;
}

function domouseover(el) {
	if (hasClass(el, "xra_node") && (!hasAncestorClass(el, "xra_content") || hasAncestorClass(el, "xra_tools"))) {
		return !showElement(el);
	}
	return el.nodeName == "A"; // if true links do not show in status
}

var lastx = null, lasty = null;
function domousemove(el) {
	if (!popupEnabled()) {
		if (lastx == null) {
			lastx = event.screenX;
			lasty = event.screenY;
		} else {
			if (lastx != event.screenX || lasty != event.screenY) {
				enablePopup(el);
			}
		}
	}
	return true;
}

function domouseout(el) {
	if (hasClass(el, "xra_node")) {
		domousemove(el);
		return tryHideElement(el);
	}
	return true;
}


function hasClass(el, cl) {
	return el && el.className && el.className.indexOf(cl) >= 0;
}

function hasAncestorClass(el, cl) {
	for (el = el.parentNode; el; el = el.parentNode) {
		if (hasClass(el, cl)) return true;
	}
	return false;
}

function firstElement(el) {
	for (; el; el = el.nextSibling) {
		if (el.nodeName.indexOf("#") != 0) return el;
	}
	return null;
}

function isAncestor(pel, el) {
	for (; el; el = el.parentNode) {
		if (pel === el) return true;
	}
	return false;
}

function parentIs(el, nm) {
	return el.parentNode && el.parentNode.nodeName == nm;
}

function singleChild(el) {
	return el.previousSibling == null && el.nextSibling == null;
}

function posElement(el, client) {
	var pel = { left: 0, top: 0, right: 0, bottom: 0 };
	for (var aux=el; aux; aux = aux.offsetParent) {
		pel.left += aux.offsetLeft;
		pel.top += aux.offsetTop;
	}
	if (client) {
		pel.left -= document.body.scrollLeft;
		pel.top -= document.body.scrollTop;
	}
	pel.right = pel.left + el.scrollWidth;
	pel.bottom = pel.top + el.scrollHeight;
	return pel;
}


function hideFrames(el) {
	for (el = el.parentNode.firstChild; el; el = el.nextSibling) {
		if (hasClass(el, "xra_frame")) {
			el.style.display = "";
			if (el.oldw) el.style.width = el.oldw;
			if (el.oldh) el.style.height = el.oldh;
		}
	}
}

function showFrame(el) {
	hideFrames(el);
	document.body.scrollTop = 0;
	document.body.scrollLeft = 0;
	el.style.display = "block";
	resizeTo(el.offsetWidth, el.offsetHeight);
	el.oldw = el.style.width;
	el.style.width = document.body.clientWidth+"px";
	el.oldh = el.style.height;
	el.style.height = document.body.clientHeight+"px";
}


function showElement(el) {
	debug.logln("show", 1);
	hideElements(el);
	var tit = firstElement(el.firstChild);
	var lst = tit ? firstElement(tit.nextSibling) : null;
	if (lst == null && el.popref) lst = document.all[el.popref];
	if (lst && !hasClass(lst, "xra_children")) lst = null;
	//debugEl("el", el); debugEl("tit", tit); debugEl("lst", lst);
	if (!hasClass(lst, "xra_hide") && hiddenElement(lst)) lst = null;
	var ok = tit != null;
	if (ok) {
		doShow({
			"element": el,
			"title": tit,
			"list": lst
		});
	}
	debug.unindent();
	return ok;
}

var popupenabled = false;
function popupEnabled() {
	return popupenabled;
}
function enablePopup(el) {
	if (!popupenabled) {
		popupenabled = true;
		domouseover(el);
	}
}

var visels = [], pendingShow = null, pendingElement = null;
function doShow(el) {
	if (el) {
		abortShow();
		markElement(el.title, true);
		pendingElement = el;
		if (popupEnabled()) {
			if (hasClass(el.element, "xra_hide")) {
				doShow();
			} else {
				pendingShow = setTimeout(doShow, 750);
			}
		}
	} else {
		el = pendingElement;
		pendingShow = null;
		pendingElement = null;
		popupElement(el.list, true, el.title);
		visels[visels.length] = el;
	}
}

function abortShow(el) {
	if (pendingShow == null) return false;
	if (typeof(el) == "undefined") el = null;
	if (el == null || el == pendingElement.element) {
		clearTimeout(pendingShow);
		markElement(pendingElement.title, false);
		pendingShow = null;
		pendingElement = null;
		return true;
	}
	return false;
}

function tryHideElement(el) {
	if (abortShow(el)) return true;
	for (var i=0; i<visels.length; i++) {
		var vel = visels[i];
		if (el == vel.element && vel.list == null) {
			visels[i] = null;
			popupElement(vel.list, false);
			markElement(vel.title, false);
			cleanupElements();
			return true;
		}
	}
	return false;
}

function hideElements(el) {
	debug.logln("hide", 1);
	abortShow();
	if (typeof(el) == "undefined") el = null;
	for (var i=visels.length-1; i>=0; i--) {
		var vel = visels[i];
		if (el == null || el.id == "xra_edit" || !isAncestor(vel.element, el)) {
			visels[i] = null;
			popupElement(vel.list, false);
			markElement(vel.title, false);
		}
	}
	cleanupElements();
	debug.unindent();
}

function cleanupElements() {
	var aux = visels; visels = [];
	for (var i in aux) {
		if (aux[i]) visels[visels.length] = aux[i];
	}
}

function markElement(el, mark) {
	if (el && el.parentNode && el.parentNode.id != "xra_edit") {
		if (el.parentNode.id == "xra_edit") return;
		if (mark) {
			if (!pushButton(el.parentNode, true)) {
				el.parentNode.style.backgroundColor = "yellow";
			}
		} else {
			if (!pushButton(el.parentNode, false)) {
				el.parentNode.style.backgroundColor = "";
			}
		}
	}
}

function pushButton(el, push, real) {
	function isButton(el) {
		return el.nodeName == "TD" && hasClass(el, "xra_node") && el.id != "xra_expand";
	}
	function inElement(el) {
		var pel = posElement(el, true);
		return event.clientX >= pel.left && event.clientX < pel.right &&
			event.clientY >= pel.top && event.clientY < pel.bottom
	}
	if (el && el.parentNode && isButton(el)) {
		if (push) {
			if (real) {
				el.setCapture();
				el.style.borderStyle = "inset";
			} else {
				el.style.borderStyle = "outset";
			}
		} else {
			if (real) {
				el.releaseCapture();
				el.style.borderStyle = "outset";
				if (inElement(el)) {
					el = firstElement(el.firstChild);
					if (el && el.nodeName == "SPAN") {
						el = firstElement(el.firstChild);
						if (el && el.nodeName == "A") {
							if (!inElement(el)) el.click();
						}
					}
				}
			} else {
				el.style.borderStyle = "";
			}
		}
		return true;
	}
	return false;
}

function popupElement(el, show, ref) {
	if (el) {
		if (show) {
			// debugEl("show", el);
			var align = ref.parentNode.align ? ref.parentNode.align : "";
			if (parentIs(ref, "TD")) {
				ref = ref.parentNode;
				if (parentIs(ref, "TR") && singleChild(ref)) ref = ref.parentNode;
				if (parentIs(ref, "TABLE") && singleChild(ref)) ref = ref.parentNode;
			}
			var pref = posElement(ref);
			var maxright = document.body.scrollLeft + document.body.clientWidth;
			var maxbottom = document.body.scrollTop + document.body.clientHeight - 2;
			
			var elleft, eltop;
			if (el.popdir == "xra_horizontal") {
				if (align == "right") {
					elleft = pref.left - el.scrollWidth;
					if (elleft < 0) elleft = pref.left + el.scrollWidth;
				} else {
					if ((pref.left+el.scrollWidth) > maxright) {
						elleft = (maxright - el.scrollWidth);
					} else {
						elleft = pref.left;
					}
				}
				eltop = (pref.bottom - 1);
			} else {
				if (el.popdir == "xra_vertical") {
					elleft = align == "right" ? (pref.left-el.scrollWidth) : (pref.right - 1);
					eltop = pref.top;
				} else {
					if (align == "right") {
						elleft = pref.left - el.scrollWidth;
						if (elleft < 0) {
							elleft = ref.offsetLeft + ref.scrollWidth;
						} else {
							elleft = ref.offsetLeft - el.scrollWidth;
						}
					} else {
						elleft = pref.left + ref.scrollWidth;
						if ((elleft+el.scrollWidth) > maxright) {
							elleft = (ref.offsetLeft - el.scrollWidth);
						} else {
							elleft = ref.offsetLeft + ref.scrollWidth;
						}
					}
					eltop = ref.offsetTop;
				}
				var elbottom = top+el.scrollHeight;
				if (elbottom > maxbottom) eltop -= elbottom - maxbottom;
			}
			el.style.left = elleft + "px";
			el.style.top = eltop + "px";
			el.style.visibility = "visible";
		} else {
			// debugEl("hide", vlst);
			el.style.visibility = "hidden";
		}
	}
}

function hiddenElement(el) {
	return el && el.style && el.style.visibility != "visible";
}
