// JavaScript Document
var ie = document.all ? true : false;

// Function to get elements by class name for DOM fragment and tag name
function getElementsByClassName(objElement, strTagName, strClassName)
{
	var objCollection = objElement.getElementsByTagName(strTagName);
	var arReturn = [];
	var strClass, arClass, iClass, iCounter;

	for(iCounter=0; iCounter<objCollection.length; iCounter++)
	{
		strClass = objCollection[iCounter].className;
		if (strClass)
		{
			arClass = strClass.split(' ');
			for (iClass=0; iClass<arClass.length; iClass++)
			{
				if (arClass[iClass] == strClassName)
				{
					arReturn.push(objCollection[iCounter]);
					break;
				}
			}
		}
	}

	objCollection = null;
	return (arReturn);
}

function nextObject(n) {
	var n;
	do n = n.nextSibling;
	while (n && n.nodeType != 1);
	return n;
}

function previousObject(n) {
	var n;
	do n = n.previousSibling;
	while (n && n.nodeType != 1);
	return n;
}


function firstObject(n) {
	var childs = n.childNodes;
	var i = 0;
	while ( childs[i] && childs[i].nodeType != 1) {i++;}
	return childs[i];
}

function lastObject(n) {
	var childs = n.childNodes;
	var i = childs.length -1;
	while ( childs[i] && childs[i].nodeType != 1) {i--;}
	return childs[i];
}

// Reset focus items in menu
function resetFocus()
{
	var objMenubar = document.getElementById('menubar');
	var objItems = getElementsByClassName(objMenubar, 'a', 'focused');
	var iCounter;

	for (iCounter=0; iCounter<objItems.length; iCounter++)
	{
		objItems[iCounter].className = objItems[iCounter].className.replace(/\s?focused/g, '');
	}

	objItems = null;
}

// Hide all sub-menus
function hideSubmenus()
{
	var objMenubar = document.getElementById('menubar');
	var objSubmenu = getElementsByClassName(objMenubar, 'ul', 'submenu');
	var iCounter;

	for (iCounter=0; iCounter<objSubmenu.length; iCounter++)
	{
		closeSubmenu(objSubmenu[iCounter]);
	}
	objSubmenu = null;
}

// Open sub menu, and place focus on first item
function revealSubmenu(objElement)
{
	var objInitial;
	var objSubmenu = getSubmenu(objElement);
	//openSubmenu(objSubmenu);
	objSubmenu.className += ' open';
	objSubmenu.setAttribute('aria-expanded', 'true');
		
	objInitial = objSubmenu.getElementsByTagName('a')[0];

	objElement.tabIndex = -1;
	objInitial.tabIndex = 0;
	objInitial.focus();

	// Open potential submenu
	var objSubmenu2 = getSubmenu(objInitial);
	openSubmenu(objSubmenu2);
}

function getSubmenu(objElement) {
	// return the UL object after the A
	return nextObject(objElement);
}

function openSubmenu(objElement) {
	if (objElement && objElement.className.match(/^submenu.*/)) {
		objElement.className += ' open';
		objElement.setAttribute('aria-expanded', 'true');
	}
}

function closeSubmenu(objElement) {
	if (objElement && objElement.className.match(/^submenu.*/)) {
		objElement.className = objElement.className.replace(/\s?open/g, '');
		objElement.setAttribute('aria-expanded', 'false');
	}
}

function isTopMenuItem(objElement) {
	return objElement.className.match(/^top\W/);
}

function getNextMenuItem(objElement) {
	var objTarget = null;
//	if (!isTopMenuItem(objElement)) {
		// Regular tabbing through sub-menu items
		var li = objElement.parentNode;
		if (nextObject(li)) {
			objTarget = nextObject(li).firstChild;
		} else {
			// Make cyclic
			li = firstObject(li.parentNode);
			objTarget = li.firstChild;
		}
//	}
	return objTarget;
}

function getPreviousMenuItem(objElement) {
	var objTarget = null;
//	if (!isTopMenuItem(objElement)) {
		var li = objElement.parentNode;
		if (previousObject(li)) {
			objTarget = previousObject(li).firstChild;
		} else {
			// Make cyclic
			li = lastObject(li.parentNode);
			objTarget = li.firstChild;
		}
//	}
	return objTarget;
}

function hasSubmenu(objElement) {
	var ul = nextObject(objElement);
	return (ul && ul.className.match(/^submenu.*/));
}

function moveMenuItemFocus(objElement, objTarget) {
	objElement.className = objElement.className.replace(/\s?focused/g, '');
	objElement.tabIndex = -1;
	objTarget.tabIndex = 0;
	objTarget.focus();
}

// Function to navigate through the menu items
function navigateMenu(objElement, objEvent)
{
	objEvent = objEvent || window.event;
	var iKey = objEvent.keyCode;
	var objItems, objTarget;

	switch (iKey)
	{
		case 9: // TAB
			// If in a submenu, set focus on the parent
			if (!isTopMenuItem(objElement))
			{
				objElement.tabIndex = -1;
				objElement.parentNode.parentNode.parentNode.firstChild.tabIndex = 0;
			}
			// Hide submenus and remove focus
			hideSubmenus();
			resetFocus();
			break;
		case 37: // Horizontal previous item (LEFT)
			
			if (!isTopMenuItem(objElement) && !isTopMenuItem(objElement.parentNode.parentNode.parentNode.firstChild)) {
				objTarget = objElement.parentNode.parentNode.parentNode.firstChild;
				moveMenuItemFocus(objElement, objTarget);
			} else {
				// If navigating from a submenu, move to the parent item
				if (!isTopMenuItem(objElement))
				{			
					objElement.tabIndex = -1;
					objElement = objElement.parentNode.parentNode;
				}

				objTarget = getPreviousMenuItem(objElement);
		
				resetFocus();
				
				if (isTopMenuItem(objElement))
				{
					// Top-level navigation
					moveMenuItemFocus(objElement, objTarget);
				} else {
					hideSubmenus();
					revealSubmenu(objTarget);
				}
			}
			break;
		case 39: // Horizontal next item (RIGHT)
		
			if (!isTopMenuItem(objElement) && hasSubmenu(objElement)) {
				objTarget = firstObject(getSubmenu(objElement)).firstChild;
				moveMenuItemFocus(objElement, objTarget);

			} else {
				if (!isTopMenuItem(objElement)) { // If navigating from a submenu, 
					// move to the parent item
					objElement.tabIndex = -1;
					objElement = objElement.parentNode.parentNode;
					if (!isTopMenuItem(objElement.parentNode.firstChild)) { // If is sub level 2
						objElement = objElement.parentNode.parentNode;				
					}
				}


				objTarget = getNextMenuItem(objElement);
		
				resetFocus();
			
				if (isTopMenuItem(objElement)) { // Top-level navigation
					moveMenuItemFocus(objElement, objTarget);
				} else {
					hideSubmenus();
					revealSubmenu(objTarget);
				}
			}
			break;
		case 38: // Vertical previous item (UP)
			// Only navigate if at submenu
			if (!isTopMenuItem(objElement))
			{
				// Close potential submenu
				var objSubmenu = getSubmenu(objElement);
				closeSubmenu(objSubmenu);

				objTarget = getPreviousMenuItem(objElement);
				// Open potential submenu
				var objSubmenu = getSubmenu(objTarget);
				openSubmenu(objSubmenu);

				moveMenuItemFocus(objElement, objTarget);

			}
			break;
		case 40: // Vertical next item (DOWN)

			// If top-level and sub-menu not expanded, expand the sub-menu
			if (isTopMenuItem(objElement))
			{
				if (getSubmenu(objElement).getAttribute('aria-expanded') == 'false')
					{
						revealSubmenu(objElement);
						objElement.className += ' focused';
					}
			} else {
				// Close potential submenu
				var objSubmenu = getSubmenu(objElement);
				closeSubmenu(objSubmenu);

				objTarget = getNextMenuItem(objElement)
				// Open potential submenu
				var objSubmenu = getSubmenu(objTarget);
				openSubmenu(objSubmenu);
				
				moveMenuItemFocus(objElement, objTarget);
			}
			break;
		case 27: // Escape
			// Close sub-menus if open
			if (!isTopMenuItem(objElement))
			{
				hideSubmenus();
				resetFocus();
				objTarget = objElement.parentNode.parentNode.parentNode.firstChild;
				moveMenuItemFocus(objElement, objTarget);
			}
			break;
		case 13: // Return
		case 32: // Space
			// Actions that can be activated with space or return would go here
	}

	if (objTarget)
	{
		// Cancel default behaviour if we've set a target to focus on
		if (objEvent.stopPropagation)
		{
			objEvent.stopPropagation();
		}
		if (objEvent.preventDefault)
		{
			objEvent.preventDefault();
		}

		// Cancel behaviour in IE
		try
		{
			objEvent.cancelBubble = true;
			objEvent.returnValue = false;
		}
		catch(err) {}

		return false;
	}
	else
	{
		// If we haven't set a target, let the browser handle the keystroke
		return true;
	}
}

function manageFocus(objElement, objEvent)
{
	objEvent = objEvent || window.event;

	if (objEvent.type == 'focus')
	{
		// Set class to indicate item is focused
		if (objElement.className.length > 0)
		{
			objElement.className += ' focused';
		}
		else
		{
			objElement.className = 'focused';
		}
	}
	else
	{
		// Remove focus, unless from a top-level menu with aria-expanded set to true
		if (isTopMenuItem(objElement))
		{
			if (nextObject(objElement).getAttribute('aria-expanded') == 'false')
			{
				objElement.className = objElement.className.replace(/\s?focused/g, '');
			}
		}
	}
}

// Set ARIA values and basic functionality
function init ()
{
//	var objAria = document.getElementById('aria');
	var objMenubar = document.getElementById('menubar');
	var objSubmenu = getElementsByClassName(objMenubar, 'ul', 'submenu');
	var objItems = objMenubar.getElementsByTagName('a');
	var iCounter;

	objMenubar.setAttribute('role', 'menubar');

//	document.getElementById('content').onmouseover = function() {return unfocusItem();};

	// Assign roles to sub-menus
	for (iCounter=0; iCounter<objSubmenu.length; iCounter++)
	{
		objSubmenu[iCounter].setAttribute('role', 'menu');
//		objSubmenu[iCounter].setAttribute('aria-labelledby', objSubmenu[iCounter].parentNode.getAttribute('id'));
	}

	hideSubmenus();

	// Add behaviour to list items
	for (iCounter=0; iCounter<objItems.length; iCounter++)
	{
		objItems[iCounter].setAttribute('role', 'menuitem');
		objItems[iCounter].tabIndex = -1;
		objItems[iCounter].onkeydown = function(event) {return navigateMenu(this, event);};
		objItems[iCounter].onfocus = function(event) {manageFocus(this, event);};
		objItems[iCounter].onblur = function(event) {manageFocus(this, event);};

		if (isTopMenuItem(objItems[iCounter]))
		{
//			objItems[iCounter].onmouseover = function() {return focusItem(this);};
			objItems[iCounter].setAttribute('aria-haspopup', 'true');
			if (iCounter === 0)
			{
				objItems[iCounter].tabIndex = 0;
			}
		} else if (hasSubmenu(objItems[iCounter]))
		{
			
			objItems[iCounter].className = "arrow";
//			objItems[iCounter].onmouseover = function() {return focusSubMenu(this);};
		}
	}

	objSubmenu = null;
	objItems = null;
}

function connect() {

	var a = arguments;

	return document.addEventListener ?

			a[0].addEventListener(a[1], a[2], a[3] || false):

			a[0].attachEvent ?

				a[0].attachEvent('on' + a[1], a[2]):

				false;

}

connect(window, 'load', function() {init();});
//window.onload = init;

