

function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
		return [curleft,curtop];
	}
}


//adds an event listener to an event
function addEventListenerjj( element, event_name, observer, capturing ) {
	if ( element.addEventListener ) // the DOM2, W3C way  
		element.addEventListener( event_name, observer, capturing );
	else if ( element.attachEvent ) // the IE way  
		element.attachEvent( "on" + event_name, observer );
}

//compares 2 nodes
function nodeEquals(node1, node2) {
	if (node1.offsetLeft == node2.offsetLeft
		&& node1.offsetTop == node2.offsetTop
		&& node1.offsetHeight == node2.offsetHeight
		&& node1.offsetWidth == node2.offsetWidth
		&& node1.innerHTML == node2.innerHTML) {
		return true;
	}
	return false;
}

function isChild(parent, child) {
	if (parent.hasChildNodes()) {
		for (var i = 0; i < parent.childNodes.length; ++i) {
			if (nodeEquals(parent.childNodes[i], child)) {
				return true;
			} else if (isChild(parent.childNodes[i], child)) {
				return true;
			}
		}
	}
	return false;
}

function Menu(root, elementtype, classname) {
	this.root = root;
	this.classname = classname;
	this.elementtype = elementtype;
	
	function close_menu(e) {
		e = (e) ? e : window.event;
		var newSource = (e.relatedTarget) ? e.relatedTarget : e.toElement;
		var el = root.getElementsByTagName(elementtype);
		for (var i = 0; i < el.length; ++i) {
			if (el[i].className.indexOf(classname) != -1) {
				e = el[i];
				break;
			}
		}
		if (!isChild(root, newSource) && !nodeEquals(root, newSource)) {
			_close_menu(e);
		}
	}
	
	function _close_menu(e) {
		if (e.moved) {
			e.moved = false;
			e.style.top = e.$_top;
			e.style.left = e.$_left;
			e.style.right = e.$_right;
			e.style.bottom = e.$_bottom;
			e.$_top = null;
			e.$_bottom = null;
			e.$_left = null;
			e.$_right = null;
		}
	}
	
	function open_menu(e) {
		e = (e) ? e : window.event;
		var source = (e.srcElement) ? e.srcElement : this;
		var el = root.getElementsByTagName(elementtype);
		for (var i = 0; i < el.length; ++i) {
			if (el[i].className.indexOf(classname) != -1) {
				e = el[i];
				break;
			}
		}
		if ((isChild(root, source) || nodeEquals(root, source)) && source.innerHTML.length > 0) {
			_open_menu(e, source);
		}
	}
	
	function _open_menu(e, source) {
		if (e && !e.moved) {
			e.moved = true;
			e.$_top = e.style.top;
			e.$_bottom = e.style.bottom;
			e.$_left = e.style.left;
			e.$_right = e.style.right;
			var pos = findPos(source);
			e.style.top = (source.offsetHeight + pos[1]) + "px";
			e.style.left = (pos[0]) + "px";
			e.style.right = "0px";
			e.style.bottom = "0px";
			var height = 0;
			var width = 0;
			// get height
			for (var i = 0; i < e.childNodes.length; ++i) {
				if (e.childNodes[i].offsetHeight) {
					pos = findPos(e.childNodes[i]);
					height += e.childNodes[i].offsetHeight;
					if (width == 0) {
						width += e.childNodes[i].offsetWidth;
					}
				}
			}
			e.style.height = (height - 3) + "px";
			e.style.width = width + "px";
			// set ul height for ie6.
			if (BrowserDetect.browser == "Explorer" && BrowserDetect.version < 7) {
				var ul = e.getElementsByTagName("UL")[0];
				ul.style.height = ul.offsetHeight + "px";
			}
		}
	}

	function open_menu_focus(e) {
		e = (e) ? e : window.event;
		var source = (e.srcElement) ? e.srcElement : this;
		var el = root.getElementsByTagName(elementtype);
		for (var i = 0; i < el.length; ++i) {
			if (el[i].className.indexOf(classname) != -1) {
				e = el[i];
				break;
			}
		}
		if (isChild(root, source) || nodeEquals(root, source)) {
			_open_menu(e, source);
		} else {
			_close_menu(e);
		}
	}
	
	this.setup = function(root, elementtype) {
		var e = root.getElementsByTagName(elementtype); 
		var a = null;
		addEventListenerjj(root, "mouseover", open_menu, false);
		addEventListenerjj(root, "mouseout", close_menu, false);
		for (i = 0; i < e.length; ++i) {
			if (e[i].className.indexOf(classname) > -1) {
				addEventListenerjj(e[i], "mouseover", open_menu, false);
			}
		}
	};
	this.addEvents = function(start) {
		var a = start.getElementsByTagName("A")
		for(var i = 0; i < a.length; ++i) {
			addEventListenerjj(a[i], "focus", open_menu_focus, false);
		}
	};
	
	this.addEvents(document.body);
	this.setup(root, elementtype);
}
