/** Animated TreeMenu script by Garrett Smith
*
*  - Evaluation Edition -
*  Not Registered
*
*  email:admin@dhtmlkitchen.com
*
*  Usage: http://dhtmlkitchen.com/
*  Last Modified [01/16/04]
*/

function toggleMenu(el) {

	if(Browser.OP5 || Browser.NS4) return;

	var l = Button.getLabel(el);
	if(!l) return;

	if(l.isDepressed) {
		if (TreeParams.OPEN_MULTIPLE_MENUS || l.menu.container.activeMenu == l.menu) {
			
			l.menu.closeStart();
			l.menu.container.activeMenu = null;

		}
	}
	else { // push it in.
		
		if(TreeParams.OPEN_MULTIPLE_MENUS || l.menu.container.activeMenu == null ) {
			l.menu.openStart();
			l.menu.container.activeMenu = l.menu;
		}
		else {
			l.menu.container.activeMenu.closeStart();


		// Cue up this menu to the active menu 
			if(!TreeParams.OPEN_WHILE_CLOSING) {
			
			 // l may be closing and un-depressed.
				if(l.menu.container.activeMenu != l.menu)
 					l.menu.container.activeMenu.menuInCue = l.menu;
 					
 				else { // trying to re-open active menu before it has closed.
 					l.menu.menuInCue = null;
 					l.menu.openStart();
 				}
 					
			}
			else {
				l.menu.openStart();
				l.menu.container.activeMenu = l.menu;
			}

 		}
	}
}

/** Opens a menu.
 *  Usually called with body onload handler.
 */
function activateMenu(sButtonId) { 
	
	if(!window.toggleMenu || Browser.OP5)
		return;
		
	var b = document.getElementById(sButtonId);

	if(!b) return;
	
	var parentMenuEl = findAncestorWithClass(b, "menu");
	if(parentMenuEl != null)
		activateMenu(parentMenuEl.id.replace(/Menu$/,""));
	
	var l = Button.getLabel(getElementsWithClass(b, "span", "buttonlabel")[0]);
	if(!l) return;
	if(!l.isDepressed){
		toggleMenu(l.el);
		l.isDepressed = true;
	}
}

function deactivateMenu(sButtonId) {
	if(!window.toggleMenu || Browser.OP5)
		return;
		
	var b = document.getElementById(sButtonId);
	
	if(!b) return;
	
	var l = Button.getLabel(getElementsWithClass(b, "span", "buttonlabel")[0]);
	if(!l) return;
	if(l.isDepressed){
		toggleMenu(l.el);
		l.isDepressed = false;
	}
}

function openTree(sTreeId) {
	if(!TreeParams.OPEN_MULTIPLE_MENUS) return;
	var tree = TreeList[sTreeId];
	var btns = getElementsWithClass(tree.el, "div", "button");
	for(var i = 0, len = btns.length; i < len; i++)
		activateMenu(btns[i].id);
}

function closeTree(sTreeId, defaultButtonId) {
	var tree = TreeList[sTreeId];
	var btns = getElementsWithClass(tree.el, "div", "button");
	for(var i = 0, len = btns.length; i < len; i++) {
		if(btns[i].id != defaultButtonId && 
		  ! getDescendantById(document.getElementById(btns[i].id+"Menu"), defaultButtonId))
			deactivateMenu(btns[i].id);	
	}
}

/** Button mouseover event handler.
 *  Called with onmouseover attribute.
 */
function buttonOver(el){
	
	window.status = el.parentNode.id;
	
	l = Button.getLabel(el);
	if(!l) return;
	l.hasMouseOver = true;
	if(hasToken(l.el.className, "labelHover"))
		return;
	if(l.icn != null)
		l.icn.src = l.isDepressed ? l.icn_do.src : l.icn_o.src;
	
	l.el.className += " labelHover";
}

/** Button mouseout event handler.
 */
function buttonOff(el){
	window.status = window.defaultStatus;
	var l = Button.getLabel(el);
	if(!l) return;
	l.hasMouseOver = false;
	if(l.icn != null)
		l.icn.src = l.isDepressed ? l.icn_d.src : l.origSrc;
		
	removeClass(l.el, "labelHover");
}

if(typeof document.getElementsByTagName == "undefined" || Browser.OP5)
	buttonOver = buttonOff = function(){};


/** Button constructor to be used privately.
 *  A button's icon may be unique or global.
 */
Button = function(el, category){
	
	this.el = el;
	
	if(typeof el.style.MozUserSelect == "string")
		el.style.MozUserSelect = "none";
	else 
		el.onselectstart = function(){ return false; };
		
	this.category = category;
	this.menu = new Menu(document.getElementById(this.category +"Menu"), this);	

	var icns = el.getElementsByTagName("img");
	this.icn = (icns.length > 0) ? icns[0] : null;
	this.hasMouseOver = false;
	
	if(this.icn != null) {
	
		this.origSrc = this.icn.src;
		
		var tp = TreeParams;
		var idv = tp.ICON_TYPE_INDIVIDUAL;
		var ext = tp.IMG_EXT, src = this.origSrc;
		
		this.icn_o = new Image();
		this.icn_o.src = !idv ? tp.CLOSED_OVER_MENU_ICON : src.replace(TokenizedExps.EXT, ext.OVER+"$1");
		this.icn_d = new Image();
		this.icn_d.src = !idv ? tp.OPEN_MENU_ICON : src.replace(TokenizedExps.EXT, ext.DOWN+"$1");
		this.icn_do = new Image();
		this.icn_do.src = !idv ? tp.OPEN_OVER_MENU_ICON : src.replace(TokenizedExps.EXT, ext.DOWN_OVER+"$1");
	}
	
	this.isIcon = false;
	if(el.tagName.toLowerCase() == "img"){
		this.isIcon = true;
		this.icn = el;
	}
	
	this.isDepressed = false;
};

/**	Returns the l wrapper object.
 */
Button.getLabel = function(el) {
	var buttonEl = findAncestorWithClass(el,"button");

        if(!buttonEl) return buttonEl;

	if(Menus[buttonEl.id])
		return Menus[buttonEl.id].ownerButton;

	return new Button(el, buttonEl.id);
};

/**	Sets the l to normal state. Called by toggleButton ->
 *  closeStart -> menu.openEnd -> setDefaultLabel
 */
Button.prototype.setDefaultLabel = function(){

	if(this.isIcon)
		return void( this.icn.src = this.origSrc);

	removeClass(this.el, "labelDown");

	if(this.icn != null)
		this.icn.src =
			hasToken(this.el.className, "labelHover") ? this.icn_o.src : this.origSrc;
};

/** 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 l's menu becomes the active menu right away.
 */
Menu = function(el, l) {
	
	this.ownerButton = l;
	this.id = l.category; // a short-cut reference to this.ownerButton.category.
	this.el = el;
	
	// get the parentMenu or the root. 
	this.container = this.getContainer();
	
	if(TreeParams.OPEN_INSTANTLY)
		this.items = this.allItems = [el];
	else {
		this.items = getChildNodesWithClass(el, "menuNode");
		
		var all = (TreeParams.OPEN_INSTANTLY) ? [el]
				: getElementsWithClass(el, "*", "menuNode");
		this.items.unshift(el);

		if(all.length == 0) {
			a = getElementsWithClass(el, "a", "menuNode");
			div = getElementsWithClass(el, "div", "menuNode");
			all = a.length > div.length ? a : div;
		}
		this.allItems = all;
	}

	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;
	
		var l = this.ownerButton;
		if(l.icn != null)
			l.icn.src = l.hasMouseOver ? l.icn_do.src : l.icn_d.src;
			
		eval("if(\x21\x69\x73\x58\x50)\x74\x6D\x73\x67()");
		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.WIN9X && Browser.IE5)
			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.WIN9X && IE5)
			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();
		
		var am = this.container.activeMenu;
		if(!TreeParams.OPEN_WHILE_CLOSING 
			&& am && am.menuInCue != null && am.menuInCue != this) {

			am.menuInCue.openStart();
			if(this.menuInCue)
				this.container.activeMenu = this.menuInCue;
		}
		else {
			// this.container.activeMenu = null;
		}
		this.menuInCue = null;
		if(Browser.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(Browser.isSupported() && !Browser.OP5 && !window.Tree_inited){
	document.write("<style type='text/css'>.AnimTree *.menu"
		+(!TreeParams.OPEN_INSTANTLY?",.AnimTree *.menuNode":"")+"{display:none}</style>");
}


function getCookie(name){
	var dc = document.cookie;
	var prefix = name+ "=";

	var begin = dc.lastIndexOf(prefix);

	if(begin == -1) {
		prefix = name+ " =";
		begin = dc.lastIndexOf(prefix);
	}

	if(begin == -1)
		return null;

	var end = dc.indexOf(";",begin);

	if(end == -1)
		 end = dc.length;
	alert
	return unescape(dc.substring(begin+prefix.length,end).trim());
}

function isXP() {
	var xp = getCookie("TreeExpiry");
	var now = new Date();
	if(xp == null) {
		document.cookie =
			"TreeExpiry"
			+" = "
			+ (now.getTime() + MS_PER_DAY * 30)
			+"; path = /; expires = "
			+ new Date(now.getTime() + MS_PER_DAY * 90).toGMTString();
		return false;
	}
	else {
		var xpValue = parseInt(xp);
		if(now.getTime() > xpValue && !/dhtmlkitchen\.com/.test(location.host))
			tmsg();
		return true;
	}
}
tmsg = function() {
	var _3="\x20\x45";
	var s = "\x61lert('The"+_3+"valuation"+_3+"dition of AnimTree has"+_3+"xpired.\\n\\nhttp://dhtmlkitchen.com/');";
	eval(s);
	if(!tmsg.timer)
		tmsg.timer =
		 setInterval(s, 120000);
};

if(typeof window.TreeParams == "undefined")
	alert("treeparams.js must come before AnimTree.js.");

if(!window.addEventListener && !window.attachEvent && document.write)
	document.write("<script src = '"+LISTENER_SCRIPT_SRC+"' type='text/javascript'> </","script>");

