// For fast response, it is recommend to use version 2 or early 
//
// version 3
// nearly reprogram many things. add the layer object so each layer has its own property
//
// version 2, solved for netscape 6 or later
// add var originPosition
// add fly in function for horizontal pulldown menu (see Kooll)
// amend many programing defect
// add fly out idea. But not implement coz of the complication.
//
// version 1.3, solved for netscape 6 or later
// isIE(), isV6Later from browser.js
// solve the problem of movable menu

var NO_FLY_IN = "nfi";
var FROM_LEFT = "fl";
var NO_FLY_OUT = "nfo";
var TO_LEFT = "tl";


// menu name must comform the rule. ie
var maxMenuTotal = 1;
var maxLevelTotal =1;
var mf = "menu"; // menu first name
var mnt = "sub"; // menuNameToken
var allMenuName = new Array(
	mf+"0",
	mf+"1"
);

var originCoord = new Array(true, true, true, true);
var posiShift = new Array(-10, 10, 60, 60); // place at least 2 value if only one menu like (-40, 0), the zero is meanless


var movable = new Array(false, false, false, false); 
/* var movable: menu move with mouse pointer horizontally 
after shown while the mouse pointer is still over the item of Navigation Bar */
var flyIn = new Array(NO_FLY_IN, NO_FLY_IN, NO_FLY_IN, NO_FLY_IN);

var flyInSpeed = new Array(15, 15, 15, 15); // smaller the value, higher the speed.

/*	Very difficult to code
var flyOut = new Array(TO_LEFT, TO_LEFT, NO_FLY_OUT, NO_FLY_OUT);
var flyOutSpeed = new Array(15,15,15,15); // smaller the value, higher the speed.*/


var blurSpeed = 70;	// smaller the value, faster the menu will hide after the mouse out of the menu
var menuLoaded = false;

menuList = new MenuList(0);
var _x = 0;
var _y = 0;

function createMenuList() {
	
	for(i=0 ; i<allMenuName.length ; i++) {

		newMenu = new Menu(allMenuName[i]);

		newMP = new MenuProperties();		
		newMP.originCoord = originCoord[i];
		if(! originCoord[i])
			newMP.posiShift = posiShift[i];
		newMP.movable = movable[i];
		newMP.blurSpeed = blurSpeed[i]
		
		if(flyIn[i] != NO_FLY_IN) {
			newMP.flyIn = flyIn[i];
			newMP.flyInSpeed = flyInSpeed[i];
		}
		
		newMenu.menuProperties = newMP;
		
		/* Very difficult to code
		/*if(flyOut[i] != NO_FLY_OUT) {
			newMP.flyOut = flyOut[i];
			newMP.flyOutSpeed = flyOutSpeed[i];
			flyOutMenuTotal++;
		}*/


		menuList.add(newMenu, null);
	}
	
	<!--startCaptureXYHandler();-->
	
	menuLoaded = true;
}


//============================= MenuProperties ===========================

function MenuProperties() {
	this.originCoord = false;
	this.posiShift = 0;
	this.movable = false;
	this.flyIn = "";
	this.flyInSpeed = 0;
	this.flyOut = "";
	this.flyOutSpeed = 0;
	this.flyInIntvl = null;
	this.flyOutIntvl = null;
	
}

//============================== Menu ======================================
function Menu(name) {
	this.name = name;
	this.theLayer = null;
	this.menuList = null;
	this.parentMenu = null;
	
	this.menuProperties = null;
	this.mouseOverOnParent = false;
	
	this.show = show;
	this.hide = hide;
	this.isShown = isShown;
	this.hasChild = hasChild;
	this.determineToHide = determineToHide;
	this.isMouseOver = isMouseOver;
	this.getLayerInstance = getLayerInstance;
	this.flyInFromLeft = flyInFromLeft;
	this.flyOutToLeft = flyOutToLeft;
}

function show() {
	if (this.theLayer == null)
		this.getLayerInstance();

	if (isIE() || (! isIE() && isV6Later()) ) {
		if ( this.menuProperties.flyIn == FROM_LEFT) {
			this.flyInFromLeft();
		}
		else
			if (! this.menuProperties.originCoord )	{
				if (this.parentMenu == null)
					this.theLayer.style.left = _x + this.menuProperties.posiShift;
				else {
					this.theLayer.style.left = parseInt(this.parentMenu.theLayer.style.left) + parseInt(this.parentMenu.theLayer.style.width);
				}
			}

		this.theLayer.style.visibility = "visible";
	}
	else {
		if (! this.menuProperties.originCoord )	this.theLayer.left = _x + this.menuProperties.posiShift;
		this.theLayer.visibility = "visible";
	}

	if ( ! this.menuProperties.movable)
		document.onmousemove = ""; 
}

function hide() {
	if (this.theLayer == null)
		this.theLayer = getLayerInstance(this.name);

	if (isIE() || (! isIE() && isV6Later()) ) {
		this.theLayer.style.visibility = 'hidden';
	}
	else {
		this.theLayer.visibility = 'hidden';		
		document.releaseEvents(Event.MOUSEMOVE);
	}
	
	clearInterval(this.flyInIntvl);
}

function isShown() {
	if (this.theLayer == null)
		this.getLayerInstance();
	
	if (isIE() || (! isIE() && isV6Later()) ) {
		return this.theLayer.style.visibility == "visible";
	}
	else {
		return this.theLayer.style.visibility == "visible";
	}
}

function hasChild(){
	return this.menuList != null ;
}

function determineToHide() {
	if (! this.mouseOverOnParent) {
		if (! this.isMouseOver() && ! this.hasChild() || 
			! this.isMouseOver() && this.hasChild() && !this.menuList.isAtLeastOneMenuShown())
			this.hide();
	}
}

function isMouseOver() {
	if (this.theLayer == null)
		this.getLayerInstance();
	
	if ( isIE() || (!isIE() && isV6Later()) ){			
		layerWidth = parseInt(this.theLayer.style.width);
		layerHeight = parseInt(this.theLayer.style.height);
		layerTop = parseInt(this.theLayer.style.top);
		layerLeft = parseInt(this.theLayer.style.left);
	}
	else {
		layerWidth = this.theLayer.clip.width;
		layerHeight = this.theLayer.clip.height;
		layerTop = this.theLayer.top;
		layerLeft = this.theLayer.left;			
	}
	
	if ( _x < layerLeft || _x > layerWidth + layerLeft || _y < layerTop || _y > layerHeight + layerTop )
		return false;
	
	return true;	
}

function flyInFromLeft() {
	if (isIE() || isV6Later()) {
		this.theLayer.style.left = 0 - parseInt(this.theLayer.style.width);
		this.flyInIntvl = setInterval("if (parseInt(this.theLayer.style.left) < 0) this.theLayer.style.left = parseInt(this.theLayer.style.left) + 20;", this.flyInSpeed);
	}
}

// Not well. very difficult to code
function flyOutToLeft() {
	code = "";
	for(i=0 ; i < menuBuffer.length; i++)
		if(menuBuffer[i] == null && (isIE() || isV6Later())){
			menuBuffer[i] = this;
			menuString = "menuBuffer[" + i + "]";
			code = "if (parseInt(" + menuString + ".theLayer.style.width) + parseInt(" + 
				menuString + ".theLayer.style.left) > 0)" +
				menuString + ".theLayer.style.left = parseInt(" + 
				menuString + ".theLayer.style.left) - 20; else {" + 
				"clearInterval(" + menuString+ ".flyOutIntvl);" +
				menuString + " = null;}";
			break;
		}

	clearInterval(this.flyInIntvl);
	this.flyOutIntvl = setInterval(code, this.flyOutSpeed);

}

//=========================== end of Menu =============================

//====================== MenuList =========================
function MenuList(level) {
	this.theList = new Array(maxMenuTotal);
	this.currentMenuIndex = -1 ;
	this.level = level;
	this.length = 0;
	this.timer = null;
	this.timerRunning = false;	
	
	this.add = add;
	this.getMenu = getMenu;
	this.setCurrentMenu = setCurrentMenu;
	this.getMenuByIndex = getMenuByIndex;
	this.getMenuIndex = getMenuIndex;
	this.hideAllHigherLevelMenu = hideAllHigherLevelMenu;
	this.getLevel = getLevel;
	this.getParent = getParent;
	this.getCurrentMenu = getCurrentMenu;
	this.getParentIndex = getParentIndex;
	this.hideCurrentMenu = hideCurrentMenu;
	this.setMouseOutOnParent = setMouseOutOnParent;
	this.isAtLeastOneMenuShown = isAtLeastOneMenuShown;
}

function isAtLeastOneMenuShown() {
	for(i=0 ; i < this.length; i++)
		if (this.theList[i].isShown())
			return true;
	return false;
}

function setMouseOutOnParent(menuName) {
	level = getLevel(menuName);
	
	if(level == this.level && this.getMenu(menuName) != null)
		this.getMenu(menuName).mouseOverOnParent = false;
	else {
		if (this.getCurrentMenu(menuName) != null)
			if (this.getCurrentMenu(menuName).hasChild())
				this.getCurrentMenu(menuName).menuList.setMouseOutOnParent(menuName);
	}
}

function getMenuIndex(name) {
	for(i=0; i < this.length ;i++)
		if (this.theList[i].name == name) {
			return i;
	}
}

function hideAllHigherLevelMenu(menuName) {
	
	this.currentMenuIndex = -1;
	clearInterval(this.timer);
	this.timerRunning = false;
	
	for(i=0; i < this.length ;i++) {
		this.theList[i].hide();
		
		if(this.theList[i].hasChild()) {
			cm = this.theList[i].menuList.getCurrentMenu(); 
			if (cm != null)
				this.theList[i].menuList.hideAllHigherLevelMenu(cm.name);
		}
	}
	
	/*else
		for(i=0; i < this.length ;i++)
			if (this.theList[i].hasChild())
				this.theList[i].menuList.hideAllHigherLevelMenu(menuName);*/
}

function setCurrentMenu(name) {
	if (getLevel(name) == this.level) {
//		alert("setC");		

		if ( menuLoaded ) {
			
		
			this.hideAllHigherLevelMenu(name);
			this.currentMenuIndex = this.getMenuIndex(name);
			
			this.getCurrentMenu().mouseOverOnParent = true;
	
			if (! this.timerRunning) {
				timeoutScript = "";
				cm = "";
	
				for(i=0 ; i <= this.level ; i++) {
					cm += "menuList.getCurrentMenu()";
					if (i < this.level) 
						timeoutScript += ("if (" + cm +".hasChild()) if (" + cm + "!= null)");
					cm += ".";
				}
				timeoutScript += (cm + "determineToHide()");
				
				/*if (menuList.getCurrentMenu().hasChild) //1
					if (menuList.getCurrentMenu() != null)
						
						menuList.getCurrentMenu().menuList.getCurrentMenu().determineToHide();
						*/
			
			this.timer = setInterval(timeoutScript , blurSpeed);
			this.timerRunning = true;
		}
		
		this.getCurrentMenu().show();
		}
	}
	else {
		if (this.getCurrentMenu().hasChild())
			this.getCurrentMenu().menuList.setCurrentMenu(name);
	}
}

function hideCurrentMenu() {
	if (this.getCurrentMenu() != null) {
		this.getCurrentMenu().hide();
		this.currentMenuIndex = -1;
	}
}

function getCurrentMenu() {
	if (this.length == 0 || this.currentMenuIndex == -1) {
		//alert("getCur null");
		return null;
	}
	
	//alert("cure not null111 " + this.currentMenuIndex + ".");	
	return this.theList[this.currentMenuIndex];
}


function add(newMenu, parentMenu) {
	level=this.getLevel(newMenu.name);
	
	if(level == this.level) {
		newMenu.level = level;
		newMenu.parentMenu = parentMenu;
		this.theList[this.length] = newMenu;
		this.length++;
	}
	else {
		theParent = this.getParent(newMenu.name);		
		
		if (theParent.menuList == null) 
			theParent.menuList = new MenuList(level);
		
		theParent.menuList.add(newMenu, theParent);	
	}
}

function getMenu(name) {
	for(i=0; i < this.length ;i++)
		if (this.theList[i].name == name) {
			return this.theList[i];
		}
	
	return null;
}


function getMenuByIndex(i) {
	return i >= this.length ? null : this.theList[i];
}

function getParent(menuName) {	
	return this.theList[this.getParentIndex(menuName)]; 
}

function getParentIndex(menuName) {
	tempName = menuName.split(mf)[1];
	childI = parseInt(tempName.split(mnt)[this.level]);
	
	return childI;
}

//===================== end of MenuList ========================

//==================== global function =====================

function getLevel(menuName) {
	level = 0;
	startI = 0;
	
	while( startI < menuName.length && menuName.indexOf(mnt, startI) != -1 ) {
		level++;
		startI = menuName.indexOf(mnt, startI) + mnt.length;
	}
	
	return level;
}

function showMenu(menuName) {
	//menuList.hideCurrentMenu(menuName);
	menuList.setCurrentMenu(menuName);
}

function hideMenu(menuName) {
	alert("this function is deprecated in version 4. Use setMouseOut() instead.");
}

function setMouseOut(menuName) {
	document.onmousemove = hideLayerHandler;
	menuList.setMouseOutOnParent(menuName);
}

function hideLayerHandler(e) {
	if ( isIE() ) {
		_x = event.clientX + document.body.scrollLeft;
		_y = event.clientY + document.body.scrollTop;
	} else {
		_x = e.pageX;
		_y = e.pageY;
	}
}

function startCaptureXYHandler() {
	if ( !isIE() ) 
		document.captureEvents(Event.MOUSEMOVE);
	
	document.onmousemove = captureXYHandler; // use event Handler aim to capture x-coord
}

function captureXYHandler(e) {
	if ( isIE() ) 
		_x = event.x;
	else 
		_x = e.pageX;
}