﻿// Offsets the menu relative to the parent category link.
var menuOffsetLeft = 5, menuOffsetTop = 27;

// The following global variables specify the area of the currently active 
// category for the article drop down menu.  They are set by the showMenu function.
var menuCategoryLeft, menuCategoryRight, menuCategoryTop, menuCategoryBottom;
var menuLeft, menuRight, menuTop, menuBottom;

/*
 * Shows the article drop down menu for the specified category.
 */
function showMenu(category, categoryContainer)
{
	var menu = document.getElementById("menu");
	var data = document.getElementById("menuDataContainer");
	var offsetParent = document.getElementById("countryNavigation");
	var offsetContainer = document.getElementById("navigationContainer");
	
	data.innerHTML = getNextSibling(category).innerHTML;
	
	var menuStyle = (menu.runtimeStyle) ? menu.runtimeStyle : menu.style;
	
	menuCategoryLeft = category.offsetLeft + categoryContainer.offsetLeft + offsetContainer.offsetLeft;
	menuCategoryTop = categoryContainer.offsetTop + offsetParent.offsetTop + offsetContainer.offsetTop;
	menuCategoryRight = menuCategoryLeft + categoryContainer.offsetWidth;
	menuCategoryBottom = menuCategoryTop + categoryContainer.offsetHeight;
	
	menuStyle.left = (menuCategoryLeft + menuOffsetLeft) + "px";
	menuStyle.top = (menuCategoryTop + menuOffsetTop) + "px";
	
	menu.className = "menuContainer menuVisible";
	
	menuLeft = menu.offsetLeft;
	menuRight = menuLeft + menu.offsetWidth;
	menuTop = menu.offsetTop;
	menuBottom = menuTop + menu.offsetHeight;

	addEventHandler(menu, "click", menuClick);
	addEventHandler(document.body, "mousemove", menuMoniter);

	for (var f = 0; f < window.frames.length; f++)
	{
	  var body = window.frames[f].document.body;

	  // it's possible that the document hasn't loaded yet so check for null (occurred in testing)
	  if (body != null)
	    addEventHandler(body, "mousemove", menuMoniter);
  }
}

/*
 * Monitors mouse movement to close the article drop down menu when appropriate.
 */
function menuMoniter(eventObj)
{  
	if (!eventObj)
	  eventObj = event;

	var element = getEventSource(eventObj);
	var doc = getDocument(element);
	var win = getWindow(doc);

	if (win && win != window)
	// mouse is over the body of an inline floating frame
	{
	  hideMenu();
	  return;
	}

	var scrollOffset = getDocumentScrollPosition();

	var x = eventObj.clientX + scrollOffset.x;
	var y = eventObj.clientY + scrollOffset.y;
	
	if (x < menuCategoryLeft || x > menuCategoryRight || y < menuCategoryTop || y > menuCategoryBottom)
		// mouse is outside the bounds of the category link area
	{
		// These variables describe the area between the category link's bottom edge
		// and the menu's top edge.
		var menuVoidLeft = Math.min(menuLeft, menuCategoryLeft);
		var menuVoidRight = menuCategoryRight;
		var menuVoidTop = menuCategoryBottom;
		var menuVoidBottom = menuTop;
		
		if (x < menuVoidLeft || x > menuVoidRight || y < menuVoidTop || y > menuVoidBottom)
			// mouse is outside the bounds of the menu void
		{			
			if (x < menuLeft || x > menuRight || y < menuTop || y > menuBottom)
				// mouse is outside the bounds of the floating menu
			{
				hideMenu();
			}
		}
	}

}

/*
 * Hides the article drop down menu if a hyperlink is clicked.
 */
function menuClick(eventObj)
{
  if (!eventObj)
    eventObj = event;

  var source = getEventSource(eventObj);

  if (source && source.tagName == "A")
    hideMenu();
}

/*
* Hides the article drop down menu.
*/
function hideMenu()
{
	var menu = document.getElementById("menu");
	var data = document.getElementById("menuDataContainer");

	data.innerHTML = "";
	
	menu.className = "menuContainer menuHidden";

	removeEventHandler(menu, "click", menuClick);
	removeEventHandler(document.body, "mousemove", menuMoniter);

	for (var f = 0; f < window.frames.length; f++)
	  removeEventHandler(window.frames[f].document.body, "mousemove", menuMoniter);
}

/*
 * Utility method for fixing nextSibling behavior in Firefox.
 */
function getNextSibling(element)
{
  element = element.nextSibling;
  
  while(element.nodeType != 1)
    element = element.nextSibling;

  return element;
}

/*
 * Adds an event handler for the specified element.
 */
function addEventHandler(element, eventName, callback)
{
  if (element.addEventListener)
    // W3C event model
    element.addEventListener(eventName, callback, false);
  else
    // IE event model
    element.attachEvent("on" + eventName, callback);
}

/*
 * Removes an event handler for the specified element.
 */
function removeEventHandler(element, eventName, callback)
{
	if (element.removeEventListener)
		// W3C event model
	  element.removeEventListener(eventName, callback, false);
  else
	  // IE event model
	  element.detachEvent("on" + eventName, callback);
}

/*
 * Gets the source of an event.
 */
function getEventSource(eventObj)
{
  if (eventObj)
    return (eventObj.srcElement) ? eventObj.srcElement : eventObj.target;
  else
    return null;
}

/*
 * Gets the document object that contains the specified element.
 */
function getDocument(element)
{
  if (element)
    return (element.document) ? element.document : element.ownerDocument;
  else
    return null;
}

/*
 * Gets the window object that contains the specified document.
 */
function getWindow(doc)
{
  if (doc)
    return (doc.parentWindow) ? doc.parentWindow : doc.defaultView;
  else
    return null;
}

/*
 * Gets the x and y coordinates of the browser window's top left corner relative
 * to the scroll offset of the document.
 */
function getDocumentScrollPosition()
{
  var html = document.getElementsByTagName("html")[0];

  return { 
    x: html.scrollLeft + document.body.scrollLeft,
    y: html.scrollTop + document.body.scrollTop
  };
}