var fmIsRequestSuccessful = false;

// The following array is very important.  It contains one array element per root folder menu.  All global variables for
// each folder menu are stored here so they don't collide.  They are stored per entid of each folder menu.  Each
// array element contains an FmGlobalInfo object.
var fmGlobalInfoArray = new Array();

var fmFolderGroupTypeString;
var fmAppNamePrefix = "edlFolderMenuApp";

var fmGlobalMenuItem;

var fmMenuWidth = 200;
var fmAjaxRequestEntid = "";

var fmPreviousEntid = "";
var fmPreviousTime = new Date();
var fmTimeOfPageLoad = new Date();
var fmOverrideMenuHiding = false;

var isFirefox = navigator.userAgent.indexOf ('Firefox') != -1;
var isMacFirefox = (navigator.userAgent.indexOf ('Macintosh') != -1) && (isFirefox);
var fmOverflowAdjustedDivsArray = new Array();


// Constructor for fmGlobalInfo objects added to the fmGlobalInfoArray
function FmGlobalInfo(pRootFolderEntid,
                      pRootFolderDescr,
                      pRootFolderDivId,
                      pIsVerticalMenu,
                      pRootFolderPlaceHolderDivId,
                      pAppName,
                      pRootMenuId,
                      pMenuBarClass,
                      pMenuBarItemClass,
                      pMenuBarItemOverClass,
                      pMenuBarItemClickClass,
                      pMenuClass,
                      pMenuItemClass,
                      pMenuItemOverClass,
                      pMenuArrowClass,
                      pMenuArrowOverClass,
                      pMenuBarWidth,
                      pOverrideMenuItemMouseEventsFormName,
                      pOverrideMenuBarItemMouseEventsFormName,
                      pStatusDivId,
                      pUseMenuItemSeparator,
                      pUseGradientBackground,
                      pIsVerticalGradient,
                      pGradientStartColor,
                      pGradientEndColor,
                      pDesignSidebarOpen,
                      pFolderEntidForData
                      )
{
    this.rootFolderEntid = pRootFolderEntid;
    this.rootFolderDescr = pRootFolderDescr;
    this.rootFolderDivId = pRootFolderDivId;
    this.isVerticalMenu = pIsVerticalMenu;
    this.rootFolderPlaceHolderDivId = pRootFolderPlaceHolderDivId;
    this.appName = pAppName;
    this.rootMenuId = pRootMenuId;
    this.menuBarClass = pMenuBarClass;
    this.menuBarItemClass = pMenuBarItemClass;
    this.menuBarItemOverClass = pMenuBarItemOverClass;
    this.menuBarItemClickClass = pMenuBarItemClickClass;
    this.menuClass = pMenuClass;
    this.menuItemClass = pMenuItemClass;
    this.menuItemOverClass = pMenuItemOverClass;
    this.menuArrowClass = pMenuArrowClass;
    this.menuArrowOverClass = pMenuArrowOverClass;
    this.menuBarWidth = pMenuBarWidth;
    this.overrideMenuItemMouseEventsFormName = pOverrideMenuItemMouseEventsFormName;
    this.overrideMenuBarItemMouseEventsFormName = pOverrideMenuBarItemMouseEventsFormName;
    this.statusDivId = pStatusDivId;
    this.useMenuItemSeparator = pUseMenuItemSeparator;
    this.useGradientBackground = pUseGradientBackground;
    this.isVerticalGradient = pIsVerticalGradient;
    this.gradientStartColor = pGradientStartColor;
    this.gradientEndColor = pGradientEndColor;
    this.designSidebarOpen = pDesignSidebarOpen;
    this.folderEntidForData = pFolderEntidForData;

    this.rootMenu = null;
    this.menuBar = null;

    this.itemDescrArray = new Array();
    this.itemNameArray = new Array();
    this.itemTypeArray = new Array();
    this.itemUrlArray = new Array();
    this.itemTargetArray = new Array();
    this.itemIconClassArray = new Array();
    this.urlsPerEntidArray = new Array();
    this.descrsPerEntidArray = new Array();
    this.menuNamesArray = new Array();

}


// This function is called from Javascript in GroupHome.jsp
function fmFolderMenuOnload(pRootFolderEntid,
                            pRootFolderDescr,
                            pRootFolderDivId,
                            pGroupTypeString,
                            pIsVerticalMenu,
                            pRootFolderPlaceHolderDivId,
                            pUseMenuItemSeparator,
                            pUseGradientBackground,
                            pIsVerticalGradient,
                            pGradientStartColor,
                            pGradientEndColor,
                            pHostZoneFrameId,
                            pHostZoneContentId,
                            pDesignSidebarOpen,
                            pFolderEntidForData,
                            pBordersEnabled
                            )
{
    fmFolderGroupTypeString = pGroupTypeString;

    var rootFolderDiv = document.getElementById(pRootFolderDivId);
    if (isAjaxSupported() != "yes")
    {
        rootFolderDiv.style.display = "none";
        return;
    }

    var tempMenuBarWidth = rootFolderDiv.offsetWidth;

    // Setup all the class names:
    var tempMenuBarClass = "jsdomenubardiv_" + pRootFolderEntid;
    var tempMenuBarItemClass = "jsdomenubaritem_" + pRootFolderEntid;
    var tempMenuBarItemOverClass = "jsdomenubaritemover_" + pRootFolderEntid;
    var tempMenuBarItemClickClass = "jsdomenubaritemclick_" + pRootFolderEntid;

    var tempMenuClass = "jsdomenudiv_" + pRootFolderEntid;
    var tempMenuItemClass = "jsdomenuitem_" + pRootFolderEntid;
    var tempMenuItemOverClass = "jsdomenuitemover_" + pRootFolderEntid;

    var tempMenuArrowClass = "jsdomenuarrow_" + pRootFolderEntid;
    var tempMenuArrowOverClass = "jsdomenuarrowover_" + pRootFolderEntid;

    var tempOverrideMenuItemMouseEventsFormName = "fmOverrideMenuItemMouseEventsForm_" + pRootFolderEntid;   // form name (see jsp)
    var tempOverrideMenuBarItemMouseEventsFormName = "fmOverrideMenuBarItemMouseEventsForm_" + pRootFolderEntid;   // form name (see jsp)
    var tempStatusDiv = "fmStatusDiv_" + pRootFolderEntid;   // status div id (see jsp)

    var fmGlobalInfo = new FmGlobalInfo(pRootFolderEntid,
                                        pRootFolderDescr,
                                        pRootFolderDivId,
                                        pIsVerticalMenu,
                                        pRootFolderPlaceHolderDivId,
                                        fmAppNamePrefix + pRootFolderEntid,   // application name
                                        "edlRootMenuId" + pRootFolderEntid,   // root folder menu id
                                        tempMenuBarClass,
                                        tempMenuBarItemClass,
                                        tempMenuBarItemOverClass,
                                        tempMenuBarItemClickClass,
                                        tempMenuClass,
                                        tempMenuItemClass,
                                        tempMenuItemOverClass,
                                        tempMenuArrowClass,
                                        tempMenuArrowOverClass,
                                        tempMenuBarWidth,
                                        tempOverrideMenuItemMouseEventsFormName,
                                        tempOverrideMenuBarItemMouseEventsFormName,
                                        tempStatusDiv,
                                        pUseMenuItemSeparator,
                                        pUseGradientBackground,
                                        pIsVerticalGradient,
                                        pGradientStartColor,
                                        pGradientEndColor,
                                        pDesignSidebarOpen,
                                        pFolderEntidForData
                                        )

    fmGlobalInfoArray[pRootFolderEntid] = fmGlobalInfo;

    fmCreateRootMenu(pRootFolderEntid);

    fmPopulateRootMenu(pRootFolderEntid, pFolderEntidForData);

    fmCorrectMenuWidth(pHostZoneFrameId, pHostZoneContentId, pBordersEnabled);

    // Set color gradient using a dynamic image:

    if (fmGlobalInfoArray[pRootFolderEntid].useGradientBackground == "true")
    {
        var placeHolderDiv = document.getElementById(fmGlobalInfoArray[pRootFolderEntid].rootFolderPlaceHolderDivId);
        placeHolderDiv.style.backgroundColor = "transparent";
        var tempDiv = document.getElementById(fmGlobalInfoArray[pRootFolderEntid].rootFolderDivId);

        var startColor = fmGlobalInfoArray[pRootFolderEntid].gradientStartColor;
        var endColor = fmGlobalInfoArray[pRootFolderEntid].gradientEndColor;
        var width;
        var height;
        var orientation;
        var repeatAxis;

        if (fmGlobalInfoArray[pRootFolderEntid].isVerticalGradient == "true")
        {
            width = 1;
            height = tempDiv.offsetHeight;
            orientation = "vertical";
            repeatAxis = "x";
        }
        else
        {
            width = tempDiv.offsetWidth;
            height = 1;
            orientation = "horizontal";
            repeatAxis = "y";
        }

        tempDiv.style.backgroundColor = "";
        tempDiv.style.backgroundImage = "url(/GradientImage.page" +
                                        "?skipSettingPreviousGetUrl=true" +
                                        "&width=" + width +
                                        "&height=" + height +
                                        "&orientation=" + orientation +
                                        "&startColor=" + startColor +
                                        "&endColor=" + endColor +
                                        ")";
        tempDiv.style.backgroundRepeat = "repeat-" + repeatAxis;
    }

    // Add fmKeyPressHandler to the event processing
    if (pageBody.attachEvent != undefined)   // attachEvent is an IE method
    {
        pageBody.onkeypress = appendToFunction(pageBody.onkeypress, "fmKeyPressHandler(event)");
    }
    else
    {
        addHtmlAttribute(pageBody, "onkeypress", "fmKeyPressHandler(event);");
    }

    // Assign body onclick event to close all menus on mouse click:
    if (hdrIsSafari_1_3_2())
    {
        addHtmlAttribute(pageBody, "onclick", "fmPotentiallyHideAllMenus();");
    }
    else
    {
        $("body").bind("click", function(e){
            fmPotentiallyHideAllMenus();
        });
    }

    fmTimeOfPageLoad = new Date();

}


function fmCorrectMenuWidth(pHostZoneFrameId, pHostZoneContentId, pBordersEnabled)
{
    // Correct menu width except for IE, which was working OK TT 4510
    if (!isMSIE)
    {
        var zoneFrameDiv = document.getElementById(pHostZoneFrameId);
        var zoneContentDiv = document.getElementById(pHostZoneContentId);
        if (zoneFrameDiv != null && zoneFrameDiv != undefined &&
                zoneContentDiv != null && zoneContentDiv != undefined)
        {
            var frameDivWidth = zoneFrameDiv.offsetWidth;
            var frameDivMarginPaddingBorder = 0;

            var frameDivLeftMargin;
            var frameDivRightMargin;
            var frameDivLeftPadding;
            var frameDivRightPadding;
            var frameDivLeftBorder;
            var frameDivRightBorder;

            //   Safari 1.3.2 doesn't like getComputedStyle
            if (window.getComputedStyle)
            {
                frameDivLeftMargin = parseInt(window.getComputedStyle(zoneFrameDiv, null).marginLeft);
                frameDivRightMargin = parseInt(window.getComputedStyle(zoneFrameDiv, null).marginRight);
                frameDivLeftPadding = parseInt(window.getComputedStyle(zoneFrameDiv, null).paddingLeft);
                frameDivRightPadding = parseInt(window.getComputedStyle(zoneFrameDiv, null).paddingRight);
                frameDivLeftBorder = parseInt(window.getComputedStyle(zoneFrameDiv, null).borderLeftWidth) || 0;
                frameDivRightBorder = parseInt(window.getComputedStyle(zoneFrameDiv, null).borderRightWidth) || 0;
            }
            else if (document.defaultView.getComputedStyle)
            {
                frameDivLeftMargin = parseInt(document.defaultView.getComputedStyle(zoneFrameDiv, null).marginLeft);
                frameDivRightMargin = parseInt(document.defaultView.getComputedStyle(zoneFrameDiv, null).marginRight);
                frameDivLeftPadding = parseInt(document.defaultView.getComputedStyle(zoneFrameDiv, null).paddingLeft);
                frameDivRightPadding = parseInt(document.defaultView.getComputedStyle(zoneFrameDiv, null).paddingRight);
                frameDivLeftBorder = parseInt(document.defaultView.getComputedStyle(zoneFrameDiv, null).borderLeftWidth) || 0;
                frameDivRightBorder = parseInt(document.defaultView.getComputedStyle(zoneFrameDiv, null).borderRightWidth) || 0;
            }
            else
            {
                frameDivLeftMargin = parseInt($(zoneFrameDiv).css("margin-left"));
                frameDivRightMargin = parseInt($(zoneFrameDiv).css("margin-right"));
                frameDivLeftPadding = parseInt($(zoneFrameDiv).css("padding-left"));
                frameDivRightPadding = parseInt($(zoneFrameDiv).css("padding-right"));
                frameDivLeftBorder = parseInt($(zoneFrameDiv).css("border-left-width")) || 0;
                frameDivRightBorder = parseInt($(zoneFrameDiv).css("border-right-width")) || 0;
            }

            if (!isNaN(frameDivLeftMargin))
            {
                frameDivMarginPaddingBorder += frameDivLeftMargin;
            }

            if (!isNaN(frameDivRightMargin))
            {
                frameDivMarginPaddingBorder += frameDivRightMargin;
            }

            if (!isNaN(frameDivLeftPadding))
            {
                frameDivMarginPaddingBorder += frameDivLeftPadding;
            }

            if (!isNaN(frameDivRightPadding))
            {
                frameDivMarginPaddingBorder += frameDivRightPadding;
            }

            if (!isNaN(frameDivLeftBorder))
            {
                frameDivMarginPaddingBorder += frameDivLeftBorder;
            }

            if (!isNaN(frameDivRightBorder))
            {
                frameDivMarginPaddingBorder += frameDivRightBorder;
            }

            var newContentDivWidth = frameDivWidth - frameDivMarginPaddingBorder;
            zoneContentDiv.style.width = newContentDivWidth + "px";
        }
    }
}


function fmPopulateMenu(pMenuItem)
{
    var pRootFolderEntid = fmGetEntidFromMenuItem(pMenuItem);

    for (var x = 0; x < fmGlobalInfoArray[pRootFolderEntid].itemDescrArray.length; x++)
    {
        itemDescription = fmGlobalInfoArray[pRootFolderEntid].itemDescrArray[x];
        itemName = fmGlobalInfoArray[pRootFolderEntid].itemNameArray[x];
        var action = "";

        if (fmGlobalInfoArray[pRootFolderEntid].itemTypeArray[x] != fmFolderGroupTypeString)
        {
            if (fmGlobalInfoArray[pRootFolderEntid].itemTargetArray[x] == "_blank")
            {
                action = "javascript:openPopupWindow('" + fmGlobalInfoArray[pRootFolderEntid].itemUrlArray[x] + "','','');fmPotentiallyHideAllMenus();";
            }
            else
            {
                action = "link:" + fmGlobalInfoArray[pRootFolderEntid].itemUrlArray[x];
            }
        }
        else
        {
            action = "link:" + fmGlobalInfoArray[pRootFolderEntid].itemUrlArray[x];
        }

        pMenuItem.subMenu.addMenuItem(new menuItem(itemDescription, itemName, action, "",
                fmGlobalInfoArray[pRootFolderEntid].menuItemClass, fmGlobalInfoArray[pRootFolderEntid].menuItemOverClass));

        if (fmGlobalInfoArray[pRootFolderEntid].itemTypeArray[x] == fmFolderGroupTypeString)
        {
            // Override onmouseover and onmouseout event handling for menu item just added:
            // alert('1');
            /* alert('Item description: ' + itemDescription + '\n' +
                  'Item name: ' + itemName + '\n' +
                  'Item type: ' + fmGlobalInfoArray[pRootFolderEntid].itemTypeArray[x] + '\n' +
                  'fmFolderGroupTypeString: ' + fmFolderGroupTypeString); */
            fmOverrideMenuItemMouseEvents(itemDescription, pMenuItem.subMenu.items[itemName].id, pRootFolderEntid);

          // alert('2');
            var tempSubMenu = new jsDOMenu(fmMenuWidth, "", "", "",
                    fmGlobalInfoArray[pRootFolderEntid].menuClass);
            pMenuItem.subMenu.items[itemName].setSubMenu(tempSubMenu);
            hdrAddMouseEnterLeaveTracking(tempSubMenu.menuObj.id);
          // alert('3');
            fmGlobalInfoArray[pRootFolderEntid].menuNamesArray[pMenuItem.subMenu.items[itemName].subMenu.menuObj.id] =
                pMenuItem.subMenu.items[itemName].subMenu.menuObj.id;
          // alert('4');
            fmFlagMenuAsOurs(pRootFolderEntid, pMenuItem.subMenu.items[itemName].subMenu.menuObj.id);
        }

      // Add icon, if applicable:
        var iconClass = fmGlobalInfoArray[pRootFolderEntid].itemIconClassArray[x];
        if (iconClass != '')
        {
            /* alert('Icon class: ' + iconClass + '\n' +
                  'Item description: ' + itemDescription + '\n' +
                  'Item name: ' + itemName + '\n' +
                  'Item type: ' + fmGlobalInfoArray[pRootFolderEntid].itemTypeArray[x] + '\n' +
                  'fmFolderGroupTypeString: ' + fmFolderGroupTypeString);  */
            pMenuItem.subMenu.items[itemName].showIcon(iconClass, iconClass + "Over", iconClass + "Over");
        }

    }   // for

    var submenuDiv = document.getElementById(pMenuItem.subMenu.menuObj.id);

    // Add "empty" note to subfolder
    if (fmGlobalInfoArray[pRootFolderEntid].itemDescrArray.length == 0)
    {
        pMenuItem.subMenu.addMenuItem(new menuItem("(empty folder)", "empty", pMenuItem.actionOnClick, "",
                fmGlobalInfoArray[pRootFolderEntid].menuItemClass, fmGlobalInfoArray[pRootFolderEntid].menuItemOverClass));
    }

        // Conditionally change the height of the menubar on the fly and add a scrollbar:
    else if (submenuDiv.offsetHeight > 400)
    {
        submenuDiv.style.height = "400px";
        submenuDiv.style.overflow = "auto";
        if (isMacFirefox)
        {
            // Save list of auto adjusted divs so they can be reset to counter Mac Firefox's bug TT #4084
            fmOverflowAdjustedDivsArray[pMenuItem.subMenu.menuObj.id] = true;
        }
    }

}


function fmPopulateMenuBarMenu(pMenuBarItem)
{
    var pRootFolderEntid = fmGetEntidFromMenuBarItem(pMenuBarItem);

    with (pMenuBarItem.menu)
    {
        for (var x = 0; x < fmGlobalInfoArray[pRootFolderEntid].itemDescrArray.length; x++)
        {
            itemDescription = fmGlobalInfoArray[pRootFolderEntid].itemDescrArray[x];
            itemName = fmGlobalInfoArray[pRootFolderEntid].itemNameArray[x];
            var action = "";

            if (fmGlobalInfoArray[pRootFolderEntid].itemTypeArray[x] != fmFolderGroupTypeString)
            {
                if (fmGlobalInfoArray[pRootFolderEntid].itemTargetArray[x] == "_blank")
                {
                    action = "javascript:openPopupWindow('" + fmGlobalInfoArray[pRootFolderEntid].itemUrlArray[x] + "','','');fmPotentiallyHideAllMenus();";
                }
                else
                {
                    action = "link:" + fmGlobalInfoArray[pRootFolderEntid].itemUrlArray[x];
                }
            }
            else
            {
                action = "link:" + fmGlobalInfoArray[pRootFolderEntid].itemUrlArray[x];
            }

            addMenuItem(new menuItem(itemDescription, itemName, action, "",
                    fmGlobalInfoArray[pRootFolderEntid].menuItemClass, fmGlobalInfoArray[pRootFolderEntid].menuItemOverClass));

            if (fmGlobalInfoArray[pRootFolderEntid].itemTypeArray[x] == fmFolderGroupTypeString)
            {

                // Override onmouseover and onmouseout event handling for menu item just added:
                fmOverrideMenuItemMouseEvents(itemDescription, items[itemName].id, pRootFolderEntid);

                var tempSubMenu = new jsDOMenu(fmMenuWidth, "", "", "", fmGlobalInfoArray[pRootFolderEntid].menuClass)
                items[itemName].setSubMenu(tempSubMenu);
                hdrAddMouseEnterLeaveTracking(tempSubMenu.menuObj.id);

                fmGlobalInfoArray[pRootFolderEntid].menuNamesArray[items[itemName].subMenu.menuObj.id] =
                    items[itemName].subMenu.menuObj.id;

                items[itemName].setArrowClassName(fmGlobalInfoArray[pRootFolderEntid].menuArrowClass);
                items[itemName].setArrowClassNameOver(fmGlobalInfoArray[pRootFolderEntid].menuArrowOverClass);

                fmFlagMenuAsOurs(pRootFolderEntid, items[itemName].subMenu.menuObj.id);
            }

      // Add icon, if applicable:
            var iconClass = fmGlobalInfoArray[pRootFolderEntid].itemIconClassArray[x];
            if (iconClass != '')
            {
                items[itemName].showIcon(iconClass, iconClass + "Over", iconClass + "Over");
            }

        }
    //  for
    }

    var menuDiv = document.getElementById(pMenuBarItem.menu.menuObj.id);

// Add "empty" note to subfolder
    if (fmGlobalInfoArray[pRootFolderEntid].itemDescrArray.length == 0)
    {
        var actionForEmpty = "";
        pMenuBarItem.menu.addMenuItem(new menuItem("(empty folder)", "empty", pMenuBarItem.actionOnClick, "",
                fmGlobalInfoArray[pRootFolderEntid].menuItemClass, fmGlobalInfoArray[pRootFolderEntid].menuItemOverClass));
    }

        // Conditionally change the height of the menubar on the fly and add a scrollbar:
    else if (menuDiv.offsetHeight > 400)
    {
        menuDiv.style.height = "400px";
        menuDiv.style.overflow = "auto";
    }

}


function fmKeyPressHandler(e)
{
    // keyCode 27 is the Esc key
    if (e.keyCode == '27')
    {
        fmPotentiallyHideAllMenus();
    }

}


function fmPotentiallyHideAllMenus()
{
    if (fmOverrideMenuHiding != true)
    {
        hideAllMenus();
        fmHideMacFirefoxScrollbars();
    }
    fmOverrideMenuHiding = false;
}


function fmHideMacFirefoxScrollbars()
{
    // Perhaps this Mac Firefox bug workaround is no longer necessary or only necessary for older versions.  I have
    // disabled this to solve TT #5020, but may need to revive it for older versions.  We'll see.
    return;

    // Counter Firefox Mac's bug relative to being unable to hide the divs (leaves scroll bar visible) TT #4084
    if (isMacFirefox)
    {
        for (var divId in fmOverflowAdjustedDivsArray)
        {
          if ( fmOverflowAdjustedDivsArray[divId] == true )
          {
            var subMenuDiv = document.getElementById(divId);
            subMenuDiv.style.overflow = "hidden";
            fmOverflowAdjustedDivsArray[divId] = false;
          }
        }
    }
}


// ***** IMPORTANT NOTE: *****
// "pRootFolderEntid" - will be the actual folder entid (if a placeholder not used) or placeholder folder entid
// "pFolderEntidForData" - may be the entid of a "local relative" folder that replaces a placeholder folder

function fmPopulateRootMenu(pRootFolderEntid, pFolderEntidForData)
{
        // var entid = pRootFolderEntid;
        var entid = pFolderEntidForData;
        var descr = fmGlobalInfoArray[pRootFolderEntid].rootFolderDescr;
        var menuAlwaysVisible = true;

        fmDeleteAllItemsAndSubMenus(pRootFolderEntid);
        fmDeleteMenuItems(fmGlobalInfoArray[pRootFolderEntid].rootMenu);

        /* The fmGlobalInfoArray[pRootFolderEntid].rootMenu is used as a base menu.  It will have only one thing on it: an
           item for the root folder used as a basis for the menu.  fmGlobalInfoArray[pRootFolderEntid].rootMenu's submenu will
           be the menu containing that folder's contents.  The submenu is what we will display. */

        with (fmGlobalInfoArray[pRootFolderEntid].rootMenu)
        {

            /* Add the root folder to the fmGlobalInfoArray[pRootFolderEntid].rootMenu: */
            addMenuItem(new menuItem(descr, "x" + entid, "", "",
                    fmGlobalInfoArray[pRootFolderEntid].menuItemClass, fmGlobalInfoArray[pRootFolderEntid].menuItemOverClass ));

            var tempSubMenu = new jsDOMenu(fmMenuWidth, "", "", menuAlwaysVisible, fmGlobalInfoArray[pRootFolderEntid].menuClass);
            items["x" + entid].setSubMenu(tempSubMenu);
            hdrAddMouseEnterLeaveTracking(tempSubMenu.menuObj.id);

            fmGlobalInfoArray[pRootFolderEntid].menuNamesArray[items["x" + entid].subMenu.menuObj.id] =
                items["x" + entid].subMenu.menuObj.id;
            items["x" + entid].showIcon("folderIcon", "folderIcon", "folderIcon");
            fmFlagMenuAsOurs(pRootFolderEntid, items["x" + entid].subMenu.menuObj.id);

        }   // with fmGlobalInfoArray[pRootFolderEntid].rootMenu

        /* Populate the fmGlobalInfoArray[pRootFolderEntid].rootMenu's submenu: */
        fmStartOfMenuItemOverExitPoint(null, fmGlobalInfoArray[pRootFolderEntid].rootMenu.items["x" + entid]);   // null is where pEvent is normally passed

        /* Create the menu bar from the fmGlobalInfoArray[pRootFolderEntid].rootMenu: */
        fmCreateMenuBar(pRootFolderEntid, pFolderEntidForData);
}


function fmRequestContentsData(pEntid, pRootFolderEntid)
{

    var key = "" + pEntid;
    var rootFolderEntid = "" + pRootFolderEntid;
    var parameters = "key=" + key +
                     "&menuRootFolderEntid=" + rootFolderEntid +
                     "&jspFileParm=FolderMenu" +
                     "&translatable=" + hcTranslatable +
					 "&calledFromGroupHome=true";

    // var fmStatusDiv = document.getElementById(fmGlobalInfoArray[pRootFolderEntid].statusDivId);

    // Decision was made not to show the status bar, so comment out the following:
    // fmStatusDiv.style.zIndex = 2;
    // fmStatusDiv.style.display = "inline";

    $.ajax({
        type: "POST",
        url: "/ContentsData.page",
        async: false,
        data: parameters,
        complete: function(xmlRequestObject, successString){
            fmReceiveContentsData(xmlRequestObject, successString);
        }
    });

}


function fmReceiveContentsData(ajaxReq, successString)
{
    // successString was "error" when Firefox was showing "Stopped" in status bar; see TT 4732 for more information
    if (successString.indexOf("error") != -1)
    {
        if (ghIsWorldUser)
        {
            alert('There was an unexpected ' + successString + ' in function fmReceiveContentsData in FolderMenu.js.');
        }
        return;
    }

    // Response will be null if server timed out or is unavailable.  ajaxReq.responseText will have
    // html content explaining the reason.

    if (  (ajaxReq.responseXML == null) || (ajaxReq.responseXML.firstChild == null)  )
    {
        parent.document.write(ajaxReq.responseText);
        return;
    }

    fmAjaxRequestEntid = ajaxReq.responseXML.getElementsByTagName("resources")[0].getAttribute("entid");
    var pRootFolderEntid = ajaxReq.responseXML.getElementsByTagName("resources")[0].getAttribute("menuRootFolderEntid");
    var resources = ajaxReq.responseXML.getElementsByTagName("resource");

    fmGlobalInfoArray[pRootFolderEntid].itemDescrArray.length = 0;
    fmGlobalInfoArray[pRootFolderEntid].itemNameArray.length = 0;
    fmGlobalInfoArray[pRootFolderEntid].itemTypeArray.length = 0;
    fmGlobalInfoArray[pRootFolderEntid].itemUrlArray.length = 0;
    fmGlobalInfoArray[pRootFolderEntid].itemTargetArray.length = 0;
    fmGlobalInfoArray[pRootFolderEntid].itemIconClassArray.length = 0;

    for (var x = 0; x < resources.length; x++)
    {
        var resource = resources[x];
        fmGlobalInfoArray[pRootFolderEntid].itemDescrArray[x]   = resource.getElementsByTagName("title")[0].firstChild.data;
        fmGlobalInfoArray[pRootFolderEntid].itemNameArray[x]    = "x" + resource.getElementsByTagName("entid")[0].firstChild.data;
        fmGlobalInfoArray[pRootFolderEntid].itemTypeArray[x]    = resource.getElementsByTagName("type")[0].firstChild.data;
        fmGlobalInfoArray[pRootFolderEntid].itemUrlArray[x]   = resource.getElementsByTagName("url")[0].firstChild.data;

        if (resource.getElementsByTagName("targetWindow")[0].firstChild == null)
        {
            fmGlobalInfoArray[pRootFolderEntid].itemTargetArray[x] = "";
        }
        else
        {
            fmGlobalInfoArray[pRootFolderEntid].itemTargetArray[x]   = resource.getElementsByTagName("targetWindow")[0].firstChild.data;
        }

        if (resource.getElementsByTagName("iconClass")[0].firstChild == null)
        {
            fmGlobalInfoArray[pRootFolderEntid].itemIconClassArray[x] = "";
        }
        else
        {
            fmGlobalInfoArray[pRootFolderEntid].itemIconClassArray[x]   = resource.getElementsByTagName("iconClass")[0].firstChild.data;
        }

        // Handle opening in same window
        if (fmGlobalInfoArray[pRootFolderEntid].itemTargetArray[x] == "")
        {
            fmGlobalInfoArray[pRootFolderEntid].urlsPerEntidArray[fmGlobalInfoArray[pRootFolderEntid].itemNameArray[x]] =
                fmGlobalInfoArray[pRootFolderEntid].itemUrlArray[x];
        }

        // Handle opening in new window
        else
        {
            fmGlobalInfoArray[pRootFolderEntid].urlsPerEntidArray[fmGlobalInfoArray[pRootFolderEntid].itemNameArray[x]] =
                "javascript:openPopupWindow('" + fmGlobalInfoArray[pRootFolderEntid].itemUrlArray[x] + "','','');fmPotentiallyHideAllMenus();";
        }

        fmGlobalInfoArray[pRootFolderEntid].descrsPerEntidArray[fmGlobalInfoArray[pRootFolderEntid].itemNameArray[x]] = fmGlobalInfoArray[pRootFolderEntid].itemDescrArray[x];
    }

    // var fmStatusDiv = document.getElementById(fmGlobalInfoArray[pRootFolderEntid].statusDivId);
    // fmStatusDiv.style.zIndex = 0;
    // fmStatusDiv.style.display = "none";

    fmIsRequestSuccessful = true;

}   // function fmReceiveContentsData


function fmTraceOut(someText)
{
    return;
  // var taElem = document.getElementById('outputArea');
    // taElem.value = someText + "\n" + taElem.value;   // add to top
}


function fmStartOfMenuItemClickExitPoint(pEvent, pMenuItem)
{
    var pRootFolderEntid = fmGetEntidFromMenuItem(pMenuItem);

    // A click action shouldn't do anything on an empty folder:
    var itemDesc = "default description";
    if (pMenuItem.innerText != undefined)
    {
        itemDesc = pMenuItem.innerText;   // IE
    }
    else
    {
        itemDesc = pMenuItem.textContent;   // Firefox
    }

    /*
    if (itemDesc == '(empty folder)')
    {
        return;
    }
    */


  // Exit points could be called for ANY menu (including those not generated by this page).  Therefore only run
    // this code if for one of OUR menus.
    if (fmIsOurMenu(pMenuItem) != true)
    {
        return;
    }

  // 3/7/08 Added actionOnClick test below.  I had a bit of a time trying to remember the purpose of testing for
    // the iconObj stuff.  I believe it was intended to mean "don't run the remainder of this function if the menu
    // item is a "More..." or "Edit..." or similar action.  However, once I added the option to not show icons in
    // the navbar, then one could no longer navigate to folders due to the following block executing a return.
    // I think adding the actionOnClick test will fix that problem.

    if (
            pMenuItem.actionOnClick.length != 0 &&
            (  (pMenuItem.iconObj == null) || (pMenuItem.iconObj == undefined)  )
            )
    {
        return;
    }

    var itemName = "x" + fmExtractEntid(pMenuItem);

    // window.location = fmGlobalInfoArray[pRootFolderEntid].urlsPerEntidArray[itemName];

}


function fmDeleteAllDomNodesForElement(pElement)
{
    var children = pElement.childNodes;

    if (children != undefined)
    {
        while (children.length > 0)
        {
            pElement.removeChild(children[0]);
        }
    }

    // For above, try this shortcut method, which may work: pElement.Node.length = 0;

}


function fmDeleteMenuItems(pMenu)
{

    // First delete all properties from the menu's "items" object:
    for (itemName in pMenu.items)
    {
        delete pMenu.items[itemName];
    }

    // Then delete all html/DOM elements from the menu's div:
    fmDeleteAllDomNodesForElement(document.getElementById(pMenu.menuObj.id));
}


function fmDeleteAllItemsAndSubMenus(pRootFolderEntid)
{
    fmDeleteAllItemAndSubMenuDomInfo(pRootFolderEntid);
    fmRecursivelyDeleteItemAndSubMenuObjects(fmGlobalInfoArray[pRootFolderEntid].rootMenu);
    delete fmGlobalInfoArray[pRootFolderEntid].rootMenu.previousItem;
}


// This function will only delete DOM info for menus that are OURS because it only processes menus in the
// fmGlobalInfoArray[pRootFolderEntid].menuNamesArray, which we keep track of.
function fmDeleteAllItemAndSubMenuDomInfo(pRootFolderEntid)
{
    var numberOfMenus = menuCount;
    var menuNames = "";
    for (var menuName in fmGlobalInfoArray[pRootFolderEntid].menuNamesArray)
    {
        menuNames += menuName + ":";
    }

    for (var x = 1; x <= numberOfMenus; x++)
    {
        var nameOfMenu = "DOMenu" + x;
        if (  (menuNames.indexOf(nameOfMenu + ":") >= 0) && (nameOfMenu != fmGlobalInfoArray[pRootFolderEntid].rootMenu.menuObj.id)  )
        {
            fmDeleteAllDomNodesForElement(document.getElementById(nameOfMenu));
            var parentElem = document.getElementById(nameOfMenu).parentNode;
            parentElem.removeChild(document.getElementById(nameOfMenu));

      // Subtract 1 from third party tool's menu count:
            menuCount--;

            fmGlobalInfoArray[pRootFolderEntid].menuNamesArray[nameOfMenu] = "";
        }
    }
}


function fmRecursivelyDeleteItemAndSubMenuObjects(pMenu)
{

    // Loop #1 through and process this menu's items which aren't submenus:
    for (itemName in pMenu.items)
    {
        if ( pMenu.items[itemName].subMenu == null )
        {
            // traceOut('Loop 1: Deleting menu item object with name '  + itemName);
            delete pMenu.items[itemName];
        }
    }   // Loop #1

    // Loop #2 through and process this menu's remaining items (which should be submenus):
    for (itemName in pMenu.items)
    {
        var saveItemName = itemName;
        fmRecursivelyDeleteItemAndSubMenuObjects(pMenu.items[itemName].subMenu);
    // traceOut('Loop 2: Deleting menu item object with name '  + saveItemName);
        delete pMenu.items[saveItemName];
    }   // Loop #2

}


function fmExtractEntid(pMenuItem)
{

    // pMenuItem.parent.items is an associative array that contains a list of x + folder entid
    // match up pMenuItem.id with the correct pMenuItem.parent.items entry to get the x + folder entid
    // pMenuItem.parent.items.folder2.id is what to match up with pMenuItem.id

    var entid = "";
    for (itemName in pMenuItem.parent.items)
    {
        if (pMenuItem.parent.items[itemName].id == pMenuItem.id)
        {
            entid = itemName.substring(1);
            break;
        }
    }
    return entid;
}


function fmBuildDynamicMenuItems(pEvent, pMenuItem, pRootFolderEntid)
{


    var itemDesc = "default description";
    var menuItemDiv = document.getElementById(pMenuItem.id);
    if (menuItemDiv.innerText != undefined)
    {
        itemDesc = menuItemDiv.innerText;   // IE
    }
    else
    {
        itemDesc = menuItemDiv.textContent;   // Firefox
    }
  
  // traceOut('Regenerating menu ' + itemDesc);

    // Delete existing menu items, if submenu:
    fmDeleteMenuItems(pMenuItem.subMenu);
      

      // Extract the entid:
    var entid = fmExtractEntid(pMenuItem);

    fmIsRequestSuccessful = false;
    fmRequestContentsData(entid, pRootFolderEntid);

      // Use the response data, which should be ready since doing synchronous Ajax request:
    if (fmIsRequestSuccessful == true)
    {
        fmGlobalMenuItem = pMenuItem;
        // alert('inside fmBuildDynamicMenuItems about to call fmPopulateMenu.  itemDesc: ' + itemDesc);
        fmPopulateMenu(fmGlobalMenuItem);
    }

}


function fmBuildDynamicMenuBarItems(pEvent, pMenuBarItem, pRootFolderEntid)
{
    var itemDesc = "default description";
    var menuItemDiv = document.getElementById(pMenuBarItem.id);
    if (menuItemDiv.innerText != undefined)
    {
        itemDesc = menuItemDiv.innerText;   // IE
    }
    else
    {
        itemDesc = menuItemDiv.textContent;   // Firefox
    }

  // traceOut('Regenerating menu ' + itemDesc);

    // Delete existing menu items:
    fmDeleteMenuItems(pMenuBarItem.menu);


      // Extract the entid:
    var entid = fmExtractEntid(pMenuBarItem);

    fmIsRequestSuccessful = false;
    fmRequestContentsData(entid, pRootFolderEntid);

      // Use the response data, which should be ready since doing synchronous Ajax request:
    if (fmIsRequestSuccessful == true)
    {
        fmGlobalMenuItem = pMenuBarItem;
        fmPopulateMenuBarMenu(fmGlobalMenuItem);
    }

}


function fmOverrideMenuItemMouseEvents(pItemDescription, pMenuItemDivId, pRootFolderEntid)
{
    // traceOut('overriding mouse events for item=' + pItemDescription + ' div=' + pMenuItemDivId);
    var menuItemDiv = document.getElementById(pMenuItemDivId);

    menuItemDiv.onmouseover = null;
    menuItemDiv.onmouseout = null;

    var tempOverrideMenuItemMouseEventsFormName = fmGlobalInfoArray[pRootFolderEntid].overrideMenuItemMouseEventsFormName;

    // The only way I know of to dynamically add "hoverIntent" to an element that is created on-the-fly (after
    // the document onload process is finished) is the following.  It temporarily adds an event handler to an empty form's "onreset"
    // event.  When the empty form is reset, it adds the "hoverIntent" function to the menu item div.

    // Discovered that IE (7?) doesn't unbind properly, so whenever you use multiple jQuery bind/unbind instructions
    // in the same page, use separate forms for each of them.

    if (hdrIsSafari_1_3_2())
    {
        var menuItemDivElem = document.getElementById(pMenuItemDivId);
        addHtmlAttribute(menuItemDivElem, "onmouseover", "menuItemOver(event);");
        addHtmlAttribute(menuItemDivElem, "onmouseout", "menuItemOut(event);");
    }
    else
    {
        $("#" + tempOverrideMenuItemMouseEventsFormName).bind("reset", function() { $("#" + pMenuItemDivId).hoverIntent({
            sensitivity: 1,
            interval: 90,
            over: menuItemOver,   // a jsdomenubar function name
            timeout: 100,
            out: menuItemOut } ); } );   // a jsdomenubar function name

        document.forms[tempOverrideMenuItemMouseEventsFormName].reset();

        $("#" + tempOverrideMenuItemMouseEventsFormName).unbind();
    }

}


function fmOverrideMenuBarItemMouseEvents(pItemDescription, pMenuBarItemElemId, pRootFolderEntid)
{
    // traceOut('overriding mouse events for item=' + pItemDescription + ' div=' + pMenuItemDivId);
    var menuBarItemElem = document.getElementById(pMenuBarItemElemId);

    menuBarItemElem.onmouseover = null;
    menuBarItemElem.onmouseout = null;

    var tempOverrideMenuBarItemMouseEventsFormName = fmGlobalInfoArray[pRootFolderEntid].overrideMenuBarItemMouseEventsFormName;

    // The only way I know of to dynamically add "hoverIntent" to an element that is created on-the-fly (after
    // the document onload process is finished) is the following.  It temporarily adds an event handler to an empty form's "onreset"
    // event.  When the empty form is reset, it adds the "hoverIntent" function to the menu item div.

    // Discovered that IE (7?) doesn't unbind properly, so whenever you use multiple jQuery bind/unbind instructions
    // in the same page, use separate forms for each of them.
    if (hdrIsSafari_1_3_2())
    {
        var menuBarItemElem = document.getElementById(pMenuBarItemElemId);
        addHtmlAttribute(menuBarItemElem, "onmouseover", "menuBarItemOver(event);");
        addHtmlAttribute(menuBarItemElem, "onmouseout", "menuBarItemOut(event);");
    }
    else
    {
        $("#" + tempOverrideMenuBarItemMouseEventsFormName).bind("reset", function() { $("#" + pMenuBarItemElemId).hoverIntent({
            sensitivity: 1,
            interval: 90,
            over: menuBarItemOver,   // a jsdomenubar function name
            timeout: 100,
            out: menuBarItemOut } ); } );   // a jsdomenubar function name

        document.forms[tempOverrideMenuBarItemMouseEventsFormName].reset();

        $("#" + tempOverrideMenuBarItemMouseEventsFormName).unbind();
    }
}


function fmFlagMenuAsOurs(pRootFolderEntid, menuDivId)
{
    var menuDiv = document.getElementById(menuDivId);
    menuDiv.setAttribute("app", fmGlobalInfoArray[pRootFolderEntid].appName);
}


function fmFlagMenuBarAsOurs(pRootFolderEntid, menuBarDivId)
{
    var menuBarDiv = document.getElementById(menuBarDivId);
    menuBarDiv.setAttribute("app", fmGlobalInfoArray[pRootFolderEntid].appName);
}


function fmFlagMenuBarItemAsOurs(pRootFolderEntid, menuBarItemSpanId)
{
    var menuBarItemSpan = document.getElementById(menuBarItemSpanId);
    menuBarItemSpan.setAttribute("app", fmGlobalInfoArray[pRootFolderEntid].appName);
}


function fmGetEntidFromMenuBarItem(pMenuBarItem)
{
    var parentMenuElem = document.getElementById(pMenuBarItem.parent.menuBarObj.id);
    var appAttribute = parentMenuElem.getAttribute("app");
    return fmGetEntidFromAttributeString(appAttribute);
}


function fmGetEntidFromMenuItem(pMenuItem)
{
    var parentMenuElem = document.getElementById(pMenuItem.parent.menuObj.id);
    var appAttribute = parentMenuElem.getAttribute("app");
    return fmGetEntidFromAttributeString(appAttribute);
}


function fmGetEntidFromAttributeString(pAttributeString)
{
    if (  (pAttributeString == null) || (pAttributeString == undefined)  )
    {
        return "";
    }
    else
    {
        var startPos = pAttributeString.indexOf(fmAppNamePrefix);
        if (startPos >= 0)
        {
            startPos += fmAppNamePrefix.length;
            var entid = pAttributeString.substring(startPos);
            return entid;
        }
        else
        {
            return "";
        }
    }
}


function fmIsOurMenuBarItem(pMenuBarItem)
{
    var pRootFolderEntid = fmGetEntidFromMenuBarItem(pMenuBarItem);

    if (pRootFolderEntid == "")
    {
        return false;
    }

    var parentMenuDiv = document.getElementById(pMenuBarItem.parent.menuBarObj.id);
    var appAttribute = parentMenuDiv.getAttribute("app");
    if (  (appAttribute == null) || (appAttribute == undefined) || (appAttribute != fmGlobalInfoArray[pRootFolderEntid].appName)  )
    {
        return false;
    }

    if (  (fmGlobalInfoArray[pRootFolderEntid].menuBar != undefined) &&
          (pMenuBarItem.parent.menuBarObj == fmGlobalInfoArray[pRootFolderEntid].menuBar.menuBarObj)    )
    {
        return true;
    }
    else
    {
        return false;
    }
}


function fmIsOurMenu(pMenuItem)
{
    var pRootFolderEntid = fmGetEntidFromMenuItem(pMenuItem);

    if (pRootFolderEntid == "")
    {
        return false;
    }

    var parentMenuDiv = document.getElementById(pMenuItem.parent.menuObj.id);
    var appAttribute = parentMenuDiv.getAttribute("app");
    if (  (appAttribute == null) || (appAttribute == undefined) || (appAttribute != fmGlobalInfoArray[pRootFolderEntid].appName)  )
    {
        return false;
    }

    var menuNames = "";
    for (var menuName in fmGlobalInfoArray[pRootFolderEntid].menuNamesArray)
    {
        menuNames += menuName + ":";
    }

    var ourMenu = false;

    if (menuNames.indexOf(pMenuItem.parent.menuObj.id + ":") >= 0)
    {
        ourMenu = true;
    }

    if (pMenuItem.parent.menuObj.id == fmGlobalInfoArray[pRootFolderEntid].rootMenu.menuObj.id)
    {
        ourMenu = true;
    }

    return ourMenu;

}


function fmStartOfMenuItemOverExitPoint(pEvent, pMenuItem)
{

    // Exit points could be called for ANY menu (including those not generated by this page).  Therefore only run
    // this code if for one of OUR menus.
    if (fmIsOurMenu(pMenuItem) != true)
    {
        return;
    }

    var pRootFolderEntid = fmGetEntidFromMenuItem(pMenuItem);


    if (pMenuItem.subMenu != null)
    {
        // If two "hover overs" happen back to back in a short period of time for the same entid/menu, don't do anything with it
        var currentEntid = fmExtractEntid(pMenuItem);
        if (currentEntid == fmPreviousEntid)
        {
            var currentTime = new Date();
            var timeDifference = currentTime - fmPreviousTime;
            if (timeDifference < 1000)   // mdss 2/4/08 changed from 4000 to 1000
            {
                return;
            }
        }

        fmPreviousEntid = currentEntid;
        fmPreviousTime = currentTime;

      // Ajax should be ready, since doing sync request
        // alert('inside fmStartOfMenuItemOverExitPoint - prior to call to fmBuildDynamicMenuItems');
        fmBuildDynamicMenuItems(pEvent, pMenuItem, pRootFolderEntid);

    }

}


function fmStartOfMenuBarItemClickExitPoint(pEvent, pMenuBarItem)
{
    // Exit points could be called for ANY menu (including those not generated by this page).  Therefore only run
      // this code if for one of OUR menus.
      if (fmIsOurMenuBarItem(pMenuBarItem) != true)
      {
          return;
      }

      var pRootFolderEntid = fmGetEntidFromMenuBarItem(pMenuBarItem);

      var itemName = "x" + fmExtractEntid(pMenuBarItem);

      pMenuBarItem.enabled = false;   // should prevent click from re-showing the menubar's menu
      fmPotentiallyHideAllMenus();
      window.location = fmGlobalInfoArray[pRootFolderEntid].urlsPerEntidArray[itemName];
}


function fmStartOfMenuBarItemOverExitPoint(pEvent, pMenuBarItem)
{

    // Exit points could be called for ANY menu (including those not generated by this page).  Therefore only run
    // this code if for one of OUR menus.
    if (fmIsOurMenuBarItem(pMenuBarItem) != true)
    {
        return;
    }

    // fmTouchMenuBarClassNames();
    ghTouchMenuBarForIE();

    // If the menu bar item is NOT A MENU, then bail:
    if (pMenuBarItem.menu == null)
    {
        fmPotentiallyHideAllMenus();
        // fmTouchMenuBarClassNames();
        ghTouchMenuBarForIE();
        return;
    }

    var pRootFolderEntid = fmGetEntidFromMenuBarItem(pMenuBarItem);


    fmBuildDynamicMenuBarItems(pEvent, pMenuBarItem, pRootFolderEntid);

    // Calculate placement of menu before showing it:
    var menuBarItemDiv = document.getElementById(pMenuBarItem.id);
    var menuBarItemLeftEdge = menuBarItemDiv.offsetLeft;
    var menuBarItemTopEdge = menuBarItemDiv.offsetTop;
    var menuBarItemWidth = menuBarItemDiv.offsetWidth;
    var menuBarItemHeight = menuBarItemDiv.offsetHeight;

    // var folderMenuDiv = document.getElementById(fmGlobalInfoArray[pRootFolderEntid].rootFolderDivId);
    // var folderMenuLeftEdge = folderMenuDiv.offsetLeft;
    // var folderMenuTopEdge = folderMenuDiv.offsetTop;
    var fmdOffset = $("#" + fmGlobalInfoArray[pRootFolderEntid].rootFolderDivId).offset();
    var folderMenuLeftEdge = fmdOffset.left;
    var folderMenuTopEdge = fmdOffset.top;

    var popupMenuElem = document.getElementById(pMenuBarItem.menu.menuObj.id);

    var windowWidth = hdrGetWindowWidth(window);
    var windowHeight = hdrGetWindowHeight(window);

    var targetX = 0;
    var targetY = 0;

    if (fmGlobalInfoArray[pRootFolderEntid].isVerticalMenu == "true")
    {
        var menuPlaceHolderDiv = document.getElementById(fmGlobalInfoArray[pRootFolderEntid].rootFolderPlaceHolderDivId);
        var menuPlaceHolderWidth = menuPlaceHolderDiv.offsetWidth;
        targetX = $(menuBarItemDiv).offset().left + $(menuBarItemDiv).outerWidth();

        // Handle case where targetX is to the right of the browser window:
        if (targetX + popupMenuElem.offsetWidth > windowWidth )
        {
            targetX = $(menuBarItemDiv).offset().left - popupMenuElem.offsetWidth;
        }

        targetY = folderMenuTopEdge + menuBarItemTopEdge;

        // Handle case where targetY is below the browser window:
        if (targetY + popupMenuElem.offsetHeight > windowHeight )
        {
            targetY = folderMenuTopEdge + menuBarItemTopEdge + menuBarItemHeight - popupMenuElem.offsetHeight - 1;
            if (targetY < 0)
            {
                targetY = 0;
            }
        }

    }
    else
    {
        targetX = folderMenuLeftEdge + menuBarItemLeftEdge;

        // Handle case where targetX is to the right of the browser window:
        if (targetX + popupMenuElem.offsetWidth > windowWidth )
        {
            targetX = folderMenuLeftEdge + menuBarItemLeftEdge + menuBarItemWidth - popupMenuElem.offsetWidth;
        }

        targetY = folderMenuTopEdge + menuBarItemTopEdge + menuBarItemHeight;

        // Handle case where targetY is below the browser window:
        if (targetY + popupMenuElem.offsetHeight > windowHeight )
        {
            targetY = folderMenuTopEdge - popupMenuElem.offsetHeight - 1;
        }

    }

    // hideMenuBarMenus();   // this doesn't work (at least for my purposes)
    fmPotentiallyHideAllMenus();
    // pMenuBarItem.menu.moveTo(targetX, targetY);
    pMenuBarItem.menu.moveTo(targetX, targetY);

    pMenuBarItem.menu.show();

    // fmTouchMenuBarClassNames();
    ghTouchMenuBarForIE();

}


function fmStartOfMenuBarItemOutExitPoint(pMenuBarItem)
{

    // Exit points could be called for ANY menu (including those not generated by this page).  Therefore only run
    // this code if for one of OUR menus.
    if (fmIsOurMenuBarItem(pMenuBarItem) != true)
    {
        return;
    }

    // fmTouchMenuBarClassNames();
    ghTouchMenuBarForIE();
}

function fmMenuItemClickReturnActionStringOverrideExitPoint(pEvent, pMenuItem)
{
    var action = pMenuItem.actionOnClick;
  // alert('action=' + action);
    // Return the original action and let it proceed as it normally would
    return action;
}


function fmCreateRootMenu(pRootFolderEntid)
{
    var menuAlwaysVisible = true;

    var tempMenu = new jsDOMenu(fmMenuWidth,
                        "",
                        fmGlobalInfoArray[pRootFolderEntid].rootMenuId,
                        menuAlwaysVisible,
                        fmGlobalInfoArray[pRootFolderEntid].menuClass);

    fmGlobalInfoArray[pRootFolderEntid].rootMenu = tempMenu;

    // May not need the following:
    hdrAddMouseEnterLeaveTracking(tempMenu.menuObj.id);

    fmFlagMenuAsOurs(pRootFolderEntid, fmGlobalInfoArray[pRootFolderEntid].rootMenu.menuObj.id);
}


// ***** IMPORTANT NOTE: *****
// "pRootFolderEntid" - will be the actual folder entid (if a placeholder not used) or placeholder folder entid
// "pFolderEntidForData" - may be the entid of a "local relative" folder that replaces a placeholder folder

function fmCreateMenuBar(pRootFolderEntid, pFolderEntidForData)
{
    //*** Create overall menu and its items:

    // fmGlobalInfoArray[pRootFolderEntid].menuBar = new jsDOMenuBar("absolute", "absoluteMenuBar", "", "", fmMenuBarWidth);   // ** seems to work OK except height doesn't auto-adjust; 600 was old width
    // fmGlobalInfoArray[pRootFolderEntid].menuBar = new jsDOMenuBar("absolute", "absoluteMenuBar", "", "", "");   // absolute without width specified
    // fmGlobalInfoArray[pRootFolderEntid].menuBar = new jsDOMenuBar("static", fmGlobalInfoArray[pRootFolderEntid].rootFolderPlaceHolderDivId, "", "", "");   // static without width specified
    fmGlobalInfoArray[pRootFolderEntid].menuBar = new jsDOMenuBar("static", fmGlobalInfoArray[pRootFolderEntid].rootFolderPlaceHolderDivId, "",
            fmGlobalInfoArray[pRootFolderEntid].menuBarClass);   // 5th parm is width, 6th parm is height
    hdrAddMouseEnterLeaveTracking(fmGlobalInfoArray[pRootFolderEntid].menuBar.menuBarObj.id);

    fmFlagMenuBarAsOurs(pRootFolderEntid, fmGlobalInfoArray[pRootFolderEntid].rootFolderPlaceHolderDivId);

    // var entid = pRootFolderEntid;
    var entid = pFolderEntidForData;
    var cmbBrowseMenuSubmenu = fmGlobalInfoArray[pRootFolderEntid].rootMenu.items["x" + entid].subMenu;

    with (fmGlobalInfoArray[pRootFolderEntid].menuBar) {

        // Pre-process array to get index of last item.  For some reason, cmbBrowseMenuSubmenu.items.length always
        // reports 0.  Maybe that object isn't really an array.

        var lastIndex = -1;
        for (itemName in cmbBrowseMenuSubmenu.items)
        {
            lastIndex++;
        }

        var x = -1;

        for (itemName in cmbBrowseMenuSubmenu.items)
        {
            x++;

            var action = "";
            if (fmGlobalInfoArray[pRootFolderEntid].itemTargetArray[x] == "_blank")
            {
                action = "javascript:openPopupWindow('" + fmGlobalInfoArray[pRootFolderEntid].itemUrlArray[x] + "','','');fmPotentiallyHideAllMenus();";
            }
            else
            {
                action = "link:" + fmGlobalInfoArray[pRootFolderEntid].itemUrlArray[x];
            }

            var cmbDescr = fmGlobalInfoArray[pRootFolderEntid].descrsPerEntidArray[itemName];
            var cmbMenuObj = cmbBrowseMenuSubmenu.items[itemName].subMenu;

            var tempMenuBarItem = new menuBarItem(
                    cmbDescr,
                    cmbMenuObj,
                    itemName,
                    "",
                    action,
                    (fmGlobalInfoArray[pRootFolderEntid].designSidebarOpen == "true" && x == lastIndex) ?
                    fmGlobalInfoArray[pRootFolderEntid].menuBarItemOverClass :
                    fmGlobalInfoArray[pRootFolderEntid].menuBarItemClass,
                    fmGlobalInfoArray[pRootFolderEntid].menuBarItemOverClass,
                    fmGlobalInfoArray[pRootFolderEntid].menuBarItemClickClass
                    );

            addMenuBarItem(tempMenuBarItem);
            fmFlagMenuBarItemAsOurs(pRootFolderEntid, tempMenuBarItem.id);

            if (fmGlobalInfoArray[pRootFolderEntid].itemTypeArray[x] == fmFolderGroupTypeString)
            {
                // Override onmouseover and onmouseout event handling for menubar item just added:
                fmOverrideMenuBarItemMouseEvents(cmbDescr, tempMenuBarItem.id, pRootFolderEntid);
            }


            // Don't show the separate for the last menu item (was using CSS, but IE doesn't abide)
            if (  ( x == lastIndex) && (fmGlobalInfoArray[pRootFolderEntid].useMenuItemSeparator == "true")  )
            {
                var tempElem = document.getElementById(tempMenuBarItem.id);
                if (fmGlobalInfoArray[pRootFolderEntid].isVerticalMenu == "true")
                {
                    tempElem.style.borderBottom = "none";
                }
                else
                {
                    tempElem.style.paddingRight = "2px";
                    tempElem.style.borderRight = "none";
                }
            }

        }

    }

}


function fmTouchMenuBarClassNames()
{
    // Refresh the menu bar class name (with same thing it had).  For some reason, this solves an IE bug.
    for (entidKey in fmGlobalInfoArray)
    {
        var placeHolderDiv = document.getElementById(fmGlobalInfoArray[entidKey].rootFolderPlaceHolderDivId);
        if (  (placeHolderDiv != null) && (placeHolderDiv != undefined)  )
        {
            placeHolderDiv.className = fmGlobalInfoArray[entidKey].menuBarClass;
        }
    }

}
