// must call write*Menu() before this
function dmenuInit() {
	if (document.getElementById) {
		newMenu('menu_regions', 'root_regions');
		newMenu('menu_prices', 'root_prices');
		makeSiblings('menu_regions', 'menu_prices');
			newMenu('menu_regions_canada', 'root_regions_canada', 'menu_regions');
			newMenu('menu_regions_unitedstates', 'root_regions_unitedstates', 'menu_regions');
			newMenu('menu_regions_caribbean', 'root_regions_caribbean', 'menu_regions');
			newMenu('menu_regions_oceania', 'root_regions_oceania', 'menu_regions');
			newMenu('menu_regions_europe', 'root_regions_europe', 'menu_regions');
			newMenu('menu_regions_southamerica', 'root_regions_southamerica', 'menu_regions');
			newMenu('menu_regions_centralamerica', 'root_regions_centralamerica', 'menu_regions');
			newMenu('menu_regions_asia', 'root_regions_asia', 'menu_regions');
			newMenu('menu_regions_africa', 'root_regions_africa', 'menu_regions');
	}
}

window.popUpMenuConfig = {
    // number of milliseconds it takes for a menu to disappear once the mouse
    // has left it, unless otherwise specified in newMenu() call.
	defaultVanishDelay:1000
};

function newMenu(menuId, rootId) {
/*	menuId: ID of the element to (dis)appear
	rootId: ID of element whose mouseover event triggers the menu
	parentId: (optional, default NONE) ID of parent menu element
    vanishDelay: (optional, default popUpMenuConfig.defaultVanishDelay) */
	var root = document.getElementById(rootId);
	var menu = document.getElementById(menuId);
    
    // optional vanishDelay arg
    vanishDelay = (arguments.length >= 4)
                  ? arguments[3]
                  : popUpMenuConfig.defaultVanishDelay;

	root.rootInfo = {
		myMenu:menu,
		isMouseOver:false
	};
	menu.menuInfo = {
		myRoot:root,
		isMouseOver:false,
		parent:null,
		pseudoParent:null,
		children:new Array(),
		vanishId:null,
        vanishDelay:vanishDelay
	};

	root.onmouseover = function() {
		rootMouseOver(this);
	}
	root.onmouseout = function() {
		rootMouseOut(this);
	}

	menu.onmouseover = function() {
		menuMouseOver(this);
	}
	menu.onmouseout = function() {
		menuMouseOut(this);
	}

	// If parent was specified, establish relationship
    if ((arguments.length >= 3) && arguments[2]) {
        parentId = arguments[2];
		var parent = document.getElementById(parentId);
		parent.menuInfo.children[parent.menuInfo.children.length] = menu;
		menu.menuInfo.parent = parent;
	}
}

// Arguments should be IDs of desired child menus
function makeSiblings() {
/*	Creates a pseudo-parent object for two or more menu
	elements, meaning the appearance of one causes the
	disappearance of the others. */
	if (!window.pseudoParentMenus) {
		window.pseudoParentMenus = new Array();
	}
	var index = window.pseudoParentMenus.length;
	window.pseudoParentMenus[index] = {children:new Array()};
	var childMenu;
	for (var i = 0; i < arguments.length; i++) {
		childMenu = document.getElementById(arguments[i]);
		window.pseudoParentMenus[index].children[window.pseudoParentMenus[index].children.length] = childMenu;
		childMenu.menuInfo.pseudoParent = window.pseudoParentMenus[index];
	}
}

function mouseIsOut(menu) {
	if (
		menu.menuInfo.isMouseOver ||
		menu.menuInfo.myRoot.rootInfo.isMouseOver
	) {
		return false;
	}

	// recursively check if the mouse is over any child menus
	for (var i = 0; i < menu.menuInfo.children.length; i++) {
		if (!mouseIsOut(menu.menuInfo.children[i])) {
			return false;
		}
	}

	return true;
}

function startVanish(menu) {
	if (mouseIsOut(menu)) {
		var date = new Date();
		var vanishId = String(date.getTime()) + String(Math.round(Math.random()*100));
		menu.menuInfo.vanishId = vanishId;
		setTimeout('vanish("' + menu.id + '", ' + vanishId + ');', menu.menuInfo.vanishDelay);
		/*	These variables must be passed literally because they will
			be out of scope once the call to vanish() is evaluated. */

		// recursively pass the vanishing up the menu tree
		if (menu.menuInfo.parent) {
			startVanish(menu.menuInfo.parent);
		}
	}
}

function vanish(menuId, vanishId) {
	var menu = document.getElementById(menuId);
	// for the menu to vanish...
	if (
		(
			(arguments.length == 1) || // ...this must either have been called by hideMenuTree(), or...
			(vanishId == menu.menuInfo.vanishId) // ...the vanishId must still be valid, and...
		) &&
		mouseIsOut(menu) // ...the mouse must be out of the menu which is to vanish
	) {
		menu.style.visibility = 'hidden'; // hide the menu
		if (menu.menuInfo.myRoot.rollout) { // call root's rollout function, if it exists (for image swapping)
			menu.menuInfo.myRoot.rollout();
		}
	}
}

function hideMenusExcept(menuArray, skipId) {
/*	Runs hideMenuTree() on all menus in menuArray
	except one with an ID of skipId. */
	for (var i = 0; i < menuArray.length; i++) {
		if (menuArray[i].id != skipId) {
			hideMenuTree(menuArray[i]);
		}
	}
}

// Hides a menu, its children, their children, their children ... etc.
// Note: this means if you set up a bogus menu structure, it could loop infinitely
function hideMenuTree(menu) {
	vanish(menu.id);
	for (var i = 0; i < menu.menuInfo.children.length; i++) {
		hideMenuTree(menu.menuInfo.children[i]);
	}
}

function rootMouseOver(root) {
	root.rootInfo.isMouseOver = true;
	root.rootInfo.myMenu.style.visibility = 'visible'; // Make the menu visible...
	if (root.rollover) { // call root's rollover function, if it exists (for image swapping)
		root.rollover();
	}

	// ...then hide all the menu's siblings
	if (root.rootInfo.myMenu.menuInfo.parent) { // if the menu has a parent
		hideMenusExcept(root.rootInfo.myMenu.menuInfo.parent.menuInfo.children, root.rootInfo.myMenu.id);
	} else if (root.rootInfo.myMenu.menuInfo.pseudoParent) { // if the menu has a pseudo-parent
		hideMenusExcept(root.rootInfo.myMenu.menuInfo.pseudoParent.children, root.rootInfo.myMenu.id);
	}
}

function rootMouseOut(root) {
	root.rootInfo.isMouseOver = false;
	startVanish(root.rootInfo.myMenu);
}

function menuMouseOver(menu) {
	menu.menuInfo.isMouseOver = true;
}

function menuMouseOut(menu) {
	menu.menuInfo.isMouseOver = false;
	startVanish(menu);
}
