// The menu data comes in delimited strings. This function converts
// the strings to arrays for easier access.
function preProcessMenuData()
{
    //var now = new Date();
    for (i = 0; i < gMenuLevelCount; i++)
    {
        gMenuItems[i] = gMenuItems[i].split('|');
        var childCount = 0;
        for (j = 0; j < gMenuItems[i].length; j++)
        {
            gMenuItems[i][j] = gMenuItems[i][j].split(';');
            // Make sure number of children is a valid number
            if ((gMenuItems[i][j][2] == null) || (gMenuItems[i][j][2] == ''))
            {
                gMenuItems[i][j][2] = 0;
            }
            // This fourth element is the position in the menu item array
            // where the children of this menu item starts.
            gMenuItems[i][j][4] = childCount;
            childCount += new Number(gMenuItems[i][j][2]);
        }
    }

    gMenuIsPreProcessDone = true;
}

// Opens the url in the specified target
function openLink(url, target)
{
    var oAnchor  = document.createElement('a');
    oAnchor.href = url;
    if (target && (target != null) && (target != '')) 
        oAnchor.target = target;
    document.body.appendChild(oAnchor);
    oAnchor.focus();
    oAnchor.click();
    document.body.removeChild(oAnchor);
}

// Expands links that were compressed to save space.
function expandLink(url)
{
    if (url.substr(0,2) == '$p') url = gAppRoot + 'Templates/Page.aspx' + url.substr(2);
    return url;
}

// Returns the x coordinate of the specified object
function findPosX(obj)
{
    var curleft = 0;
    if (obj.offsetParent)
    {
        while (obj.offsetParent)
        {
            curleft += obj.offsetLeft
            obj = obj.offsetParent;
        }
    }
    else if (obj.x)
    {
        curleft += obj.x;
    }
    return curleft;
}

// Returns the y coordinate of the specified object
function findPosY(obj)
{
    var curtop = 0;
    if (obj.offsetParent)
    {
        while (obj.offsetParent)
        {
            curtop += obj.offsetTop;
            obj = obj.offsetParent;
        }
    }
    else if (obj.y)
    {
        curtop += obj.y;
    }
    return curtop;
}

// Determines the x coordinate of a menu item
function getX(parentMenu, menu)
{
    // Parent pos
    var x = findPosX(parentMenu);
    // Add width of parent
    x += (parentMenu.offsetWidth + 1);

    // Make sure we're not too far to the right
    if ((x + menu.offsetWidth - document.body.scrollLeft) > document.body.clientWidth)
    {
        // Move left by the double width
        x -= (menu.offsetWidth-1) * 2;
        // Make sure we're not too far to the left
        x = (x < document.body.scrollLeft) ? document.body.scrollLeft : x;
    }
    return x;
}

// Determines the y coordinate of a menu item
function getY(parentMenu, menu)
{
    // Parent pos
    var y = findPosY(parentMenu);
    
    // Make sure we're not too far down
    if ((y + menu.offsetHeight - document.body.scrollTop) > document.body.clientHeight)
    {
        // Move menu upwards
        y -= (menu.offsetHeight - parentMenu.offsetHeight);
        
        // If we're too far up we try to align the menu at the bottom
        if (y < document.body.scrollTop)
        {
            y = (document.body.clientHeight + document.body.scrollTop) - menu.offsetHeight;
            
            // If we're still too far up - align at the top
            if (y < document.body.scrollTop)
            {
                y = (y < document.body.scrollTop) ? document.body.scrollTop : y;
            }
        }        
    }
    return y;
}

// Hides all windowed controls so that they are not 
// displayed on top of the menu.
function hideWindowedControls()
{
    // Hide all listboxes
    for (var i = 0; i < document.getElementsByTagName('select').length; i++)
    {
        document.getElementsByTagName('select')[i].style.visibility = 'hidden';
    }
}

// Shows all windowed controls.
function showWindowedControls()
{
    // Show all listboxes
    for (var i = 0; i < document.getElementsByTagName('select').length; i++)
    {
        document.getElementsByTagName('select')[i].style.visibility = 'visible';
    }
}

// Closes a popmenu by removing the div-element from the document.
// Returns true if a menu with the specified id was found.
function closeMenu(menuId)
{
    var isMenuFound = false;
    if (menuId != null)
    {
        var menuDiv = document.getElementById(menuId);
        if (menuDiv) 
        {
            document.body.removeChild(menuDiv);
            isMenuFound = true;
        }
    }
    
    return isMenuFound;
}

// Closes all menus from the specified starting level and up.
function closeMenus(startLevel)
{
    var level = startLevel;
    var menuFound;
    
    do
    {
        menuFound = closeMenu('menulevel' + level++);
    } while (menuFound);
    
    // If we're closing all menus we also need to deactivate the 
    // active item on level 0.
    if (startLevel == 0)
    {
        var menuTopDiv = document.getElementById('TopMenuOuterDiv');
        // TopMenuOuterDiv is a div that contains the top level menu items.
        // So the first menu item is its firstChild.
        if (menuTopDiv && menuTopDiv.firstChild)
        {
            menuTopDiv.firstChild.className = 'topMenuItem';
            deactivateSiblings(menuTopDiv.firstChild, 'topMenuItem');
        }
        
        // Turn previously hidden controls back on again
        showWindowedControls();
    }
    
    // Hide the menu arrow
    hideMenuArrow();
    
    // Reset the close timer
    gMenuTimer = null;
}

// Starts a timer for closing all menus
function startCloseMenuTimer()
{
    if (gMenuTimer == null)
    {
        gMenuTimer = window.setTimeout("closeMenus(0)", 500);
    }
}

// Stops the close men timer
function stopCloseMenuTimer()
{
    if (gMenuTimer != null)
    {
        window.clearTimeout(gMenuTimer);
        gMenuTimer = null;
    }
}

// Deactivates a menu-item
function deactivateMenuItem(menuDiv, level)
{
    // Menu not ready - bail out
    if(!gMenuIsPreProcessDone)
        return;

    menuDiv.className = (level == 0) ? '' : 'topMenuSubItem';
    startCloseMenuTimer();
}

// Deactivates all the siblings to the specified menu-div.
function deactivateSiblings(menuDiv, className)
{
    var div = menuDiv.previousSibling;
    while ((div != null) && (div.className != ''))
    {
        div.className = className;
        div = div.previousSibling;
    }
    
    div = menuDiv.nextSibling;
    while ((div != null)  && (div.className != ''))
    {
        div.className = className;
        div = div.nextSibling;
    }
}

// Hides the menu arrow that points to the current item.
function hideMenuArrow()
{
	var imgArrow = document.getElementById("TopMenuArrowImage");
	if (imgArrow)
	{
		imgArrow.style.display = 'none';
	}
}

// Shows the menu arrow that points to the current item.
function showMenuArrow(x, y)
{
	var imgArrow = document.getElementById("TopMenuArrowImage");
	if (!imgArrow)
	{
		var imgArrow = document.createElement("img");
		imgArrow.id  = 'TopMenuArrowImage';
		imgArrow.src = gAppRoot + 'images/nav_pil.gif';
		imgArrow.style.position = 'absolute';
		document.body.appendChild(imgArrow);
	}
	
	imgArrow.style.display	= 'block';
	imgArrow.style.left		= x + 'px';
	imgArrow.style.top		= y + 'px';
}

// Activates a menu item
function activateMenuItem(menuDiv, childCount, skipChildren, level)
{
    // Menu not ready - bail out
    if(!gMenuIsPreProcessDone)
        return;

    stopCloseMenuTimer();
    // Close all menus from this level and up
    closeMenus(level);
    // Activate this menu item and...
    menuDiv.className = (level == 0) ? '' : 'topMenuSubItemActive';
    // ...deactivate its siblings
    deactivateSiblings(menuDiv, (level == 0) ? '' : 'topMenuSubItem');
    
    // Display the menu arrow to the left of the current item
    if (level > 0)
    {
		showMenuArrow(findPosX(menuDiv) - 30, findPosY(menuDiv) + 8);
	}
    
    // We're done if there are no children
    if ((childCount == 0) || (gMenuItems[level] == null)) 
        return;

    // Create a div for the submenu
    var subMenuDiv = document.createElement("div");
    subMenuDiv.id  = 'menulevel' + level;
    subMenuDiv.className = 'topMenuSubItemBox';

    // Add items to the submenu
    for (i = skipChildren; i < (skipChildren + childCount); i++)
    {
        subMenuDiv.innerHTML += createMenuItem(gMenuItems[level][i], level+1);
    }

    // Display the submenu...
    document.body.appendChild(subMenuDiv);

    // ...and specify its position
    var ieHeight = (navigator.appVersion.indexOf("MSIE") != -1) ? 11 : 0; // ie loses 11 pixels on the body margin and border
    subMenuDiv.style.left = (findPosX(menuDiv) + 42)+ 'px';
    subMenuDiv.style.top  = (findPosY(menuDiv) + ieHeight + menuDiv.offsetHeight - 40 - subMenuDiv.clientHeight) + 'px';
    
    // Hide controls that might interfere with the menu
    if (level == 0)
    {
        hideWindowedControls();
    }
}

// Creates a submenu item and returns it as a string.
function createMenuItem(menuData, level)
{
    var menuText     = menuData[0];
    var menuUrl      = expandLink(menuData[1]);
    var childCount   = new Number(menuData[2]);
    var targetFrame  = menuData[3];
    var skipChildren = new Number(menuData[4]);
    
    // The container menu div
    var menuItemDiv = '<div class="topMenuSubItem" ';
    menuItemDiv += 'onmouseover="activateMenuItem(this, ' + childCount + ', ' + skipChildren + ', ' + level + ');" ';
    menuItemDiv += 'onmouseout="deactivateMenuItem(this, ' + level + ');" ';
    if (targetFrame && (targetFrame != null) && (targetFrame != '')) 
    {
        menuItemDiv += 'onclick="openLink(\'' + menuUrl + '\', \'' + targetFrame + '\');">';
    }
    else
    {
        menuItemDiv += 'onclick="location.href = \'' + menuUrl + '\';">';
    }
    
    // A div containing the menu item text
    var textDiv  = '<div class="topMenuSubItemText" style="float: left; width: 100%; padding-top: 2px;">' + menuText + '</div>';
    // Display an arrow if there are children
    //var arrowDiv = (childCount > 0) ?
    //                    '<div style="float: right;">&raquo;</div>' :
    //                    '';
    // A clearer-div
    var clearDiv = '<div style="clear: both;"></div>';

    // Put it all together
    menuItemDiv += (textDiv + /*arrowDiv +*/ clearDiv + '</div>');
    return menuItemDiv;
}
