



function toggleMenu(el) {
	
	if(Browser.id.OP5 || Browser.id.NS4) return; 
	
	var label = Button.getLabel(el);
	
	
	if(label.isDepressed) {
		if (TreeParams.OPEN_MULTIPLE_MENUS || label.menu.container.activeMenu == label.menu) {
			
			label.menu.closeStart();
			label.menu.container.activeMenu = null;
			
		}
	}
	else{ // push it in.
		
		if(TreeParams.OPEN_MULTIPLE_MENUS || label.menu.container.activeMenu == null ) {
			label.menu.openStart();
			label.menu.container.activeMenu = label.menu;
		}
		else {
			label.menu.container.activeMenu.closeStart();


		// Cue up this menu to the active menu 
			if(!TreeParams.OPEN_WHILE_CLOSING){
			
			 // label may be closing and un-depressed.
				if(label.menu.container.activeMenu != label.menu)
 					label.menu.container.activeMenu.menuInCue = label.menu;
 					
 				else { // trying to re-open active menu before it has closed.
 					label.menu.menuInCue = null;
 					label.menu.openStart();
 				}
 					
			}
			else {
				label.menu.openStart();
				label.menu.container.activeMenu = label.menu;
			}

 		}
	}
}

/** Opens a menu.
 *  Usually called with body onload handler.
 */
function activateMenu(sButtonId){ 
	
	if(!window.toggleMenu || Browser.id.OP5)
		return;
		
	var button = document.getElementById(sButtonId);
	
	if(!button) return;
	
	var parentMenuEl = findAncestorWithClass(button, "menu");
	if(parentMenuEl != null)
		activateMenu(parentMenuEl.id.replace(/Menu$/,""));

	var label = Button.getLabel(getElementsWithClass(button, "*", "buttonlabel")[0]);
	if(!label.isDepressed){
		toggleMenu(label.el);
		label.isDepressed = true;
	}

}

 function InitCounter(num) {
    if (document.images['lo'+num])
      return toggleMenu(document.images['lo'+num].parentNode);       	
}



/** Button mouseover event handler.
 *  Called with onmouseover attribute.
 */
function buttonOver(el){
	
	window.status = el.parentNode.id;
	
	label = Button.getLabel(el);
	if(hasToken(label.el.className, "labelHover"))
		return;
	
	label.el.className += " labelHover";
}

/** Button mouseout event handler.
 */
function buttonOff(label){
	window.status = window.defaultStatus;
	removeClass(label, "labelHover");
}

if(typeof document.getElementsByTagName == "undefined" || Browser.id.OP5)
	buttonOver = buttonOff = function(){};


/** Button constructor to be used privately.
 */
Button = function(el, category){
	
	this.el = el;
	
	this.category = category;
	this.menu = new Menu(document.getElementById(this.category +"Menu"), this);
		
	var icons = el.getElementsByTagName("img");
	this.icon = (icons.length > 0) ?
				icons[0] : null;
	
	this.isIcon = false;
	if(el.tagName.toLowerCase() == "img"){
		this.isIcon = true;
		this.icon = el;
	}
	
	this.isDepressed = false;
};

/**	Returns the label wrapper object. 
 */
Button.getLabel = function(el) {
	
	var buttonEl = findAncestorWithClass(el,"button");
	
	if(Menus[buttonEl.id])
		return Menus[buttonEl.id].ownerButton;
		
	return new Button(el, buttonEl.id);	
};

/**	Sets the label to normal state. Called by toggleButton -> 
 *  closeStart -> menu.openEnd -> setDefaultLabel
 */
Button.prototype.setDefaultLabel = function(){
	if(this.isIcon)
		return void( this.icon.src = TreeParams.CLOSED_MENU_ICON);
	
	removeClass(this.el, "labelHover");
	removeClass(this.el, "labelDown");

	if(this.icon != null)
		this.icon.src = TreeParams.CLOSED_MENU_ICON;
};

/** Menu is a kind of container. 
 *  (constructor to be used privately)
 *
 *  activeMenu may point to a child menu object (never a sibling)
 *  on certain occasions.
 *
 *  menuInCue is only necessary when OPEN_WHILE_CLOSING 
 *  is false. This property links one menu to another, 
 *  so that when the first menu is done closing, 
 *  the second menu can open.
 *
 *  For example, if menu 'China' is open, 
 *  and menu 'Movies' (a closed menu) is clicked,
 *  'Movies' will become the menuInCue. 
 *
 *  It gets tricky when there are more than one menuInCue.
 *  When an activeMenu is closed, its menuInCue may be 
 *  the menu that just got clicked, but if the user has a 
 *  fast click hand, the menuInCue can become a third menu. 
 *  In that case, Menu1.menuInCue -> menu2, menu2.menuInCue 
 *  will reassign menu1.menuInCue to point to menu3.
 *  and menu2 will never open!
 * 
 *  If a fourth menu were clicked before 
 *  menu1 had finished closing, menu4 would become menu1's menuInCue.
 *
 * When OPEN_WHILE_CLOSING is true, things are much easier.
 * The clicked label's menu becomes the active menu right away.
 */
Menu = function(el, label) {
	
	this.ownerButton = label;
	this.id = label.category; // a short-cut reference to this.ownerButton.category.
	this.el = el;
	
	// get the parentMenu or the root. 
	this.container = this.getContainer();
	
	this.items = getChildNodesWithClass(el, "menuNode");
	this.items.unshift(el);
	
	var all = getElementsWithClass(el, "*", "menuNode");
	
	if(all.length == 0) {
		lis = getElementsWithClass(el, "li", "menuNode");
		divs = getElementsWithClass(el, "div", "menuNode");
		all = lis.length > divs.length ? lis : divs;
	}
			
	this.allItems = all;
	this.allItems.unshift(el);
	this.cur = 0;
	
	this._root = null;
	
	this.activeMenu = null;
	this.menuInCue = null;
	Menus[this.id] = this;
};
Menus = {};


/** Menu methods.
 *
 *  openStart starts a menu opening.
 *  closeStart starts a menu closing.
 *
 *  open
 *  close 
 *  
 *  openEnd (open -> openEnd)  Also called by closeStart when a menu must 
 *  stop opening so it can close. This happens if a user rapidly clicks
 * 
 *  closeEnd  (close -> closeEnd) Also called by openStart when a menu must 
 *  stop closing so it can open. This happens if a user rapidly clicks
 *
 * getContainer (returns the parentMenu or the root).
 */
Menu.prototype = {

	openStart : function(){
	
		if(this.opening) return;
	
		if(this.ownerButton.icon != null)
			this.ownerButton.icon.src = TreeParams.OPEN_MENU_ICON;
			
		if(this.closing){ 
			this.closeEnd();
			if(this.itemsToClose){
				this.itemsToOpen = this.itemsToClose.reverse();
				this.cur = this.itemsToClose.length - this.cur;
			}
		}
		else{
			this.cur = 0;
			this.itemsToOpen = new Array();
			
			// if itemsToClose does not exist, the this has not been closed.
			if(this.itemsToClose)
				this.itemsToOpen = this.itemsToClose.reverse();
			
			else 
			    this.itemsToOpen = this.items;
			    
			if(!this.ownerButton.isIcon)
				this.ownerButton.el.className += " labelDown";
		}

		this.closing = false;
		this.opening = true;
			
		// make sure we're not backwards. 
		if(this.itemsToOpen[0] != this.el)
			this.itemsToOpen.reverse();
		this.performActionTimer = setInterval(
									"Menus." + this.id +".open()", 
									TreeParams.TIME_DELAY);
		if(Browser.id.win9x && !Browser.id.NS6)
			this.performActionTimer2 = setInterval(
									"Menus." + this.id +".open()", 
									TreeParams.TIME_DELAY);
					
					
		this.ownerButton.isDepressed = true;
		
	},
	
	closeStart : function() {
		
		if(this.closing) return;
		if(this.opening){
			this.openEnd();
		}
		else {
			this.opening = false;
			this.cur = 0;
			this.itemsToClose = new Array();
			
			for(var i = this.allItems.length-1,counter = 0; i > 0; i--)
			
				if(this.allItems[i].style.display == "block")
					this.itemsToClose[counter++] = this.allItems[i];
		}
		
		this.itemsToClose[this.itemsToClose.length] = this.el;

		this.performActionTimer = setInterval("Menus." + this.id + ".close()", TreeParams.TIME_DELAY);
		if(Browser.id.win9x && !Browser.id.NS6)
			this.performActionTimer2 = setInterval("Menus." + this.id + ".close()", TreeParams.TIME_DELAY);
		this.closing = true;
						
		this.ownerButton.isDepressed = false;
	},

	open : function(){
	
		this.itemsToOpen[this.cur].style.display = "block";
		if(++this.cur == this.itemsToOpen.length)
			this.openEnd();
	},
	
	close : function(){

		this.itemsToClose[this.cur].style.display = "";
		if(++this.cur >= this.itemsToClose.length)
			this.closeEnd();
	},
	
	openEnd : function() {
		
		clearInterval(this.performActionTimer);
		clearInterval(this.performActionTimer2);
		
		this.opening = false;
		this.itemsToClose = this.itemsToOpen.reverse();
		this.cur = this.itemsToOpen.length - this.cur;
		if(!TreeParams.OPEN_MULTIPLE_MENUS && this.container.activeMenu != this)
			this.closeStart();

		this.container.activeMenu = this;

	},
	
	closeEnd : function() {
		
		clearInterval(this.performActionTimer);
		clearInterval(this.performActionTimer2);
		
		this.closing = false;

		if(this.cur >= this.itemsToClose.length)
			this.ownerButton.setDefaultLabel();
		
		if(!TreeParams.OPEN_WHILE_CLOSING 
			&& this.container.activeMenu
			&& this.container.activeMenu.menuInCue != null
			&& this.container.activeMenu.menuInCue != this){

			this.container.activeMenu.menuInCue.openStart();
			if(this.menuInCue)
				this.container.activeMenu = this.menuInCue;
		}
		else {
			// this.container.activeMenu = null;
		}
		this.menuInCue = null;
		if(Browser.id.IE6) 
			setTimeout("repaintFix(document.getElementById('"+this.el.id+"'));", 50);
	},
	
	
	getContainer : function(){
		
	// look for ancestor with class menu.
	// get that element's id minus "Menu"
	
		var parentMenuElement = findAncestorWithClass(this.el,"menu");
		if(parentMenuElement != null){
			pId = parentMenuElement.id.replace(/Menu$/,"");
			if(!Menus[pId])
				return Button.getLabel(getElementsWithClass(document.getElementById(pId), "*", "buttonlabel")[0]).menu;
			return Menus[pId];
		}
		if(!this._root){
			var rt = findAncestorWithClass(this.el, "AnimTree");
			if(!rt)
				rt = document.body;
			if(!rt.id)
				rt.id = "AnimTree_"+ Math.round(Math.random() * 1E5);
								
			if(TreeList[rt.id] != null)
				this._root = TreeList[rt.id];
			else
				this._root = new Tree(rt);
		}
		return this._root;
	}
};


/** Tree is a type of container, like Menu. 
 *  Tree constructor to be used privately.
 */
Tree = function(el) {
	this.el = el;
	this.activeMenu = null;
	this.id = el.id;
	TreeList[this.id] = this;
 };

TreeList = {};

if(document.getElementById && !Browser.id.OP5 && !window.Tree_inited){
	
	document.writeln("<style type='text/css'>",
			"/* <![CDATA[ */\n",
			".menu,.menuNode{display:none;}\n",
			"/* ]]> */",
			"<"+"/style>");
	
	window.Tree_inited = true;
}
