var menuInitItemHeight = 20;
var menuItemHeight = 25;
var menuLoginFormHeight = 7;

//top.debug = window.open();function log(m){if(!top.debug)top.debug=window.open();top.debug.document.write(m+'<br />');}

Navigation = function (nodeID) {

	var navigation = this;
	var selectedItem = null;
	
	this.rootNode = document.getElementById(nodeID);
	this.state = this.CLOSED;
	
	if(document.all){
		var iframeID = "primary-iframe";
		this.iframe = document.createElement("iframe");
		this.iframe.id=iframeID;
		this.iframe.frameBorder=0;
		this.rootNode.appendChild(this.iframe);	
	}
	
	// behavior
	var closeMenu = function (e) {
		if (e) e.stopPropagation(); else window.event.cancelBubble = true;
		var destination = (e) ? e.relatedTarget : window.event.toElement;
		if(!destination) return;
		if (destination.tagName != "INPUT") // firefox bug ?
			navigation.changeState(navigation.LOSTMOUSE, destination, this.menuitem);
		if (this.menuitem || !navigation.isChild(destination)) removeClass(navigation.selectedItem, "selected");
	}
	var openMenu = function (e) {
		if (e) e.stopPropagation(); else window.event.cancelBubble = true;
		if (navigation.selectedItem) removeClass(navigation.selectedItem, "selected");
		navigation.selectedItem = this;
		if (navigation.selectedItem.menuitem.submenu || navigation.selectedItem.id == "nav-my-post") addClass(navigation.selectedItem, "selected");
		var destination = (e) ? e.relatedTarget : window.event.toElement;
		if(!destination) return;
		navigation.changeState(navigation.GOTMOUSE, destination, this.menuitem);
	}
	var openSubMenu = function (e) {
		addClass(this, "selected");
		if (e) e.stopPropagation(); else window.event.cancelBubble = true;
		//adjust manupanel
		var destination = (e) ? e.relatedTarget : window.event.toElement;
		if(!destination) return;
		navigation.changeState(navigation.GOTMOUSE, destination, this.menuitem);
	}
	var closeSubMenu = function (e) {
		removeClass(this, "selected");
		if (e) e.stopPropagation(); else window.event.cancelBubble = true;
		// check 4 lost events
		var destination = (e) ? e.relatedTarget : window.event.toElement;
		if(!destination) return;
		if (!navigation.isChild(destination)) navigation.changeState(navigation.LOSTMOUSE, destination, this.menuitem);
	}
	
	var root = this.rootNode.getElementsByTagName("ul")[0];
	root.onmouseout = closeMenu;
	var lis = root.getElementsByTagName("li");
	
	// shift main panel to the ul
	this.rootNode = root;
	
	for (var i=0; i < lis.length; i++) {
		if (lis[i].parentNode == root) {
			// level 0
			lis[i].onmouseover = openMenu;
			lis[i].menuitem = new Object();
			if (lis[i].getElementsByTagName("li").length > 0) {
				// has submenu
				lis[i].menuitem.submenu = lis[i].getElementsByTagName("ul")[0];
				lis[i].menuitem.height = this.calculateMenuHeight(lis[i].menuitem.submenu);
			}
			else {
				lis[i].menuitem.submenu = null;
				lis[i].menuitem.height = menuInitItemHeight;
				if (lis[i].id == "nav-my-post") lis[i].menuitem.height = 160;
			}
		}
		if (lis[i].parentNode.parentNode.parentNode == root) {
			// level 1
			lis[i].onmouseover = openSubMenu;
			lis[i].onmouseout = closeSubMenu;
			lis[i].menuitem = new Object();
			if (lis[i].getElementsByTagName("li").length > 0) {
				lis[i].menuitem.submenu = lis[i].getElementsByTagName("ul")[0];
				lis[i].menuitem.height =  this.calculateMenuHeight(lis[i].menuitem.submenu);
			}
			else {
				lis[i].menuitem.submenu = null;
				lis[i].menuitem.height = menuInitItemHeight;
			}
		}
	}
	// recalculate the height
	for (var i=0; i < lis.length; i++) {
		if (lis[i].parentNode == root && lis[i].getElementsByTagName("li").length > 0) {
			this.recalculateMenuHeight(lis[i].menuitem);
		}
	}
}
//Event types
Navigation.prototype.GOTMOUSE  = 0;
Navigation.prototype.LOSTMOUSE = 1;

//States
Navigation.prototype.OPEN      = 0;
Navigation.prototype.CLOSED    = 1;
Navigation.prototype.ANIMATING = 2;
Navigation.prototype.HOT       = 3;

Navigation.prototype.changeState = function (eventType, destination, newItem) {
	if (this.isChild(destination) && !newItem) {
		return;//Ignore event bubbling when open, top item events got newItems, so they fall through
	}
	switch (eventType) {
		case this.GOTMOUSE:
			switch (this.state) {
				case this.HOT:
					this.activeItem = newItem;
				break;
				case this.CLOSED:// Menu will open in half a second unless the fuse is put out
					this.fuse = setTimeout(this.method(this.open), 200);
					this.activeItem = newItem;
					this.state = this.HOT;
				break;
				case this.OPEN:// Switch between main categories
					if (newItem != this.activeItem) {
						this.adjust(newItem);
					}
				break;
				case this.ANIMATING:// Stop and animate to new target
					if (newItem != this.activeItem) {
						this.animator.stop();
						this.adjust(newItem);
					}
				break;
			}
		break;
		case this.LOSTMOUSE:
			switch (this.state) {
				case (this.HOT):// Lost the mouse, cancel menu opening
					clearTimeout(this.fuse);
					this.activeItem = null;
					this.state = this.CLOSED;
				break;
				case (this.OPEN):// Close it
					this.close();
				break;
				case this.ANIMATING:// Stop and animate to closed position
					this.animator.stop();
					this.close();
				break;
			}
		break;
	}
}
Navigation.prototype.open = function () {
	this.state = this.ANIMATING;
	this.animator = new Animator(menuInitItemHeight, this.activeItem.height, this.method(this.setHeight), this.method(this.opened));
	this.animator.start();
}
Navigation.prototype.opened = function () {
	this.state = this.OPEN;
	this.animator = null;
}

Navigation.prototype.close = function () {
	this.state = this.ANIMATING;
	this.animator = new Animator(this.currentHeight, menuInitItemHeight, this.method(this.setHeight), this.method(this.closed));
	this.animator.start();
}
Navigation.prototype.closed = function () {
	this.state = this.CLOSED;
	this.activeItem = null;
	this.animator = null;
}
Navigation.prototype.adjust = function (newItem) {
	this.state = this.ANIMATING;
	this.activeItem = newItem;
	this.animator = new Animator(this.currentHeight, this.activeItem.height, this.method(this.setHeight), this.method(this.opened));
	this.animator.start();
}
Navigation.prototype.isChild = function (candidate) {
	while (candidate && candidate != this.rootNode.parentNode) {
		if (candidate == this.rootNode) return true;
		try {
			candidate = candidate.parentNode;
		} catch (c) {return false}
	}
	return false;
}
Navigation.prototype.setHeight = function (x) {
    if(isNaN(x)==false)
    {
	    this.currentHeight = x;
	    var height=(x+16)/10;
	    this.rootNode.style.height = height+"em";
	    if(document.all)
	    {
		    this.iframe.style.height = height+"em";
		    this.iframe.style.marginTop = -height+"em";
		}
	}
}
Navigation.prototype.calculateMenuHeight = function (list) {
	var total = 0;
	var items = list.getElementsByTagName("a");
	for (var i=0; i < items.length; i++) {
		if (items[i].parentNode.parentNode == list)
			total += menuItemHeight;
		else
			total += 0;
	}
	return total+menuItemHeight;
}
Navigation.prototype.recalculateMenuHeight = function (list) {
	var items = list.submenu.getElementsByTagName("li");
	var level1items = 0;
	for (var i=0; i < items.length; i++) {
		if (items[i].parentNode == list.submenu) {
			if ((level1items*menuItemHeight) + items[i].menuitem.height > list.height-menuItemHeight)
				items[i].menuitem.height = (level1items*menuItemHeight) + items[i].menuitem.height;
			else
				items[i].menuitem.height = list.height;
			level1items += 1;
		}
	}
}
Navigation.prototype.destroy = function() {
	this.rootNode.onmouseout=null;
	var lis = this.rootNode.getElementsByTagName("li");
	for (var i = 0; i < lis.length; i++) {
		lis[i].onmouseover = lis[i].onmouseout = null;
	}
}
