﻿var menuTimeOutBeforeImgChanged = 100; //ms
var menuTimeOutBeforeRedirect = 100; //ms

// global menu state
var menuReady = false;

var menuObj;

var menuImgs = new Array();
var menuOverImgs = new Array();

var menus = new Array();

function addMenuEventListiner(obj, evt, func) {
	if (obj) {
		if (obj.addEventListener)
			obj.addEventListener(evt, func, false);
		else if (obj.attachEvent)
			obj.attachEvent('on' + evt, func);
	}
}


function addMenuImage(src, id, type) {
	var img = new Image();

	addMenuEventListiner(img, 'load', function(){
		onMenuImageLoaded(id, type)
	});

	switch (type) {
		case 0:
			menuImgs[id] = img;
			break;
		case 1:
			menuOverImgs[id] = img;
			break;
		default:
			alert('Image type is not supported')
	}
	
	img.src = src;
}

function onMenuImageLoaded(id, type) {
	var itemLoaded = (menuImgs[id]) ? ((0 == type) ? true : menuImgs[id].complete) : false;
	var overLoaded = (menuOverImgs[id]) ? ((1 == type) ? true : menuOverImgs[id].complete) : false;
	
	if (itemLoaded && overLoaded) {
		//init element
		InitMenuItems(menus, id);
	}
}


function InitMenuItems(items, id) {
	for (var i = 0; i < items.length; ++i) {
		var item = items[i];
		if (id == item.id)
			//remove span element and create img element instead
			initMenuItem(item, id);

		if (item.menuItems && item.menuItems.length > 0)
			InitMenuItems(item.menuItems, id);
			
	}
}

function initMenuItem(menuItem, id) {
	var anchor = menuItem.anchor;
	if (anchor) {
		removeMenuItemChildNodes(anchor);
		anchor.style.backgroundColor = 'transparent';

		var img = document.createElement('img');
		img.src = menuImgs[id].src;
		img.id = menuItem.elemId;

		addMenuEventListiner(anchor, 'mouseover', function() { return setMenuItemImage(menuItem.elemId, menuItem.id, 1); });

		//addMenuEventListiner(anchor, 'focus', function() { return setMenuItemImage(menuItem.elemId, menuItem.id, 1); });

		addMenuEventListiner(anchor, 'mouseout', function() { return setMenuItemImage(menuItem.elemId, menuItem.id, 0); });
		//addMenuEventListiner(anchor, 'blur', function() { return setMenuItemImage(menuItem.elemId, menuItem.id, 0); });

		if ('' != menuItem.href)
			addMenuEventListiner(anchor, 'click', function() { setMenuItemImage(menuItem.elemId, menuItem.id, 0); menuRedirect(menuItem.href, menuItem.elemId, menuItem.id); return false; });

		anchor.appendChild(img);
	}
}

function menuRedirect(url, imgId, id) {
	setTimeout(function() {
		setMenuItemImage(imgId, id, 1);
		setTimeout(function() {
			window.location.href = url;
		}, menuTimeOutBeforeRedirect);
	}, menuTimeOutBeforeImgChanged);
	return false;
}


function setMenuItemImage(imgId, id, type) {
	if (document.images) {
		var curImg = document.images[imgId];
		if (0 == type) {
			//return to default state
			setDefaultMenuImage(curImg, id);
			return true;
		}
		else if (1 == type) {
			//mouse over or focused state
			setMenuOverImage(curImg, id);
			return true;
		}
	}

	return false;
}




function setDefaultMenuImage(img, id) {
	img.src = menuImgs[id].src;
}


function setMenuOverImage(img, id) {
	//set to default state previeous selected item
	img.src = menuOverImgs[id].src;
}



function removeMenuItemChildNodes(elem) {
	while (elem.childNodes[0]) {
		elem.removeChild(elem.childNodes[0]);
	}
}


function makeMenu() {
	var row = createRow(menuObj);
	for (var i = 0; i < menus.length; ++i) {
		var menuItem = menus[i];
		var cell = createCell(row);
		cell.style.width = menuItem.width;
		var anchor = document.createElement('a');
		if (!menuItem.visible)
			anchor.style.visibility = 'hidden';
		cell.appendChild(anchor);
		if ('' == menuItem.href) {
			anchor.onclick = 'return false';
			anchor.style.cursor = 'default';
		}
		else
			anchor.href = menuItem.href;

		var spn = document.createElement('span');
		spn.appendChild(document.createTextNode(menuItem.text));

		anchor.appendChild(spn);

		menuItem.anchor = anchor;
	}
	createSubMenus();
	menuReady = true;
}

function createSubMenus() {
	for (var i = 0; i < menus.length; ++i) {
		var menuItem = menus[i];
		if (menuItem.menuItems && menuItem.menuItems.length > 0)
			createSubMenu(menuItem);
		else
			addMenuEventListiner(menuItem.anchor, 'mouseover', function() { showMenu(null); });
			
		addMenuEventListiner(menuItem.anchor, 'mouseout', function() { requestHideMenu(); });
	}
}

function createSubMenu(menuItem) {
	
	//alert(document.body.innerHTML);
	var subMenu = document.createElement('div');
	subMenu.className = 'subMenu';
	subMenu.style.visibility = 'hidden';

	//Create sub menus
	for (var i = 0; i < menuItem.menuItems.length; ++i) {
		var item = menuItem.menuItems[i];

		var itemDiv = document.createElement('div');
		if (0 == i)
			itemDiv.className = 'first';

		var itemA = document.createElement('a');
		var itemSpan = document.createElement('span');
		itemSpan.appendChild(document.createTextNode(item.text));
		itemA.appendChild(itemSpan);
		itemDiv.appendChild(itemA);

		item.anchor = itemA;

		subMenu.appendChild(itemDiv);
	}

	//add to DOM
	menuObj.parentNode.appendChild(subMenu);

	//position subMenu
	setSubMenuPosition(subMenu, menuItem.anchor);

	addMenuEventListiner(menuItem.anchor, 'mouseover', function() { showMenu(subMenu) });

	addMenuEventListiner(subMenu, 'mouseover', function() { keepMenu(); });
	addMenuEventListiner(subMenu, 'mouseout', function() { requestHideMenu(); });
}


// set menu position just before displaying it
function setSubMenuPosition(subMenu, baseElem) {
	var left = 0;
	var top = baseElem.offsetHeight;
	while (baseElem && baseElem.id != 'menu') {
		left += baseElem.offsetLeft;
		top += baseElem.offsetTop;

		baseElem = baseElem.offsetParent;
	}
	
	subMenu.style.left = left + 'px';
	subMenu.style.top = top + 'px';
}


function createRow(tbl) {
	if (tbl.insertRow)
		return tbl.insertRow(-1);
	else {
		var row = document.createElement('tr');
		tbl.appendChild(row);
		return row;
	}
}

function createCell(row) {
	if (row.insertCell)
		return row.insertCell(-1);
	else {
		var cell = document.createElement('td');
		row.appendChild(cell);
		return cell;
	}
}

var menuTimer;

var currentSubMenu = null;
var menuVisibilityOffset = 0;

var menuVisibilityStep = 5; // 0 < menuOpacityOffset <= 100
var menuAnimationDelay = 10; //ms
var menuHideDelay = 500; //ms - delay before hide menu

var menuAnimation = false; //true if animation showing, false - otherwise
var menuAnimationDirection; //0 - showing sub menu; 1 - hiding sub Menu;

//function called when menu mouse over event occurs
function showMenu(subMenu) {
	if (menuReady) {

		if (currentSubMenu) { //sub Menu is showed or in animation mode
			if (currentSubMenu != subMenu) //if subMnu is showed but requested another sub menu to show
				hideCurrentSubMenu(true); //hide current sub menu immediatelly
			else {
				keepMenu(); //continue show current subMenu
				return;
			}
		}

		if (subMenu)
			showSubMenu(subMenu); //all sub menu are hided - request to show sub menu
		//else return; //do nothing
	}
}

//function called when menu or submenu mouse out event occurs
function requestHideMenu() {
	if (menuReady) {
		if (currentSubMenu) {
			if (menuAnimation)
				menuAnimationDirection = 1;
			else
				menuTimer = setTimeout(function() { hideCurrentSubMenu(false) }, menuHideDelay);
		}
	}
}

//function called when sub menu mouse over event occurs or when showMenu called for currently showed subMenu
function keepMenu() {
	if (menuReady) {
		if (menuAnimation) { //animation is started
			menuAnimationDirection = 0; //in this case - menu in next animation frame will start (or continue) showing menu
		}
		else //in this case it is possible situation when menu is waiting for hiding
			clearTimeout(menuTimer); //cancel hiding
	}
}

function stopAllTimers() {
	subMenuAnimation = false; //stop show/hide animation calculations
	clearTimeout(menuTimer); //stop waiting for hiding
}

function cancelAll() {
	menuReady = false;
	stopAllTimers();
}

function showSubMenu(subMenu) {
	currentSubMenu = subMenu;

	startMenuAnimation(0);
}

function hideCurrentSubMenu(hideImmediatelly) {
	if (currentSubMenu) {
		if (hideImmediatelly) {
			if (menuAnimation) //animation is started
				menuAnimation = false; //stop animation
			else
				clearTimeout(menuTimer); //stop waiting for hiding

			//hide sub menu
			currentSubMenu.style.visibility = 'hidden';
			currentSubMenu = null;
		}
		else {
			//start hide animation
			startMenuAnimation(1);
		}
	}
}

function startMenuAnimation(direction) {
	if (currentSubMenu) {
		menuAnimation = true; //init animation indicator
		menuAnimationDirection = direction; //init animation direction

		if (0 == direction) {//init before start animation
			menuVisibilityOffset = 0;
			currentSubMenu.style.visibility = 'visible';
			setMenuVisibility();
		}

		//startAnimation
		setTimeout(function() {
			if (menuAnimation) {//manu animaion indicate continue animation
				if (0 == menuAnimationDirection)
					menuVisibilityOffset += menuVisibilityStep;
				else if (1 == menuAnimationDirection)
					menuVisibilityOffset -= menuVisibilityStep;
				else //menuAnimationDirection have wrong value
					return;
				setMenuVisibility();

				if ((menuVisibilityOffset > 0) && (menuVisibilityOffset < 100))
					setTimeout(arguments.callee, menuAnimationDelay);
				else { //menu is showed or hided - cleanup variables and exit from animation loop
					menuAnimation = false;
					if (1 == menuAnimationDirection) {
						currentSubMenu.style.visibility = 'hidden';
						currentSubMenu = null;
					}
				}
			}
		}, menuAnimationDelay);
		
	}
}

function setMenuVisibility() {
	menuVisibilityOffset = (menuVisibilityOffset > 100) ? 100 :
				(menuVisibilityOffset < 0) ? 0 : menuVisibilityOffset;

	if (currentSubMenu) {
		if (currentSubMenu.filters) {
			if (menuVisibilityOffset > 75) {
				currentSubMenu.style.filter = '';
			}
			else
				currentSubMenu.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + menuVisibilityOffset + ')';
		}
		else {
			currentSubMenu.style.opacity = menuVisibilityOffset / 100;
		}
	}
}

/*

var menuTimer;
var menuAnimationTimer;

var currentSubMenu = null;
var subMenuVisibilityOffset = 0;

var menuOpacityOffset = 20; // 0 < menuOpacityOffset <= 100
var menuAnimationDelay = 1000;//ms
//show hide functions
function showMenu(subMenu) {
if (menuReady) {
//stop show/hide timer
cancelHide();
		
//hide current active menu if necessary
if (currentSubMenu && (subMenu != currentSubMenu))
hideCurrentSubMenu(true);
else
cancelShowAnimation();

//show new subMenu
if (subMenu) {
animateSubMenu(subMenu, true);
}
}
}


function requestHideMenu() {
menuTimer = setTimeout(hideCurrentSubMenu, hide_delay);
}

function cancelHide() {
clearTimeout(menuTimer);
}

function cancelShowAnimation() {
clearTimeout(menuAnimationTimer);
}


function hideCurrentSubMenu(hideImediatelly) {
if (menuReady && currentSubMenu) {
cancelShowAnimation();
if (hideImediatelly == true) {
currentSubMenu.style.visibility = 'hidden';
setSubMenuVisibilityOffset(0);
currentSubMenu = null;
}
else {
//alert(hideImediatelly);
animateSubMenu(currentSubMenu, false);
}
}
}

function cancelAll() {
menuReady = false;
cancelHide();
cancelShowAnimation();
}

//animation functions

function animateSubMenu(subMenu, isShow) {
if (isShow) {
currentSubMenu = subMenu;
setSubMenuVisibilityOffset(subMenuVisibilityOffset);
subMenu.style.visibility = 'visible';
}
menuAnimationTimer = setTimeout(function() {
var offset = (isShow) ? subMenuVisibilityOffset + menuOpacityOffset : subMenuVisibilityOffset - menuOpacityOffset;
setSubMenuVisibilityOffset(offset);
tmpStr += ' ' + currentSubMenu.style.filter + ';';// +subMenu.style.visibility + ' ' + isShow + ' ' + subMenuVisibilityOffset.toString() + ';';
if ((subMenuVisibilityOffset > 0) && (subMenuVisibilityOffset < 100))
menuAnimationTimer = setTimeout(arguments.callee, menuAnimationDelay);
else if (!isShow) {
currentSubMenu.style.visibility = 'hidden';
currentSubMenu = null;
//alert(tmpStr);
tmpStr = '';
}
}, 0);
}

var tmpStr = '';

function setSubMenuVisibilityOffset(val) {
val = (val < 0) ? 0 : (val > 100) ? 100 : val;
subMenuVisibilityOffset = val;

if (currentSubMenu) {
if (currentSubMenu.filters)
//currentSubMenu.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + subMenuVisibilityOffset + ')';
currentSubMenu.style.filter = 'alpha(opacity=' + subMenuVisibilityOffset + ')';
else
currentSubMenu.style.opacity = subMenuVisibilityOffset / 100;
}
}
*/