// Constant declaration
// Constants are declared as var and not const as IE does not recognise them
var MENU_ITEM_SRC_CONST = "_menuItemSource";

var FRAME_MOVEUP_CONST = 'moveUp';
var FRAME_MOVEDN_CONST = 'moveDown';

var FRAME_CHILDLIST_ID_CONST = '_sdf_clist_identif_';
var FRAME_CHILD_SEPARATOR_CONST = '_sdf_child_sep_';
var FRAME_PARENT_IDENTIFIER_CONST = '_sdf_parent_identif_ ';
var FRAME_ROOT_PARENT_IDENTIFIER_CONST = '_sdf_root_parent_identif_ ';

var FRAME_IMAGEBAR_IDENTIFIER_CONST = "imageBar_";
var FRAME_SUBMENU_CONST = '_subMenu';

var FRAME_CONTAINER_TD_ID_CONST = '_t2r1c1';

var HIDDEN_TOOLBAR_DIV_IDENTIFIER = '_toolbarDiv';

var _MENUBAR_ZINDEX    = '65003';
var _SUBMENUBAR_ZINDEX = '65004';
var _FRAMEDIV_ZINDEX   = '65002';
var _FRAMEDIV_DFLT_ZINDEX = '0';

// Hashmap to store the id of the frame whose z-Index property was last changed
// and now needs to be restored. See showMenu() for what is it for.
var zIndexModifiedFrame = new Object();

// Variable declaration
var regionBar = null;  
var imageBarRegion = null; 
var clickImageRegion = null; 
var currToolBarDiv = null;

// The content thats currently displayed on mouse enter of the frame
var displayedContent = null; 
// Menu related regions
var menuBarDiv = null; 
var subMenuBarDiv = null; 
var menuBarSpan = null;  

var modifiedFrameComps = new Object();

// Hashmap to store all the frames removed as part of max operation.
// Key in the map is parent of the frame getting maxed.
var maxedFrameComps = new Object();
var minimizedFrameComps = new Object();

// Map to contain all temporary children created
// while doing a form submit
tempSDFParams = new Object();

// Map to store the heights of the components being minimized, so that 
// components can be expanded to their original heights during restore operation.
var minimizedCompHeights = new Object();

// Map to store the widths of the components being minimized, required during 
// the restore operation.
var minimizedCompWidths = new Object();

var maximizedParentWidths = new Object();

var showHideParentWidths = new Object();

var maxHoldingFrames = new Object();

var xmlObj;

// Indicator of which toolbars have their close icons clicked. A "true" value 
// indicates the toolBar has been closed.
var toolBarCloseStatus = new Object();

// This variable indicates whether or not the mouse is hovering over the 
// content area of a component.
var hovering = null;

var menuDirReversedForSafari = false;
function initGUI()
{  
  regionBar = document.getElementById('regionbar'); 
  if (document.attachEvent)
  {
    document.attachEvent('onclick',doDocumentClick); 
  }
  if (document.addEventListener)
  {
    document.addEventListener('click',doDocumentClick, false); 
  }
}

initGUI(); 

function doDocumentClick(event)
{  
  if (!event)
  {
    var event = window.event;
  }
  var elem = (event.target) ? event.target : event.srcElement;

  if ( ( imageBarRegion && 
       ( imageBarRegion.id != elem.id ) ) && 
       ( clickImageRegion && ( clickImageRegion.id != elem.id ) ) )
  {
    imageBarRegion.style.display = 'none'; 
  }
  
  // If there are any active menus, set their styles to nothing. 
  
  // This will be the case when last menu invoked through showMenuFloatingOMO
  if ( (clickImageRegion) && 
       (clickImageRegion.id != elem.id) ) 
  {
    hideLastMenuShown();
  }
  
  // This will be the case when last menu invoked through showMenu
  if ( (! clickImageRegion) && (menuBarDiv) )
  {
    hideLastMenuShown();
  }
  
  // This will be the case when last menu invoked is submenu through eny other means
  if ( (! clickImageRegion) && (subMenuBarDiv) )
  {
    hideLastMenuShown();
  }
  
  if (displayedContent)
  {
    displayedContent.style.display = 'none';
  }
}


/*
 * Shows help file in a new window.
 * 
 */
function showFrameHelpWindow(elem)
{
  var formElem = findFormElem(elem);
  if (formElem)
  {
    var actionURL = formElem.action;
    var appURL = actionURL.substring(1, actionURL.length);
    appURL = '/' + appURL.substring(0, appURL.indexOf('/')) + '/frameHelp.html';
    window.open(appURL, "_blank", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,copyhistory=no,width=435,height=275");
  }
  return false;
}

/**
 *  prevents event from being propagated further
 */
function preventEventPropagation(event)
{ 
  if (event.stopPropagation)
  {   
    event.stopPropagation();
  }
  else if (event.srcElement) // should be IE
  {   
    event.cancelBubble = true;
  }
  
  //to prevent default action:
  if (event.preventDefault) //non-IE
  {    
    event.preventDefault();
  }
  else 
  {
    event.returnValue = false; //IE
    return false; //legacy browsers  
  }
}

function findPosX(obj)
{
  var curleft = 0;
  if (obj.offsetParent)
  {
    while (obj.offsetParent)
    {
      if(obj.style.position != 'relative' || _agent.isSafari )
      {  
        curleft += obj.offsetLeft;
      }
      obj = obj.offsetParent;
    }
  }
  else if (obj.x)
  {
    curleft += obj.x;
  }
  return curleft;
}

function findPosY(obj)
{   
  var curtop = 0; 
  
  if (obj.offsetParent)
  {
    while (obj.offsetParent)
    {      
      if( obj.style.position != 'relative' || _agent.isSafari )
      {              
        curtop += obj.offsetTop;        
      }      
      obj = obj.offsetParent;
    }
  }
  else if (obj.y)
  {
    curtop += obj.y;
  }
  return curtop;
}

function findPosHeight(obj)
{
  var curbottom = 0;
  if (obj.offsetParent)
  {
    while (obj.offsetParent)
    {
      curbottom += obj.offsetHeight;
      obj = obj.offsetParent;
    }
  }
  else if (obj.width)
  {
    curbottom += obj.width;
  }
  return curbottom;
}


/*
 * Finds holding DIV element of the current image element.
 * returns the parent DIV element node of the elem object passed as argument
 */
function findHoldingDiv(elem)
{  
  var upNodeName = null; //parentNode   
  
  if (elem.parentNode.localName) // Mozilla etc
  {
    upNodeName = elem.parentNode.localName.toUpperCase();
  } 
  else if (elem.parentNode.tagName) // IE only
  {
    upNodeName = elem.parentNode.tagName.toUpperCase();
  }  
  
  if (upNodeName == "DIV")
  {
    return (elem.parentNode);
  }
  else
  {    
    return findHoldingDiv(elem.parentNode);
  }
}

/*
 * Returns string representing the element type in uppercase.
 */
function findElemType(elem)
{
  var thisNodeName = null; 
  if (elem.localName) // Mozilla etc
  {
    thisNodeName = elem.localName.toUpperCase();
  }
  else if (elem.tagName) // IE only
  {
    thisNodeName = elem.tagName.toUpperCase();
  }
  return thisNodeName;
}

function getWinSize() 
{
  var sizeObj = new Object();
  sizeObj.objWidth = 0;
  sizeObj.objHeight = 0;
  
  if( typeof( window.innerWidth ) == 'number' ) 
  {
    //Non-IE
    sizeObj.objWidth = window.innerWidth;
    sizeObj.objHeight = window.innerHeight;
  } 
  else if( document.documentElement &&
           ( document.documentElement.clientWidth || 
             document.documentElement.clientHeight ) ) 
  {
    //IE 6+ in 'standards compliant mode'
    sizeObj.objWidth = document.documentElement.clientWidth;
    sizeObj.objHeight = document.documentElement.clientHeight;
  } 
  else if( document.body && 
           ( document.body.clientWidth || document.body.clientHeight ) ) 
  {
    //IE 4 compatible
    sizeObj.objWidth = document.body.clientWidth;
    sizeObj.objHeight = document.body.clientHeight;
  }
  return sizeObj;
}

function getWidth(obj)
{    
  if (obj.style.width)
  {     
   return obj.style.width;
  }

  if (obj.style.pixelWidth)
  {      
    return obj.style.pixelWidth;
  }

  if (obj.offsetWidth)
  {     
    return obj.offsetWidth;
  }

  if (document.defaultView && document.defaultView.getComputedStyle) 
  {    
    return document.defaultView.getComputedStyle(obj,'').getPropertyValue('width');
  }
}

function getHeight(obj)
{    
  if (obj.style.height)
  {     
   return obj.style.height;
  }

  if (obj.style.pixelHeight)
  {      
    return obj.style.pixelHeight;
  }

  if (obj.offsetHeight)
  {     
    return obj.offsetHeight;
  }

  if (document.defaultView && document.defaultView.getComputedStyle) 
  {    
    return document.defaultView.getComputedStyle(obj,'').getPropertyValue('height');
  }
}
/** 
 *  Gets the modified position of the menu left and top.
 *  If the menu shown exceed the browser viewport, makes the menu
 *  div's right boundary to be right aligned with the browser boundary.
 *  How do you get the width?
 */
function getMenuPos(leftPos, topPos, menuDiv)
{
  var menuWidth = parseInt(getWidth(menuDiv)) ;
  var winSize = getWinSize();
  var menuPos = new Object();
  menuPos.leftPos = leftPos;
  menuPos.topPos = topPos;
  
  if (parseInt(winSize.objWidth) - parseInt(leftPos) < menuWidth)
  {
    menuPos.leftPos = winSize.objWidth - menuWidth;
  }
  if ( (parseInt(winSize.objHeight) - parseInt(topPos)) < 100)
  {
    menuPos.topPos = winSize.objHeight - 100;
  }
  return menuPos;
}

/** 
 *  Gets the modified position of the sub menu left and top.
 *  If the sub menu if shown would exceed the browser viewport, makes the menu
 *  div's right boundary to be right aligned with the main menu boundary.
 *  How do you get the width?
 */
function getSubMenuPos(leftPos, 
                       topPos, 
                       mainMenuItem, 
                       subMenuDiv)
{
  var mainMenuDiv = findHoldingDiv(findHoldingDiv(mainMenuItem));  
  var mainMenuDivWidth = getWidth(mainMenuDiv);         
  
  var frameDiv;          
  
  if ( mainMenuDiv.parentNode )
  {
    frameDiv = mainMenuDiv.parentNode;
  }
  else
  {
    frameDiv = findHoldingDiv(mainMenuDiv);
  }      
     
  var frameDivWidth = getWidth(frameDiv);     
  
  var menuPos = new Object();
  menuPos.leftPos = parseInt(frameDivWidth) - 5;
  
  var mainMenuItemDiv = findHoldingDiv(mainMenuItem);  
  menuPos.topPos  = parseInt(mainMenuItemDiv.offsetTop + 12);
  
  return menuPos;
}

/*
 * Shows the menu associated with the elem object. 
 * elem is the Image region that has been clicked.
 */
function showMenu(event, isRTL)
{     
  if (window.event)
  {
    event = window.event;
  }
    
  var elem = (event.target) ? event.target : event.srcElement;
  
  if (_agent.isIE)
  {
      if ( (event.keyCode != '13') && (event.keyCode != '0') )
      {
        return;
      }      
  }
  else
  {
      if ( (event.which != '13') && (event.which != '1') )
      {
        return;
      }        
  }  

  // Reset style of the previously active menu if any to make it gayab.
  hideLastMenuShown();                
  
  var tempElem = 
      document.getElementById(elem.id.substring(0,elem.id.indexOf("_action")));   
  
  var frameParentFrameId = getFrameRootParentFrameId(tempElem);  
  var frameParentFrame = document.getElementById(frameParentFrameId);             

  if ( frameParentFrame != null )
  {
      if ( tempElem.id != getFrameRootParentFrameId(tempElem) && !_agent.isSafari )   
      {          
          var elemId = 'imageBar_' + elem.id.substring(0,elem.id.indexOf("_action")) + '_div1';          
          var frameElem = document.getElementById(elemId);              
          frameParentFrame.parentNode.appendChild(frameElem); 
      }      
  }
  
  var clickedImageRegion = elem; 
  var parentDiv = findHoldingDiv(clickedImageRegion);           
  
  var menuDivId = FRAME_IMAGEBAR_IDENTIFIER_CONST + parentDiv.id;           
  
  menuDivRegion = document.getElementById(menuDivId);            
  
  // if (true), an additional check is made to determine whether the menu to be 
  // shown is the one on a hide-and-show toolbar (FadeIn/FadeOut behavior).
  // If so, the menuDivID representing the dropdown menu is derived from the id 
  // representing the toolBarDiv.Else the function returns.
  
  if ( ! (menuDivRegion) )
  {     
      var originalMenuDivId = menuDivId;
      // Extracting the 11 character long String "_toolbarDiv"
      var toolBarString = menuDivId.substring(menuDivId.length-11,menuDivId.length);           
      
      if ( toolBarString == HIDDEN_TOOLBAR_DIV_IDENTIFIER )
      {                
         // Replacing the 11 character long string "_toolBarDiv" with the string 
         // "_div1"
         menuDivId = menuDivId.substring(0,menuDivId.length-11) + "_div1";         
      }                
      
      menuDivRegion = document.getElementById(menuDivId);         
      
      if ( ! (menuDivRegion) )
      {            
        return;
      }                             
  
      // Setting the currToolBarDiv to the toolBarDiv from which the above 
      // menuDiv has just been dropped.The originalMenuDivId is manipulated to 
      // get the same.This is done each time a menu is successfully dropped
      // from a FadeIn/FadeOut toolbar to keep track of the current toolBar 
      // which has its menu dropped.Later,using this global variable, the 
      // toolBarDiv along with the dropped menu will be hidden in 
      // hideLastMenushown function.      
      
      // Removing the 9 character long "imageBar_" string to get the 
      // current toolBarDiv id
      currToolBarDiv = document.getElementById
                    (originalMenuDivId.substring(9,originalMenuDivId.length));                    
      
  }            

  menuDivRegion.style.display = 'inline'; 
  menuDivRegion.style.position = 'absolute';   
  var frameDiv = findHoldingDiv(parentDiv);            
  
  if (_agent.isIE)
  {
    // In IE, unless the z-Index of this DIV is set to a value more than default, 
    // the menu goes behind the next element. Hence, need to : 
    // 1. reset the style of the div last set and 
    // 2. set the style of this div to a value lower than menuDivRegion              

    frameDiv.style.zIndex = _FRAMEDIV_ZINDEX;                        

    // reset the zIndex of the previously reset frame div
    var lastChangedFrameId = zIndexModifiedFrame[0];

    if (lastChangedFrameId)
    {
      if (lastChangedFrameId != frameDiv.id)
      {
        var lastChangedFrame = document.getElementById(lastChangedFrameId);
        if (lastChangedFrame)
        {         
          lastChangedFrame.style.zIndex = _FRAMEDIV_DFLT_ZINDEX;
        }
      }
    }
  }     
  
  if ( !_agent.isSafari && !_agent.isIE )
  {
      var frameElemId = 'imageBar_' + elem.id.substring(0,elem.id.indexOf("_action")) + '_div1';          
      var frameElemElem = document.getElementById(frameElemId);  
      var itemElem;
      var explicitWidthFlag = true;
      
      var itemElems = frameElemElem.childNodes;
      
      for ( var i=0; i<itemElems.length; i++ )
      {     
        itemElem = itemElems[i]    
        if ( itemElem.offsetWidth > 110 )
        {
            explicitWidthFlag = false; 
            break;
        }
      }   
      
      if ( explicitWidthFlag )
      {
        frameElemElem.style.width = '110px';    
      }    
  }
  var frameDivWidth = getWidth(frameDiv);  
  var menuDivWidth = getWidth(menuDivRegion);              
  
  // With the introduction of the new header-body table, for proper horizontal 
  // positioning of the dropdown menu, instead of the earlier frameDiv, the new
  // table is what will be used as a reference now.Getting the table element 
  // below and using it to calculate the horizontal location of the menu.
  
  var tableElem = document.getElementById(frameDiv.id + '_table');       
  
  if (isRTL)
  {
    if ( tempElem.id != getFrameRootParentFrameId(tempElem) && !_agent.isSafari )
    {
        menuDivRegion.style.left = findPosX(tableElem) + 2 + 'px';
    }
    else
    {
        if ( _agent.isIE )
        {
          menuDivRegion.style.left = '+2px';      
        }
        else
        {
          menuDivRegion.style.left = findPosX(tableElem) + 2 + 'px';
        }
        
    }
  }
  else
  {
    if ( tempElem.id != getFrameRootParentFrameId(tempElem) && !_agent.isSafari )
    {
        menuDivRegion.style.left = (parseInt(tableElem.offsetWidth)) + findPosX(tableElem) 
                                        - parseInt(menuDivWidth) - 2 + 'px';        
    }
    else
    {
        menuDivRegion.style.left = (parseInt(tableElem.offsetWidth)) - parseInt(menuDivWidth) + 2 +'px';      
    }                                        
  }     
  
  
  if ( tempElem.id != getFrameRootParentFrameId(tempElem) && !_agent.isSafari )   
  {                
     menuDivRegion.style.top  = findPosY(frameDiv) + 22 + 'px';       
  }
  else
  {     
     if ( !_agent.isSafari )
     {
        menuDivRegion.style.top  = '+22px';
     }
     else
     {     
        var menuBottomPos = parseInt(findPosY(parentDiv)) + 
                                parseInt(getHeight(parentDiv)) +                          
                                    parseInt(getHeight(menuDivRegion));                                              
                                    
        if ( menuBottomPos > document.body.parentNode.scrollHeight )
        {            
            menuDivRegion.style.bottom  = '+22px';
            menuDirReversedForSafari = true;            
        }
        else
        {            
            menuDivRegion.style.top  = '+22px';
        }                 
     } 
  }   
  
  menuDivRegion.style.zIndex = _MENUBAR_ZINDEX; 
  
  preventEventPropagation(event);
  
  menuBarDiv = menuDivRegion;
  zIndexModifiedFrame[0] = frameDiv.id;
}

/**
 *  anchorElem is the div of the main menu for which sub menu is shown
 */
function showHideSubMenu(anchorElem, isRTL)
{
  //fc1_menuItemSource_showContent
  // Children a tag id is of the form fc1_menuItemSource_showContent
  // fc1 -> id of the holding frame, _menuItemSource - unique id, 
  // _showContent -> the menu item identifier  
    
  var postFixPos = anchorElem.id.indexOf("_menuItemSource") + "_menuItemSource".length;
  var aTagIdPostFixStr = anchorElem.id.substring(postFixPos, anchorElem.id.length);
  
  if (aTagIdPostFixStr == '_showContent')
  {
    showSubMenu(anchorElem, '_showContent', isRTL);
  }
  else
  {
    hideSubMenu(anchorElem, '_showContent');
  }

  if (aTagIdPostFixStr == '_move')
  {
    showSubMenu(anchorElem, '_move', isRTL);
  }
  else
  {
    hideSubMenu(anchorElem, '_move');
  }
}

function hideSubMenu(elem, menuIdentifier)
{
  //var sourceElem = event.srcElement;
  var sourceElem = elem;
  var parentDiv = findHoldingDiv(findHoldingDiv(sourceElem));
  var parentId = parentDiv.id;
  var subMenuId = parentDiv.id + menuIdentifier + FRAME_SUBMENU_CONST;
  var subMenuDiv = document.getElementById(subMenuId);
  
  if (subMenuDiv)
  {
    subMenuDiv.style.display = 'none';
  }
}

function showSubMenu(elem, menuIdentifier, isRTL)
{
  //var sourceElem = event.srcElement;
  var sourceElem = elem;   
  
  var parentDiv = findHoldingDiv(findHoldingDiv(sourceElem));
  var parentId = parentDiv.id;                
  
  // Remove starting from _menuItemSource to get the top-level DIV id.
  // The component table rather than the top-level DIV will now be the 
  // reference for all position calculations.Appending the '_table' for the
  // same.
  var frameElemId = elem.id.substring(0, elem.id.indexOf(MENU_ITEM_SRC_CONST)) 
                                        + '_table';     
  
  var frameElem = document.getElementById(frameElemId);   
  
  var subMenuId = parentDiv.id + menuIdentifier + FRAME_SUBMENU_CONST;
  var subMenuDiv = document.getElementById(subMenuId);           
      
  if (subMenuDiv)
  {
    var tempElem = document.getElementById
                  (elem.id.substring(0, elem.id.indexOf(MENU_ITEM_SRC_CONST)));   
  
    var frameParentFrameId = getFrameRootParentFrameId(tempElem);   
    
    if ( tempElem.id != getFrameRootParentFrameId(tempElem) && !_agent.isSafari )  
    {    
        var frameParentFrame = document.getElementById(frameParentFrameId);                    
        frameParentFrame.parentNode.appendChild(subMenuDiv);
    }
    
    subMenuDiv.style.display = 'inline'; 
    subMenuDiv.style.position = 'absolute';        
   
    var subMenuXPos = getWindowAdjustedMenuXPosition(frameElem, sourceElem, subMenuDiv);
    if (isRTL)
    {     
      if ( tempElem.id != getFrameRootParentFrameId(tempElem) && !_agent.isSafari )  
      {    
        subMenuDiv.style.left = findPosX(frameElem) + 4 - getWidth(subMenuDiv) + 'px';
      }
      else
      {
        if ( _agent.isIE )
        {
            subMenuDiv.style.left = 4 - getWidth(subMenuDiv) + 'px';
        }
        else
        {
            subMenuDiv.style.left = findPosX(frameElem) + 4 - getWidth(subMenuDiv) + 'px';
        }        
      }          
    }
    else
    {     
      if ( tempElem.id != getFrameRootParentFrameId(tempElem) && !_agent.isSafari )  
      {    
        subMenuDiv.style.left = findPosX(frameElem) + subMenuXPos + 'px';
      }
      else
      {
        subMenuDiv.style.left = subMenuXPos + 'px';                    
      }
    }   
    
    if ( tempElem.id != getFrameRootParentFrameId(tempElem) && !_agent.isSafari )  
    {  
        subMenuDiv.style.top =  parseInt(findPosY(parentDiv)) + 5 + 'px';              
    }
    else
    {
        if ( menuDirReversedForSafari )
        {
            subMenuDiv.style.bottom =  (parseInt(sourceElem.offsetTop) + parseInt(sourceElem.offsetHeight) + 5) + 'px';
        }
        else
        {
            subMenuDiv.style.top =  (parseInt(sourceElem.offsetTop) + parseInt(sourceElem.offsetHeight) + 5) + 'px';
        }       
    }
 
    subMenuDiv.style.zIndex = _SUBMENUBAR_ZINDEX;
  }    
  
  subMenuBarDiv = subMenuDiv;
}

function getWindowAdjustedMenuXPosition(frameElement, sourceElem, subMenuDiv)
{
  var mainMenuDiv = findHoldingDiv(findHoldingDiv(sourceElem));
  var retXPos = 0;
  var windowXPos = 0;  
  
  if (self.innerHeight) // all except Explorer
  {
    windowXPos = self.innerWidth;
  }
  else if (document.documentElement && document.documentElement.clientHeight)
    // Explorer 6 Strict Mode
  {
    windowXPos = document.documentElement.clientWidth;
  }
  else if (document.body) // other Explorers
  {
    windowXPos = document.body.clientWidth;
  }
  
  var subMenuXPos = parseInt(frameElement.offsetWidth);   
  
  var mainMenuWidth = getWidth(mainMenuDiv);
  
  // To calculate the xPos, we add the PosX of the subMenu, the PosX of the 
  // containing frameElement and the width of the subMenuDiv.We need the PosX 
  // of the containing frameElement since the subMenuXPos is calculated from 
  // the start of the immediate,containing DIV rather than the start of the 
  // top-level,containing DIV.
  
  var xPos = subMenuXPos + findPosX(frameElement) + parseInt(getWidth(subMenuDiv));   
  
  if (xPos > windowXPos)
  {    
    retXPos = subMenuXPos - parseInt(mainMenuWidth) - parseInt(getWidth(subMenuDiv)) + 2;
  }
  else
  {
    retXPos = subMenuXPos - 5;
  }         
  
  return retXPos;
}

function displayShowcontentsSubmenuFromToolbar(event, elem)
{
  // Reset style of the previously active menu if any to make it gayab.
  if (window.event)
  {
    event = window.event;
  }
  hideLastMenuShown();

  var sourceElem = elem;
  var clickImageRegion = elem; 
  
  // elemId of the form OutterMostSDF_menuItemSource_showContent
  var frameElemId = elem.id.substring(0, elem.id.indexOf(MENU_ITEM_SRC_CONST));
  
  //div id of the form imageBar_OutterMostSDF_div1_showContent_subMenu
  var showContentsDivId = FRAME_IMAGEBAR_IDENTIFIER_CONST + frameElemId + '_div1_showContent' + FRAME_SUBMENU_CONST;
  
  var subMenuDiv = document.getElementById(showContentsDivId);
  if (subMenuDiv)
  {
    subMenuDiv.style.display = 'inline'; 
    subMenuDiv.style.position = 'absolute'; 

    subMenuDiv.style.left = findPosX(sourceElem) - 8 + 'px';
    subMenuDiv.style.top =  (findPosY(sourceElem) + 12) + 'px'; 

    subMenuDiv.style.zIndex = _SUBMENUBAR_ZINDEX;
  }

  preventEventPropagation(event);
  
  subMenuBarDiv = subMenuDiv;  
}

function hideLastMenuShown()
{
  menuDirReversedForSafari = false;  
  if (subMenuBarDiv)
  {
    subMenuBarDiv.style.display = 'none';
    
    if (!_agent.isSafari)
    {
        // Getting the header DIV
        var headerOrToolBarDiv = document.getElementById(menuBarDiv.id.substring(9,menuBarDiv.id.length));
        
        // If header DIV is null, it implies header is not displayed.Getting the toolBarDiv in that case.
        if ( headerOrToolBarDiv == null )
        {       
          var toolBarDivId = menuBarDiv.id.substring(9,menuBarDiv.id.length)
          toolBarDivId = toolBarDivId.substring(0,toolBarDivId.indexOf('_div1')) + '_toolbarDiv'        
          headerOrToolBarDiv = document.getElementById(toolBarDivId);    
        }                            
        
        headerOrToolBarDiv.parentNode.appendChild(subMenuBarDiv);
    }        
    
    subMenuBarDiv = null;    
  } 
  
  if (menuBarDiv)
  {     
    menuBarDiv.style.display = 'none';      
    
    if (!_agent.isSafari)
    {
        // Getting the header DIV
        var headerOrToolBarDiv = document.getElementById(menuBarDiv.id.substring(9,menuBarDiv.id.length));
        
        // If header DIV is null, it implies header is not displayed.Getting the toolBarDiv in that case.
        if ( headerOrToolBarDiv == null )
        {
          var toolBarDivId = menuBarDiv.id.substring(9,menuBarDiv.id.length)
          toolBarDivId = toolBarDivId.substring(0,toolBarDivId.indexOf('_div1')) + '_toolbarDiv'        
          headerOrToolBarDiv = document.getElementById(toolBarDivId);    
        }       
        
        headerOrToolBarDiv.parentNode.appendChild(menuBarDiv);
        
    }
    
    menuBarDiv = null;
    
    // Hide the last shown toolBarDiv.
    // hovering == 'true' implies mouse is within the contentarea and the toolbar is 
    // draped.In such a case, only the menu dropped from the toolbar needs to be 
    // hidden.The toolbar should be hidden only when the mouse is out of the 
    // content area, in which case hovering is 'false'.
    if (currToolBarDiv && (hovering == false) )
    {        
      currToolBarDiv.style.display = 'none';    
    }   
    
    currToolBarDiv = null;
  }  
}

/**
 *  Finds and returns the next peer for which id exists.
 *
 *  If the frame is in panelCustomizable, the parent will be 
 *  TD. In this case, will have to move the whole TD tag.
 *  However, this should be done only if no direct peer exists.
 *
 * 
 */
function findFrameNextPeerId(frameElem, frameElemParent)
{
  var numFramePeers = frameElemParent.childNodes.length;
  var thisFrameFound = false;
  for (var i = 0; i < numFramePeers; i++)
  {
    var peerTag = frameElemParent.childNodes.item(i);
    if (peerTag.id)
    {
      if (peerTag.id == frameElem.id)
      {
        thisFrameFound = true;
        continue;
      }

      if (thisFrameFound)
      {
        return peerTag.id;
      }
    }
  }
}

function toggleShowHideFrameMenuIcon(anchorElem)
{
  var anchorId = anchorElem.id;
  // If id ends with _menuItemSource_hide_subMenu then the current state is
  // hidden and the next state should be shown.
  // If id ends with _menuItemSource_hide_subMenu, the current state is shown
  // and the next state should be hidden.

  // To find endwith for a string, 
  // mainstr.substring(lastIndexOf(str) + length(str) == mainstr.length

  if ( (anchorId.lastIndexOf('_menuItemSource_hide_subMenu') + '_menuItemSource_hide_subMenu'.length) == anchorId.length)
  {
    //currentMenu is shown and need to hide this and show "hide" menu
    var nextAnchorId = anchorId.substring(0, anchorId.lastIndexOf('_menuItemSource_hide_subMenu'));
    nextAnchorId = nextAnchorId + '_menuItemSource_showContent_subMenu';
  }
  else
  {
    var nextAnchorId = anchorId.substring(0, anchorId.lastIndexOf('_menuItemSource_showContent_subMenu'));
    nextAnchorId = nextAnchorId + '_menuItemSource_hide_subMenu';
  }
    
  var currentMenuHoldingDiv = findHoldingDiv(anchorElem);
  var nextMenuHoldingDiv    = findHoldingDiv(document.getElementById(nextAnchorId));
  currentMenuHoldingDiv.style.display = 'none';
  nextMenuHoldingDiv.style.display = 'inline';
}

/**
 *  Modifies individual menu item - div or icon is decided by the funtion itself
 *  
 *  enableMenu = true -> show the item else hide it
 */
function modifyMenuItem(frameId, moveConst, enableMenu)
{
  var subMenuItemId = frameId + "_menuItemSource_" + moveConst;
  var subMenuItem   = document.getElementById(subMenuItemId);
  
  // First find out the display style  menu or toolbar and then show/hide it as 
  // the case may be. imageBar_sdf2_div1
  var menuDivId = FRAME_IMAGEBAR_IDENTIFIER_CONST + frameId + '_div1';
  var menuDiv   = document.getElementById(menuDivId);
  
  if (menuDiv)
  {
    showHideMenuItemDiv(subMenuItemId, enableMenu);
  }
  else // is a menu icon
  {
    if (subMenuItem)
    {
      if (enableMenu)
        subMenuItem.style.display = 'inline';
      else
        subMenuItem.style.display = 'none';
    }
  }
}

function modifyPeerFrameMenus(frameElem,restoreFlag)
{
  var currentFrameId = frameElem.id;
  var frameParentFrameId = getFrameParentFrameId(frameElem);
  var frameParentFrame = document.getElementById(frameParentFrameId);
  if (frameParentFrame == null)
  {
    // Do partial submit and return
    return false;
  }
  
  var frameChildrenArray = getFrameChildrenFrames(frameParentFrame,false);
  if (frameChildrenArray == null)
  {
    // Do partial submit and return
    return false;
  }

  var numFrames = frameChildrenArray.length;     
    
  // modify the move menus of the peer frames     
  modifyPeerFrameMoveMenus(frameChildrenArray,currentFrameId);
  
  // Readjust the main menus of the peer frames after the move menus 
  // modification above.
  for (var i = 0; i < numFrames; i++)
  {  
     if ( frameChildrenArray[i] != currentFrameId )
     {
        modifyMainMenuDiv(frameChildrenArray[i],restoreFlag);
     }
  }  
  
}

/**
 *  Called after removing frames to modify neighbouring frame's menu options.
 *  The algo followed is, after removing a sdf, if a child exists after this
 *  sdf, for the child before this, no change needs to be done. If no child 
 *  after this, for the child before this, move left / move down menu option
 *  should be hidden.
 *  Similarely for the sdf before.
 *
 *   enableMenu = true -> if menu should be enabled / false if hidden
 *
 */
function modifyPeerFrameMoveMenus(frameChildrenArray,currentFrameId)
{  
  var numFrames = frameChildrenArray.length;
  
  var frameIdBeforeCurrentFrame = null;
  var frameIdAfterCurrentFrame  = null;
  
  var thisFrameIndex = 0;
  // Get the new frame children array
  for (var i = 0; i < numFrames; i++)
  {
    var peerFrameId = frameChildrenArray[i];
    if (peerFrameId)
    {
      if (peerFrameId == currentFrameId)
      {
        thisFrameIndex = i;
        break;
      }
    }
  }
  
  var frameVisibleBeforeCurrentFrame = 
    getFrameVisibleBeforeThisFrame(thisFrameIndex, 
                                   frameChildrenArray);

  if (frameVisibleBeforeCurrentFrame)
  {
    modifyMoveMenus(frameVisibleBeforeCurrentFrame);
  }

  var frameVisibleAfterCurrentFrame = 
    getFrameVisibleAfterThisFrame(thisFrameIndex, 
                                  frameChildrenArray);

  if (frameVisibleAfterCurrentFrame)
  {
    modifyMoveMenus(frameVisibleAfterCurrentFrame);
  }
}

/**
 *  From the metadata, check if :
 *  any frame elem visible before this frame -> display move up menu.
 *  any frame elem visible after this frame ->  display move down menu.
 *  if no element visible before or after this frame, hide move menu itself
 */
function modifyMoveMenus(frameElem)
{
  //alert('entered modifyMoveMenus');
  var currentFrameId = frameElem.id;
  var frameParentFrameId = getFrameParentFrameId(frameElem);
  var frameParentFrame = document.getElementById(frameParentFrameId);
  if (frameParentFrame == null)
  {
    // Do partial submit and return
    return false;
  }
  
  var frameChildrenArray = getFrameChildrenFrames(frameParentFrame,false);
  if (frameChildrenArray == null)
  {
    // Do partial submit and return
    return false;
  }
  
  var numFrames = frameChildrenArray.length;
  
  var frameIdBeforeCurrentFrame = null;
  var frameIdAfterCurrentFrame  = null;
  
  var thisFrameIndex = 0;
  // Get the new frame children array
  for (var i = 0; i < numFrames; i++)
  {
    var peerFrameId = frameChildrenArray[i];
    if (peerFrameId)
    {
      if (peerFrameId == currentFrameId)
      {
        thisFrameIndex = i;
        break;
      }
    }
  }
  
  var frameVisibleBeforeCurrentFrame = 
    getFrameVisibleBeforeThisFrame(thisFrameIndex, 
                                   frameChildrenArray);

  var enableMoveUpMenu = false;
  if (frameVisibleBeforeCurrentFrame)
  {
    enableMoveUpMenu = true;
  }
  modifyMenuItem(currentFrameId, FRAME_MOVEUP_CONST + FRAME_SUBMENU_CONST, enableMoveUpMenu);

  var frameVisibleAfterCurrentFrame = 
      getFrameVisibleAfterThisFrame(thisFrameIndex, 
                                    frameChildrenArray);
  
  var enableMoveDnMenu = false;
  if (frameVisibleAfterCurrentFrame)
  {
    enableMoveDnMenu = true;
  }
  modifyMenuItem(currentFrameId, FRAME_MOVEDN_CONST + FRAME_SUBMENU_CONST, enableMoveDnMenu);
  
  // If no frame visible before and after this frame, hide the move menu itself
  // but the move menu will be present only when the actions style is dropwDown so
  // first checkif the style is dropdown and if yes, hide the move menu
  
  // imageBar_sdf2_div1
  var menuDivId = FRAME_IMAGEBAR_IDENTIFIER_CONST + currentFrameId + '_div1';
  var menuDiv   = document.getElementById(menuDivId);

  if (menuDiv)
  {
    var moveMenuItemId = currentFrameId + MENU_ITEM_SRC_CONST + '_move';
    var showMoveMenu = true;
    if ( (frameVisibleBeforeCurrentFrame == null) &&
         (frameVisibleAfterCurrentFrame == null) )
    {
      showMoveMenu = false;
    }
    showHideMenuItemDiv(moveMenuItemId, showMoveMenu);    
  }
}


function getFrameVisibleBeforeThisFrame(thisFrameIndex, frameChildren)
{
  var numFrames = frameChildren.length;
  var i = thisFrameIndex;
  while (i >= 1)
  {
    var peerFrameId = frameChildren[i-1];
    var peerFrame = document.getElementById(peerFrameId);
    if (peerFrame)
    {
      return peerFrame;
    }
    i--;
  }
  return null;
}

function getFrameVisibleAfterThisFrame(thisFrameIndex, frameChildren)
{
  var numFrames = frameChildren.length;
  for (var i = thisFrameIndex; i < numFrames; i++)
  {
    var peerFrameId = frameChildren[i+1];
    var peerFrame = document.getElementById(peerFrameId);
    if (peerFrame)
    {
      return peerFrame;
    }
  }
  return null;
}


/*
 * Removes the frame.
 * This can be called from two places:
 * 1. from parent remove menu option
 * 2. remove menu option directly on the frame. 
 * in either case, just pass the frame id to be removed which gets updated in 
 * modifiedFrameComps table with frameId as the key. This can later be retrieved from 
 * the hash table when it's time to show this frame
 *
 */
function removeFrameDiv(frameId)
{
  // When removing, store the removed frame, the frame before which this frame existed and 
  // the name of the parent node of this frame. Also, find the holding div for this
  // frame and then find the id of the menu item through which the frame can be retrieved.
  // once the anchor tag retrieved, set the source to be unchecked.gif
  
  var frameElem = document.getElementById(frameId);
  var frameElemParent = frameElem.parentNode;
  
  var nextPeerId = findFrameNextPeerId(frameElem, frameElemParent);
  
  modifiedFrameComps[frameId] = frameElem;
  modifiedFrameComps[frameId].beforeElem = nextPeerId;
  modifiedFrameComps[frameId].parentNodeId = frameElemParent.id;
  
  if ( _agent.isSafari )
  {
    frameElem.style.display = 'none';
    return false;
  }
  frameElemParent.removeChild(frameElem);
  
  return false;
}

/*
 *  Return false to indicate component retrieved from client side 
 *  true indicates a partial submit had occured and no firther 
 *  processing required on client side.
 */
function showHiddenFrame(event, elem)
{
  // When showing the frame thru show (frame title), from the anchor id clicked, 
  // find the id of the frame to be shown, from modifiedFrameComps, find the frame.
  // now from this found frame, get the parent, and the "insertBefore" item.
  // Get the DOM Element corresponding to this insertBefore item and then call
  // parentNode.insertBefore(). If no insertBefore item exists, this any ways 
  // should lead to this frame being the first child.

  var toBeShownFrameId = elem.id.substring(0, elem.id.indexOf("_menuItemSource") );  
  var toBeShownFrame = modifiedFrameComps[toBeShownFrameId];     
  
  delete modifiedFrameComps[toBeShownFrameId];        
  
  if ( toBeShownFrame == null )  
  {
    // do partial submit on the form
    // parent frame id to be retireved from id:
    var holdingDivId = findHoldingDiv(findHoldingDiv(elem)).id;
    
    var parentFrameId = holdingDivId.substring(FRAME_IMAGEBAR_IDENTIFIER_CONST.length, holdingDivId.indexOf("_div1_showContent_subMenu"));
    var formElem = findFormElem(elem);
    // doValidate 1 is false.
    // construct the elem id so that submit takes care of it.
    var submitSource = parentFrameId + "_menuItemSource_" + toBeShownFrameId + "showContent" + "_subMenu";
    //_submitPartialChange(formElem, 1, {partialTargets:parentFrameId, event:'show', source:submitSource});
    submitForm(formElem, 0, {partialTargets:parentFrameId, event:'show', source:submitSource});
    return true;
  }
  else
  {    
    if ( _agent.isSafari )
    {
        toBeShownFrame.style.display = '';
        return toBeShownFrame;
    }
    var toBeShownFrameParentId = toBeShownFrame.parentNodeId;
    var toBeShownFrameParent = document.getElementById(toBeShownFrameParentId);

    // toBeShownFrame.beforeElem can be null if it's only child
    if (toBeShownFrame.beforeElem)
    {
      var insertBeforeElemId = toBeShownFrame.beforeElem;
      var beforeElem = document.getElementById(insertBeforeElemId);
      toBeShownFrameParent.insertBefore(toBeShownFrame, beforeElem);
    }
    else
    {
      toBeShownFrameParent.appendChild(toBeShownFrame);
    }  
    return toBeShownFrame;
  }
}

function retainParentWidth(frameElem)
{  
  var frameParentFrameId = getFrameParentFrameId(frameElem);
  var frameParentTableId = frameParentFrameId + '_table';
  var frameParentTableElem = document.getElementById(frameParentTableId);
  
  if ( frameParentTableElem )
  {  
      showHideParentWidths[frameParentTableId] = frameParentTableElem.style.width;         
      frameParentTableElem.style.width = frameParentTableElem.offsetWidth + 'px';  
  }
}

function showHideFrameFromMenu(event, elem)
{
  if (window.event)
  {
    event = window.event;
  }
    
  if ( elem == null )
  {
    elem = (event.target) ? event.target : event.srcElement; 	
  }
  
  if (_agent.isIE)
  {
      if ( (event.keyCode != '13') && (event.keyCode != '0') )
      {
        return;
      }      
  }
  else
  {
      if ( (event.which != '13') && (event.which != '1') )
      {
        return;
      }        
  }
  
  //var childFrameDisclosed = getMenuItemState(elem);
  var frameId = elem.id.substring(0, elem.id.indexOf("_menuItemSource"));
  var frameElem = document.getElementById(frameId);
  
  // if frameElem exists, this call must be to hide the frame else it must be to show the frame
  var childFrameDisclosed = false;
  if (frameElem && !_agent.isSafari )
  {    
    childFrameDisclosed = true;
  }   
  
  if ( _agent.isSafari && frameElem.style.display != 'none' )
  {
    childFrameDisclosed = true;
  }
  
  if (childFrameDisclosed)
  {    
    // already disclosed. call hide.
    sendMessage(frameElem, elem.id, false);
    retainParentWidth(frameElem);
    removeFrameDiv(frameId);    
    // modify the menus of the peer frames after the above frame removal.
    // "false" indicates this is a forward operation.
    modifyPeerFrameMenus(frameElem,false);
  }
  else
  {
    // Not disclosed. Call to show the frame
    var retVal = showHiddenFrame(event, elem);  
    // retVal will indicate if it was a partial submit 
    // or, if the frame was restored, the restored frame element
    if (retVal == true)
    {
      return;
    }       
        
    var childDivOfThisFrame = findHoldingDiv(findHoldingDiv(elem));
    var thisFrameDivId = childDivOfThisFrame.id.substring(0,childDivOfThisFrame.id.indexOf('_div1'));
    // Removing the 9 character long "imageBar_" string to get this frame's id.
    thisFrameDivId = thisFrameDivId.substring(9,thisFrameDivId.length);        
    
    var thisFrameDiv = document.getElementById(thisFrameDivId);
    
    var submitSource = thisFrameDiv.id + "_menuItemSource_" + frameId + "showContent" + "_subMenu";
    // Changing the submitSource as this is what is expected on the server side.    
    sendMessage(elem, submitSource, false);    
    frameElem = document.getElementById(frameId);
    // modify the menus of the peer frames after the bringing bakc the hidden 
    // frame.
    // "true" indicates this is a reverse (restore) operation.
    modifyPeerFrameMenus(frameElem,true);
    modifyMoveMenus(frameElem);
  }

  toggleShowHideFrameMenuIcon(elem);
  
  hideLastMenuShown();

  return false;
}

// Moves the frame on the client side. Handles both moveUp and moveDown options
function moveFrame(event, elem)
{ 
  if (window.event)
  {
    event = window.event;
  }
       
  if ( elem == null )
  {
    elem = (event.target) ? event.target : event.srcElement; 	
  }

  if (_agent.isIE)
  {
      if ( (event.keyCode != '13') && (event.keyCode != '0') )
      {
        return;
      }      
  }
  else
  {
      if ( (event.which != '13') && (event.which != '1') )
      {
        return;
      }        
  }
  
  //sDFTableContent_menuItemSource_moveDown_subMenu
  var toBeMovedFrameId = elem.id.substring(0, elem.id.indexOf(MENU_ITEM_SRC_CONST));  
  
  var frameElem = document.getElementById(toBeMovedFrameId);   
  
  // Do safari specific handling =-=rbaranwa  
  if (_agent.isSafari)
  {
    // Safari browser does not recognize comment node hence all such calculation
    // goes haywire. The workaround is to do a partial page submit
    var formElem = findFormElem(elem);
    _submitPartialChange(formElem.id, 
                         0,
                         {partialTargets:frameElem.id,
                         event:'move', 
                         source: elem.id });
    return false;
  }

  var moveDestination = elem.id.substring(elem.id.indexOf(MENU_ITEM_SRC_CONST) + 
                                          MENU_ITEM_SRC_CONST.length + 1 , //+1 for trailing '_'
                                          (elem.id.lastIndexOf(FRAME_SUBMENU_CONST) ) );
  
  var frameParentFrameId = getFrameParentFrameId(frameElem);
  var frameParentFrame = document.getElementById(frameParentFrameId);
  var frameChildrenArray = getFrameChildrenFrames(frameParentFrame,true);
  var autoMovedFrameId = ''; // Id of the frame that has moved as a result of user specified frame movement.
  
  
  // hide the menus last shown so that we start with a clean slate
  // This is done right at the beginning as with node cloning on, 
  // hideLastMenuShown would not work.
  hideLastMenuShown();
  
  if (moveDestination == FRAME_MOVEDN_CONST) // same will be the process for moveRight
  {
    var frameAfterFrameId   = getFrameAfterThisFrameId(frameChildrenArray, toBeMovedFrameId);       
    autoMovedFrameId        = frameAfterFrameId;
    var frameAfterFrameElem = document.getElementById(frameAfterFrameId);             
    swapFrameNodes(frameElem, frameAfterFrameElem);   
  }
  if (moveDestination == FRAME_MOVEUP_CONST) // same will be the process for moveLeft
  {
    var frameBeforeFrameId   = getFrameBeforeThisFrameId(frameChildrenArray, toBeMovedFrameId);
    autoMovedFrameId         = frameBeforeFrameId;
    var frameBeforeFrameElem = document.getElementById(frameBeforeFrameId);
    swapFrameNodes(frameElem, frameBeforeFrameElem);
  }

  // Now that the move has happened, change the metadata comment to indicate current 
  // positions so that next move is handled correctly.
  changeMetadataCommentChildrenSequence(frameParentFrame, 
                                        toBeMovedFrameId, 
                                        autoMovedFrameId, 
                                        moveDestination);

  // Now that the move has happened, need to modify the menu options on the frame that has been moved
  // as a result of direct user action and also on the frame that has meved because user moved frame moved.
  
  // Get the new frame children array
  var newFrameChildrenArray = getFrameChildrenFrames(frameParentFrame,true);
  var numPeerFrames = newFrameChildrenArray.length;
  
  // if the moveDestination is down, check if the frame being moved was the first frame
  // if so, it needs to have moveUp menu option also enabled on it.
  // Since it was the first frame, the auto moved frame will now become the first frame
  // and hence should have only moveDown menu option available on it.
  if (moveDestination == FRAME_MOVEDN_CONST) // same will be the process for moveRight
  {
    var toBeMovedFrameNewPosition = getFramePosition(newFrameChildrenArray, toBeMovedFrameId);       
    
    // Move up should always be available on the frame being moved down, hence enable it.
    var moveUpMenuOptionId = toBeMovedFrameId + "_menuItemSource_" + FRAME_MOVEUP_CONST + FRAME_SUBMENU_CONST;        
    showHideMenuItemDiv(moveUpMenuOptionId, true);            
    
    if (toBeMovedFrameNewPosition == numPeerFrames)
    {      
      // This frame has moved to the edges. Modfify it's menu item to not contain moveDown menu.
      var moveDnMenuOptionId = toBeMovedFrameId + "_menuItemSource_" + FRAME_MOVEDN_CONST + FRAME_SUBMENU_CONST;      
      showHideMenuItemDiv(moveDnMenuOptionId, false);
    }
    
    // since the operation is moveDown, the auto moved (which would have moved up)
    // frame's moveDown should always be available. Enable this menu.
    var autoMovedFrameMoveDnOptionId = autoMovedFrameId + "_menuItemSource_" + FRAME_MOVEDN_CONST + FRAME_SUBMENU_CONST;      
    showHideMenuItemDiv(autoMovedFrameMoveDnOptionId, true);   
    
    // if the autoMoved frame has moved to the top, need to disable it's 
    // move up menu option. 
    if (toBeMovedFrameNewPosition == 2)
    {
      var autoMovedFrameMoveUpOptionId = autoMovedFrameId + "_menuItemSource_" + FRAME_MOVEUP_CONST + FRAME_SUBMENU_CONST;
      showHideMenuItemDiv(autoMovedFrameMoveUpOptionId, false);
    }
  }
  else if (moveDestination == FRAME_MOVEUP_CONST)
  {
    // if the moveDestination is up, check if the frame being moved was the last frame
    // If so, it needs to have moveDn menu option also enabled on it.
    // Since it was the last frame, the autoMovedFrame will now become last frame and 
    // hence it should have only moveUp menu option available on it now.
    
    var toBeMovedFrameNewPosition = getFramePosition(newFrameChildrenArray, toBeMovedFrameId);
    
    // Since the frame is being moved up, moveDown should always be available on it.
    var moveDnMenuOptionId = toBeMovedFrameId + "_menuItemSource_" + FRAME_MOVEDN_CONST + FRAME_SUBMENU_CONST;
    showHideMenuItemDiv(moveDnMenuOptionId, true);

    if (toBeMovedFrameNewPosition == 1)
    {
      // This frame has reached at top. moveUp should not be available on this.
      var moveUpMenuOptionId = toBeMovedFrameId + "_menuItemSource_" + FRAME_MOVEUP_CONST + FRAME_SUBMENU_CONST;
      showHideMenuItemDiv(moveUpMenuOptionId, false);
    }
    
    // since the operation is moveUp, the auto moved (which would have moved down)
    // frame's moveUp should always be available. Enable this menu.
    var autoMovedFrameMoveUpOptionId = autoMovedFrameId + "_menuItemSource_" + FRAME_MOVEUP_CONST + FRAME_SUBMENU_CONST;
    showHideMenuItemDiv(autoMovedFrameMoveUpOptionId, true);
    
    // if the autoMoved frame has moved to the bottom, need to disable it's 
    // move down menu option. 
    var toBeMovedFrameOldPosition = getFramePosition(frameChildrenArray, toBeMovedFrameId);
    if (toBeMovedFrameOldPosition == numPeerFrames)
    {
      var autoMovedFrameMoveDnOptionId = autoMovedFrameId + "_menuItemSource_" + FRAME_MOVEDN_CONST + FRAME_SUBMENU_CONST;
      showHideMenuItemDiv(autoMovedFrameMoveDnOptionId, false);
    }
  }
  
  sendMessage(frameParentFrame, elem.id, true);
  return false;
}

/**
 *  Shows / hides the menu item containing div.
 *  show = true -> menu option should be displayed. false -> hide the menu option
 */
function showHideMenuItemDiv(menuItemId, show)
{    
  var menuOption = document.getElementById(menuItemId);       
  
  if ( menuOption )
  {
    var menuOptionHoldingDiv = findHoldingDiv(menuOption);
    if (show == true)
    {
      menuOptionHoldingDiv.style.display = 'inline';
    }
    else
    {
      menuOptionHoldingDiv.style.display = 'none';
    }
  }
}

/**
 *  Gets position of frame in the array list. This is on a 1 based index.
 */
function getFramePosition(peerFrameArray, frameId)
{
  var numPeers = peerFrameArray.length;
  for (var i = 0; i < numPeers; i++)
  {
    if (frameId == peerFrameArray[i])
    {
      return ++i;
    }
  }
  return -1;
}

/**
 *  Changes the metadata comment associated with frameParentFrame
 *  to reflect the new order of children frames after the move has 
 *  happened. 
 */
function changeMetadataCommentChildrenSequence(frameParentFrame, 
                                               movedFrameId, 
                                               autoMovedFrameId, 
                                               moveDestination)
{
  var commentNode = getFrameChildrenFramesCommentsNode(frameParentFrame);
  if (commentNode == null)
  {
    alert('unexpected error: frame parent does not have metadata comment');
    return;
  }
  var commentNodeData = commentNode.data;
  var changedString = commentNodeData;
  // need to replace movedFrameId with autoMovedFrameId in commentNodeData
  
  if (moveDestination == FRAME_MOVEDN_CONST)
  {
    // movedFrameId will occur before autoMovedFrameId in the commentNodeData
    // else it will occur after comments node data
    var indexMovedFrameId = commentNodeData.indexOf(movedFrameId);
    var strTillMovedFrameId = commentNodeData.substring(0, indexMovedFrameId + movedFrameId.length);
    strTillMovedFrameId = strTillMovedFrameId.replace(movedFrameId, autoMovedFrameId);
    
    var strAfterMovedFrameId = commentNodeData.substring(indexMovedFrameId + movedFrameId.length, commentNodeData.length);
    strAfterMovedFrameId = strAfterMovedFrameId.replace(autoMovedFrameId, movedFrameId);
    
    changedString = strTillMovedFrameId + strAfterMovedFrameId;
  }
  
  if (moveDestination == FRAME_MOVEUP_CONST)
  {
    // movedFrameId will occur before autoMovedFrameId in the commentNodeData
    // else it will occur after comments node data
    var strPartOneIndex = commentNodeData.indexOf(autoMovedFrameId);
    var strPartOne = commentNodeData.substring(0, strPartOneIndex + autoMovedFrameId.length);
    strPartOne = strPartOne.replace(autoMovedFrameId, movedFrameId);
    
    var strPartTwo = commentNodeData.substring(strPartOneIndex + autoMovedFrameId.length, commentNodeData.length);
    strPartTwo     = strPartTwo.replace(movedFrameId, autoMovedFrameId);

    changedString = strPartOne + strPartTwo;
  }
  commentNode.data = changedString;
}

/**
 *  Swaps the frame nodes by moving fromFrameNode -> toFrameNode and toFrameNode -> fromFrameNode
 *  This changes the DOM Tree by swapping these nodes mutually.
 *  parent frame of this frame. Return this id - part of the data that the comment has.
 */
function swapFrameNodes(fromFrameNode, toFrameNode)
{
  var fromNodeParent = fromFrameNode.parentNode;
  var toNodeParent   = toFrameNode.parentNode;   
  
  var fromNodeNextSibling = fromFrameNode.nextSibling;
  var toNodeNextSibling   = toFrameNode.nextSibling;            
  
  var fromNodeForSwitch = fromFrameNode;
  var toNodeForSwitch = toFrameNode;  
  
  // The original cloning approach could have been avoided.Still retaining 
  // it for the safari browser since things worked fine with the clone approach 
  // for safari.
  if ( _agent.isSafari )
  {
    fromNodeForSwitch  = fromFrameNode.cloneNode(true);     
    toNodeForSwitch    = toFrameNode.cloneNode(true);
    fromNodeParent.removeChild(fromFrameNode);             
    toNodeParent.removeChild(toFrameNode);
  }    
  
  if (fromNodeNextSibling == null)
  {    
    fromNodeParent.appendChild(toNodeForSwitch);
  }
  else
  {    
    fromNodeParent.insertBefore(toNodeForSwitch, fromNodeNextSibling);
  }  
  
  if (toNodeNextSibling == null)
  {      
    toNodeParent.appendChild(fromNodeForSwitch);
  }
  else
  {     
    // if from frame node.id == toNodeNextSibling.id, just do an append    
    
    if (toNodeNextSibling.id)
    {      
      if (fromFrameNode.id == toNodeNextSibling.id)
      {
        toNodeParent.insertBefore(fromNodeForSwitch, toNodeForSwitch);
      }
      // When the toNode has a next sibling, this else part inserts the 
      // fromNodeClone before the toNodeNextSibling
      else
      {        
          toNodeParent.insertBefore(fromNodeForSwitch, toNodeNextSibling);
      }
    }
    else
    {        
      toNodeParent.insertBefore(fromNodeForSwitch, toNodeNextSibling);
    }    
  }      

}

/**
 *  Get the child node comment. This comment node's data specifies which is the
 *  parent frame of this frame. Return this id - part of the data that the comment has.
 */
function getFrameParentFrameId(frameElem)
{
  var frameChildren = frameElem.childNodes;
  var childrenLen = frameChildren.length;
  var parentFrameId = "";
  for (var i = 0; i < childrenLen; i++)
  {
    var childNode = frameChildren.item(i);
    if (childNode.nodeType == 8)//COMMENT_NODE == 8;
    {
      // Check if it is a comment from showDetailFrame specifying frame parent.
      //_sdf_parent_identif_ -> identifier for parent frame
      var nodeData = childNode.data;
      if (nodeData.indexOf(FRAME_PARENT_IDENTIFIER_CONST) > -1)
      {
        parentFrameId = nodeData.substring(FRAME_PARENT_IDENTIFIER_CONST.length, nodeData.length);
        return trimString(parentFrameId);
      }
    }
  }
  return null;
}

/**
 *  Get the child node comment. This comment node's data specifies which is the
 *  root parent frame of this frame. Return this id - part of the data that the comment has.
 *  Root parent is the showDetailFrame appearing farthest up in the hierarchy of the showDetailFrame
 *  when viewed with root on top
 */
function getFrameRootParentFrameId(frameElem)
{
  // This DIV represents the DIV rendered specially to hold information 
  // pertaining to the root-level frame.
  var rootParentInfoDiv = document.getElementById( frameElem.id + '_rootParentInfoDiv');   
  var frameChildren = rootParentInfoDiv.childNodes;
  var childrenLen = frameChildren.length;
  var parentFrameId = "";
  for (var i = 0; i < childrenLen; i++)
  {
    var childNode = frameChildren.item(i);
    if (childNode.nodeType == 3)//TEXT_NODE == 3;
    {
      // Check if it is a comment from showDetailFrame specifying frame parent.
      //_sdf_parent_identif_ -> identifier for parent frame
      var nodeData = childNode.data;
      if (nodeData.indexOf(FRAME_ROOT_PARENT_IDENTIFIER_CONST) > -1)
      {
        parentFrameId = nodeData.substring(FRAME_ROOT_PARENT_IDENTIFIER_CONST.length, nodeData.length);
        return trimString(parentFrameId);
      }
    }
  }
  return null;
}

/**
 *  Get the child node comment. This comment node's data specifies the list of children
 *  the frame has. Among these the move is going to happen. Return this Array of ids.
 */
function getFrameChildrenFrames(frameElemParent,onDisplayFlag)
{
  var commentNode = getFrameChildrenFramesCommentsNode(frameElemParent);
  if (commentNode == null)
  {
    // Do some logging / alert also?
    return null;
  }
  var nodeData = commentNode.data;
  var childrenIdString = nodeData.substring(FRAME_CHILDLIST_ID_CONST.length + 1, // +1 for leading '_'
                                            nodeData.length);
          
  var childrenIdList = trimString(childrenIdString).split(FRAME_CHILD_SEPARATOR_CONST);
  
  if ( onDisplayFlag )
  {
      for ( var i=0; i<childrenIdList.length; i++ )
      {
        if ( childrenIdList[i] in modifiedFrameComps )
        {        
            childrenIdList.splice(i,1);
        }
      }  
  }
  
  return childrenIdList;
}

/**
 *  Get the child node comment. This comment node's data specifies the list of children
 *  the frame has. 
 */
function getFrameChildrenFramesCommentsNode(frameElemParent)
{
  var children = frameElemParent.childNodes;
  var childrenLen = children.length;
  var childrenIdString = "";
  for (var i = 0; i < childrenLen; i++)
  {
    var childNode = children.item(i);
    if (childNode.nodeType == 8)//COMMENT_NODE == 8;
    {
      // Check if it is a comment from showDetailFrame specifying frame parent.
      var nodeData = childNode.data;
      if (nodeData.indexOf(FRAME_CHILDLIST_ID_CONST) > -1)
      {
        return childNode;
      }
    }
  }
  return null;
}

function trimString(argString) 
{
  argString = argString.replace( /^\s+/g, "" );// strip leading
  return argString.replace( /\s+$/g, "" );// strip trailing
}

function getFrameBeforeThisFrameId(frameListArray, thisFrameId)
{
  var numElems = frameListArray.length;
  var beforeFrameId = "";
  for (var i = 0; i < numElems; i++)
  {
    if (frameListArray[i] == thisFrameId)
    {
      return beforeFrameId;
    }
    beforeFrameId = frameListArray[i];
  }
  return null;
}

function getFrameAfterThisFrameId(frameListArray, thisFrameId)
{
  var numElems = frameListArray.length;   
  
  var afterFrameId = "";
  var thisFrameFound = false;
  for (var i = 0; i < numElems; i++)
  {
    if (thisFrameFound == true)
    {
      afterFrameId = frameListArray[i];
      return afterFrameId;
    }
    if (frameListArray[i] == thisFrameId)
    {
      thisFrameFound = true;
    }
  }
  return null;
}

/** 
 *  if hide = true, hides the menu item else  shows it
 *
 */
function hideShowMenuItem(menuItemId, hide)
{
  var menuItem = document.getElementById(menuItemId);
  if (menuItem)
  {
    var menuItemDiv = findHoldingDiv(menuItem);
    if (menuItemDiv)
    {
      if (hide)
        menuItemDiv.style.display = 'none'; 
      else
        menuItemDiv.style.display = 'inline'; 
    }
  }
}

 /**
  * used for reinstating restore menu on the frame.
  * Restore menu needs to be present when
  * 1. Frame state first changed to maximize (by default 
  *    restore menu for restoring from max will be present)
  * 2. Next, frame state changed to minimize (restoreFromMin would be available now)
  * 3. Restore from min now done. 
  * After step 3, during normal course, restore menu would go away because the state
  * is being restored. However, because of step 1. above, restore menu should be 
  * present even now as restore From Max is yet to be done. Hence, this 
  * reinstates the restoreFromMax restore menu.
  */
function reinstateRestoreMenu(frameId, restoreItemId)
{
  var frameElem = document.getElementById(frameId); // this can't be null.
  
  var frameRootParentFrameId = getFrameRootParentFrameId(frameElem);
  if (frameRootParentFrameId == null)
  {
    // Can't do anything in this case. Simply return.
    return false;
  }

  var frameParentContainerId = frameRootParentFrameId + FRAME_CONTAINER_TD_ID_CONST;
  var frameParentContainerElem = document.getElementById(frameParentContainerId);

  if (frameParentContainerElem)
  {
    var maxState = frameParentContainerElem.maximizedState;
    
    if (maxState == 'true')
    {
      // Find the restore element, set it's onclick to restoreFromMax and show it.
      var restoreMenuItem = document.getElementById(restoreItemId);
      if (restoreMenuItem)
      {
        if (_agent.isIE)
        {
          restoreMenuItem.onclick = restoreFromMax;
        }
        else
        {
          restoreMenuItem.setAttribute('onclick', 'restoreFromMax(event, this);');
        }

        var restoreMenuDiv  = findHoldingDiv(restoreMenuItem);
        restoreMenuDiv.style.display = 'inline';         
      }
    }
  }
}

function maximizeFrame(event, elem)
{
  if (window.event)
  {
    event = window.event;
  }
      
  if ( elem == null )
  {
    elem = (event.target) ? event.target : event.srcElement; 	
  }
  
  if (_agent.isIE)
  {
      if ( (event.keyCode != '13') && (event.keyCode != '0') )
      {
        return;
      }      
  }
  else
  {
      if ( (event.which != '13') && (event.which != '1') )
      {
        return;
      }        
  }
  
  var maxMenuOptionId = elem.id;
  var toBeMaxedFrameId = maxMenuOptionId.substring(0, maxMenuOptionId.indexOf("_menuItemSource"));
  
  // Do safari specific handling =-=rbaranwa  
  if (_agent.isSafari)
  {  
    // Safari browser does not recognize comment node hence all such calculation
    // goes haywire. The workaround is to do a partial page submit
    var formElem = findFormElem(elem);        
    
    _submitPartialChange(formElem.id, 
                         0,
                         {partialTargets:formElem.id,
                         event:'maximize', 
                         source: elem.id });
    return false;
  }
  
  // elem is the anchor tag. 
  // sDFTableContent_menuItemSource_normal
  
  // now modify the menu item.
  
  // hide the menus last shown so that we start with a clean slate
  // This is done right at the beginning as with node cloning on, 
  // hideLastMenuShown would not work.
  hideLastMenuShown();
  
  var frameElem = document.getElementById(toBeMaxedFrameId);
  var frameRootParentFrameId = getFrameRootParentFrameId(frameElem);
  
  var frameParentTableId = frameRootParentFrameId + '_table';
  var frameParentTableElem = document.getElementById(frameParentTableId);   
    
  maximizedParentWidths[frameParentTableId] = frameParentTableElem.style.width;     
    
  frameParentTableElem.style.width = frameParentTableElem.offsetWidth + 'px';
  
  if (frameRootParentFrameId == null)
  {
    // This will be the case when frame is a root lavel frame.
    // In such a case it does not make any sense in current UI 
    // to maximize the frame as there is no parent frame to occupy 
    // the parent's real estate on UI. Hence, do nothing.
    return false;
  }      
  
  // Try to get the content area DIV of the frameParent ( content area DIV
  // would be present when the frameParent displays scrollBars ).
  var frameParentContainerId = frameRootParentFrameId + '_div2' ;
  
  // In case of the parent ShowDetailFrame being set to not display any chrome,
  // the TD for case above will not exist. Instead, the child should be made a direct 
  // child of the parent showDetailFrame. This condition also needs to be 
  // handled in the restoreFromMax case
  var rootParentContainerElem = document.getElementById(frameParentContainerId);
  
  if ( !rootParentContainerElem )
  {
    // This indicates that the content area had no DIV, which would be the case 
    // when the frameParent does not have any scrollBars.
    frameParentContainerId = frameRootParentFrameId + '_div2cell' ;
    rootParentContainerElem = document.getElementById(frameParentContainerId);
  }
  
  if (rootParentContainerElem)
  {
    processMaximizeFrame(frameParentContainerId, frameElem);
  }
  else
  {
    // So, the root parent showDetailFrame TD does not exist. See if
    // rootParent frame exists.
    rootParentContainerElem = document.getElementById(frameRootParentFrameId);
    if (rootParentContainerElem)
    {
      frameParentContainerId = frameRootParentFrameId;
          processMaximizeFrame(frameParentContainerId, frameElem);
    }
  }     

  var maxMenuElem = document.getElementById(maxMenuOptionId);    
  
  var maxMenuHoldingDiv = findHoldingDiv(maxMenuElem);
  // if the parent of the elem is DIV, then the call is from menu else it's from image.
  // if the call is from DIV, get the hidden div, show it and hide this div.
  
  var parentNodeType = findElemType(maxMenuElem.parentNode);
  
  if (parentNodeType == 'DIV')
  {
    // Hide this div and show the hidden div
    //InnerSDF1_menuItemSource_maximized -> change it to normal
    var restoreItemId = maxMenuOptionId.substring(0, maxMenuOptionId.lastIndexOf('maximized')) + 'normal';
    var restoreItem = document.getElementById(restoreItemId);
    
    if (_agent.isIE)
    {
      restoreItem.onclick = restoreFromMax;
    }
    else
    {
      restoreItem.setAttribute('onclick', 'restoreFromMax(event, this);');
    }
          
    var restoreDiv  = findHoldingDiv(restoreItem);
    restoreDiv.style.display = 'inline'; 
    maxMenuHoldingDiv.style.display = 'none'; 
    
    // When frame is maximized, the move option should now be hidden as it's the
    // only frame available. Also, on restore, the move menu should again become available.    
    var moveMenuItemId = toBeMaxedFrameId + MENU_ITEM_SRC_CONST + '_move';
    showHideMenuItemDiv(moveMenuItemId, false);

    // Also, the show/hide option of the parent frame should be hidden since 
    // this is the only visible child frame now.
    var showHideMenuItemId = frameRootParentFrameId + MENU_ITEM_SRC_CONST + '_showContent';
    showHideMenuItemDiv(showHideMenuItemId, false);       
  }
  else // must be image directly instead of menu option
  {
    // TODO Handle this later.
  }  	

  maxHoldingFrames[frameRootParentFrameId] = frameRootParentFrameId;	

  // Readjust the remaining contents of the parent frame main menu after 
  // removing the show/hide above.
  modifyMainMenuDiv(frameRootParentFrameId,false);    
    
  sendMessage(document.getElementById(frameParentContainerId), elem.id, false); 
  preventEventPropagation(event);
  
  return false;
}

/**
 *  Handles maximizing of a frame.
 */
function processMaximizeFrame(frameParentContainerId, toBeMaxedFrame)
{  

  var frameParentContainerElem = document.getElementById(frameParentContainerId);              
  
  // frameParentChildren need not be frames if the parent frame contains 
  // panelCust which in turn contains frame elements.
  var frameParentContainerChildren = frameParentContainerElem.childNodes;
  var numChildren = frameParentContainerChildren.length;
  var originalChildren = new Array(numChildren); 

  // First pass to store all children that are in frameParentContainer
  for (var i = 0; i < numChildren; i++)
  {
    originalChildren[i] = frameParentContainerChildren.item(i);    
  }

  // Second pass to remove all children
  for (var i = 0; i < numChildren; i++)
  {
    originalChildren[i].parentNode.removeChild(originalChildren[i]);
  }            
  
  // Cloning the toBeMaxedFrame node
  var toBeMaxedFrameClone = toBeMaxedFrame.cloneNode(true); 
  
  // Now insert the frame in question as the only child.
  frameParentContainerElem.appendChild(toBeMaxedFrameClone);
  
  // Getting the table of the clone whose width has to be set to 100% for
  // maximizing.
  var toBeMaxedFrameCloneTable = 
                document.getElementById(toBeMaxedFrameClone.id + "_table");
  
  // Set width to 100%
  toBeMaxedFrameCloneTable.style.width = '100%';   
  
  // Set height to 100%
  toBeMaxedFrameCloneTable.style.height = '100%';   
  
  // Using the toBeMaxedFrame ID as the index to store the respective children
  // in the array. This way, in case of a series of maximized frames, each one 
  // can be identified individually.
  maxedFrameComps[toBeMaxedFrame.id] = originalChildren;

  // Store the current state as maximized so that latest states can be handled correctly
  frameParentContainerElem.maximizedState = 'true';
}


function restoreFromMax(event, elem)
{
  if (window.event)
  {
    event = window.event;
  }
      
  if ( elem == null )
  {
    elem = (event.target) ? event.target : event.srcElement; 	
  }

  if (_agent.isIE)
  {
      if ( (event.keyCode != '13') && (event.keyCode != '0') )
      {
        return;
      }      
  }
  else
  {
      if ( (event.which != '13') && (event.which != '1') )
      {
        return;
      }        
  }

  var toBeRestoredFrameId = elem.id.substring(0, elem.id.indexOf("_menuItemSource"));
  var frameElem = document.getElementById(toBeRestoredFrameId);    
  
  var frameRootParentFrameId = getFrameRootParentFrameId(frameElem); 
  delete maxHoldingFrames[frameRootParentFrameId];
  
  // Do safari specific handling =-=rbaranwa  
  if (_agent.isSafari)
  {
    // Safari browser does not recognize comment node hence all such calculation
    // goes haywire. The workaround is to do a partial page submit
    var formElem = findFormElem(elem);
    _submitPartialChange(formElem.id, 
                         0,
                         {partialTargets:formElem.id,
                         event:'restore', 
                         source: elem.id });
    return false;
  }
  else
  {    
    _doFormSubmitForRestoreOperation(elem, toBeRestoredFrameId, frameElem);
    return;
  }

}

// Form submit routine when restore called for a maximized frame that now needs to be restored.
function _doFormSubmitForRestoreOperation(elem, frameRootParentFrameId, frameParentContainer)
{     
  var formElem = findFormElem(frameParentContainer); 
  
  if (_agent.isSafari)
  {
    _submitPartialChange(formElem.id, 
                       0,
                       {partialTargets:frameRootParentFrameId,
                       event:'restore', 
                       source: elem.id });
  }
  else
  {   
    submitForm(formElem, 0, {partialTargets:frameRootParentFrameId, event:'restore', source:elem.id});
  }
  
  return true;
}

// This function modifies the mainMenuDiv corresponding to the supplied 
// mainMenuDivId.It removes/adds back any menu action items/separators 
// redundant/relevant in view of the recently executed client-side action.
function modifyMainMenuDiv (mainMenuDivId,restoreFlag)
{     
	
    var elem = document.getElementById(FRAME_IMAGEBAR_IDENTIFIER_CONST + 
                                                      mainMenuDivId + '_div1');
                                                      
    if ( elem == null )
    {
        return;
    }
    
    var numDivChildren = elem.childNodes.length;
    var atleastOneChildDisplayed = false;              
    var i;
    
    // FOR loop checks for the presence of atleast DIV node which is currently 
    // not hidden.If found, it sets the atleastOneChildDisplayed flag to 'true'.
    for ( i=0; i<numDivChildren; i++ )
    {              
        // (nodeType == 8) implies a comment node.    
        if ( (elem.childNodes.item(i).nodeType != 8) && 
             ( elem.childNodes.item(i).style.display == 'inline' ||
               elem.childNodes.item(i).style.display == '') )
        {            
            atleastOneChildDisplayed = true;
            break;
        }       
    }      
    
    var actionIconId = mainMenuDivId + '_action';    
    
    var actionIconElem = document.getElementById(actionIconId);   
    
    if ( !actionIconElem )
    {
        return;
    }
    
    var toolbarLeftImageElem = document.getElementById ( mainMenuDivId + "_half_left" );
    var toolbarRightImageElem = document.getElementById ( mainMenuDivId + "_half_right" );        
    var closeToolBarElem = document.getElementById ( mainMenuDivId + "_toolBarClose" );        
     
    if ( atleastOneChildDisplayed )
    {
        // This indicates that currently the action icon is hidden.This 
        // necessarily implies that an operation of restore nature is underway, 
        // in which case, the action icon element needs to be redisplayed, as 
        // as also any separator elements which were hidden till now.
        if ( actionIconElem.style.display == 'none' )
        {
        
       	    if ( !(mainMenuDivId in maxHoldingFrames) ) 
            {
          
                 actionIconElem.style.display = 'inline';            
                 if ( closeToolBarElem != null )
		 {
		   closeToolBarElem.style.display = 'inline';
		 }

		 if ( toolbarLeftImageElem != null )
		 {
		   toolbarLeftImageElem.style.display = 'inline';
		 }

		 if ( toolbarRightImageElem != null )
		 {
		   toolbarRightImageElem.style.display = 'inline';
		 }

		 var separatorDiv = document.getElementById(mainMenuDivId + '_separator');                        
		 if (separatorDiv)
		 {
		   separatorDiv.style.display = 'block';    
		 }
            
            }
        }
        // ELSE indicates that action icon is currently in display.There can be 
        // 2 cases here - a forward operation is taking place / a reverse 
        // restore operation is underway.
        else
        {    
            // "restoreFlag == false" indicates a forward operation.We need to 
            // remove any redundant separator elements from the menu.
            if ( !restoreFlag )
            {                
                // Checking whether the first dsiplayed element found at 
                // index 'i' was a separator or not; if it was, it is redundant 
                // now.
                if ( elem.childNodes.item(i).id == (mainMenuDivId + '_separator') )
                {                    
                    elem.childNodes.item(i).style.display = 'none';                    
                }
                else
                {   
                    // If the first displayed element was not a separator, we 
                    // need to check whether or not the last displayed element 
                    // is a separator.If it is, it is redundant and should be 
                    // removed.The FOR loop below does exactly that.
                    for ( var j=numDivChildren; j>0; j-- )
                    {
                        if ( (elem.childNodes.item(j-1).nodeType != 8) && 
                             ( elem.childNodes.item(j-1).style.display == 'block' ||
                               elem.childNodes.item(j-1).style.display == '') )
                        {                
                            if ( elem.childNodes.item(j-1).id == 
                                                    (mainMenuDivId + '_separator') )
                            {
                                elem.childNodes.item(j-1).style.display = 'none';
                            }                    
                        }
                    }
                }
            }
            else
            {  
                // ELSE indicates that a restore operation is underway.Since 
                // the aciotn icon was never hidden in this case, all we need to 
                // do is put the separator back in its place ( just in case it 
                // was hidden during the forward operation ).
                var separatorDiv = document.getElementById(mainMenuDivId + '_separator');            
            
                if (separatorDiv)
                {                       
                    separatorDiv.style.display = 'block';                        
                }                
            }
        }               
    }
    else
    {
        // If not a single displayed child is found, the menu and thereby the 
        // action icon element itself becomes redundant.
        // Hence, hide the action icon element.
        actionIconElem.style.display = 'none';
        
        if ( closeToolBarElem != null )
        {
           closeToolBarElem.style.display = 'none';
        }
        if ( toolbarLeftImageElem != null )
        {
            toolbarLeftImageElem.style.display = 'none';
        }
        
        if ( toolbarRightImageElem != null )
        {
            toolbarRightImageElem.style.display = 'none';
        }
    }
    
}

/**
 *  This function does the job of minimizing/restoring the component based on 
 *  the current state.
 */ 
function minimizeOrRestoreAction(event, elem)
{  
  if (window.event)
  {
    event = window.event;
  }
      
  if ( elem == null )
  {
    elem = (event.target) ? event.target : event.srcElement; 	
  }
  
  if (_agent.isIE)
  {
      if ( (event.keyCode != '13') && (event.keyCode != '0') )
      {
        return;
      }      
  }
  else
  {
      if ( (event.which != '13') && (event.which != '1') )
      {
        return;
      }        
  }
  
  hideLastMenuShown();
  
  var toBeMinimizedFrameId = elem.id.substring(0, elem.id.indexOf("_minimizeOrRestore"));
  
  var frameElem = document.getElementById(toBeMinimizedFrameId);        
  
  var frameElemParent = frameElem.parentNode;  
  
  var contentTDID = toBeMinimizedFrameId + '_div2cell' ;      
  var contentTD   = document.getElementById(contentTDID);    
  
  var compTableID = toBeMinimizedFrameId + '_table' ;    
  var compTable   = document.getElementById(compTableID);        
  
  var showHideMenuItemId = toBeMinimizedFrameId + MENU_ITEM_SRC_CONST + '_showContent';
  
  var frameSrc;
  var IFrameElems = null;
  
  if (contentTD != null && (contentTD != (void 0) ) )
  {        
    // This indicates that currently the component is in the normal state  
    if ( elem.id.indexOf("minimized") != -1 )
    {    
        // Storing the current width (if defined) in the global map, to be 
        // fetched back during restore operation.
        minimizedCompWidths[compTableID] = compTable.style.width;            
       
        // Setting the width to the runtime width to avoid width changes during
        // minimize operation.
        compTable.style.width = compTable.offsetWidth + 'px';               
        
        // Storing the current height (if defined) in the global map, to be 
        // fetched back during restore operation.
        minimizedCompHeights[compTableID] = compTable.style.height;
        
        // Setting the height to null
        compTable.style.height = '';
        
        contentTD.style.display = 'none';                  
        
        // Need to hide the hide menu ( in case of a panelCustomizable ) 
        // since component has gone to a minimized state.
        showHideMenuItemDiv(showHideMenuItemId, false); 
        
        // readjust the mainMenuDiv contents
        modifyMainMenuDiv(toBeMinimizedFrameId,false);  
    }
    // This indicates that currently the component is in the minimized state
    else if ( elem.id.indexOf("normal") != -1 )
    {           
        contentTD.style.display = '';                
        
        // Getting the stored width back
        compTable.style.width = minimizedCompWidths[compTableID];        
        
        // Getting the stored height back
        compTable.style.height = minimizedCompHeights[compTableID];        
        
        // Need to hide the show menu ( in case of a panelCustomizable ) 
        // since component has now gone to a normal state.
        showHideMenuItemDiv(showHideMenuItemId, true); 
        
        // readjust the mainMenuDiv contents
        modifyMainMenuDiv(toBeMinimizedFrameId,true);  
        
        // This snippet of code is to handle the problem of IFrame contents 
        // getting deleted fomr the DOM in case of Mozilla.Here, we store the 
        // the src attribute value for the portlet content IFrame element.
        if ( !_agent.isSafari && !_agent.isIE )
        {
            IFrameElems = contentTD.getElementsByTagName('IFRAME');            
            
            if ( IFrameElems && IFrameElems[0] )
            {
                frameSrc = IFrameElems[0].src;
            }
        }

    }  
    
    swapImages(elem);
  }
  else
  {      
    // Since the minimized content is unavailable on the client, do a form 
    // submit to fetch the same from the server
    _doFormSubmitForRestoreOperation(elem, toBeMinimizedFrameId, frameElem);    
  }     

  hideLastMenuShown();  
  
  sendMessage(frameElem, elem.id, false);
  preventEventPropagation(event);
  
  // Mozilla bug : And here we do a refetch using the stored src location.
  if ( !_agent.isSafari && !_agent.isIE && IFrameElems && IFrameElems[0] )
  {
    if( frameSrc != '' )
    {
       IFrameElems[0].src=frameSrc;
    }
  }
  
  return false;
}

/**
 *  This function toggles between the 2 images for "minimize" and "restore" 
 *  functions based on the current state (minimized/restore) of the component
 */ 
function swapImages(elem)
{
    // elemSiblings represents the dropdown action item,the minimize icon and 
    // the restore icon, all of which are at the same level
    var elemSiblings = elem.parentNode.childNodes;      
    
    // Running through the first 2 elements of elemSiblings - minimize and 
    // restore icons, to toggle their current display states.The 3rd element 
    // in elemSiblings, if present, would be the title text of the component.
    
    for ( i = 0 ;i < 2 ; i++ )
    {               
        var currElem = elemSiblings.item(i);               
        
        if ( currElem.style.display == 'none' )
        {
            currElem.style.display = 'inline';
        }
        else if ( currElem.style.display == 'inline' )
        {
            currElem.style.display = 'none';
        }
    }    
}

/**
 *  This function drapes the toolbar with the dropdown menu on an 
 *  onmouseover/ommouseenter event for components with hidden title bars
 */ 
function drapeToolBar(event,elem,isRTL)
{          
    if (window.event)
    {
      event = window.event;
    }
       
    if ( elem == null )
    {
      elem = (event.target) ? event.target : event.srcElement; 	
    }         
    
    var relTarg;
    
    if (_agent.isIE)
    {
        relTarg = event.fromElement;
    }
    else
    {
        relTarg = event.relatedTarget;
    }
    
    var enclosingPC = elem.id;              
    
    while(relTarg && relTarg.nodeName != 'BODY')
    {
      if(relTarg && relTarg.id && enclosingPC == relTarg.id)
        break;
      else 
        relTarg = relTarg.parentNode;
    }              
    
    if(relTarg && relTarg.id && enclosingPC == relTarg.id )
    {      
      if ( toolBarCloseStatus[elem.id] == true)
      {      
          return;
      }
    }
        
    // Here, in this case where the title bar is turned OFF, elem represents the 
    // top level component table containing the body DIV. 
    // When titleBar is turned ON, the top level table will contain the header 
    // and the body DIVs.
    // The toolbarDiv in turn is the div holding the dropdown menu actionitem.                    
    
    // Get the toolBarDiv ID from the component table ID
    var toolBarDivId = elem.id.substring(0, elem.id.indexOf("_table"))
                                                            + '_toolbarDiv';
    var toolBarDiv = document.getElementById(toolBarDivId); 
  
    // If currToolBarDiv is not null, it means a previously dropped down menu 
    // is still in the dropped down state.
    if ( currToolBarDiv )
    {       
      // If currToolBarDiv is different from the toolBarDiv we are about to
      // drape, hide currToolBarDiv along with it's dropped down menu before 
      // drapping the new one.If the 2 are the same,do not hide currToolBarDiv.  
      if ( currToolBarDiv.id != toolBarDiv.id )
      {                        
        if ( event.toElement )
        {               
            if ( (event.toElement.id.indexOf('imageBar_') == -1) && 
                 (event.toElement.id.indexOf('_menuItemSource') == -1) )
            {              
                // Setting hovering back to 'false' since the toolbar needs to be hidden
                hovering = false;
            
                hideLastMenuShown();  
            }
        }
      }

    }       
    
    if (toolBarDiv)
    {       
      toolBarDiv.style.display = "inline";                             
      toolBarDiv.style.top = '2px';       
      var toolbarWidth = getWidth(toolBarDiv);           
      
      // The toolbar width may be undefined if there was no toolbar
      // generated but the function was still called in some degenerate case.
      if ( (toolbarWidth == undefined) || isNaN(toolbarWidth) )
      {
        toolbarWidth = 0;
      }           
      
      if ( isRTL )
      {
        if ( _agent.isIE )
        {
          toolBarDiv.style.left = '+2px';
        }
        else
        {
          toolBarDiv.style.left = findPosX(elem) + 2 + 'px';
        }    
      }
      else
      {
          toolBarDiv.style.left = (parseInt(elem.offsetWidth)  
                                   - parseInt(toolbarWidth) ) - 2 + 'px';                                             
      }
      // A new toolbar has been successfully draped.Set hovering to 'true'.                                 
      hovering = true;                                       
    }

    preventEventPropagation(event);
}


function closeToolBar (event,elem)
{       
   var tableElemId = elem.id.substring(0, elem.id.indexOf("_toolBarClose"))
                                                            + '_table';                                                                                                                                                           
                     
   // set the close status for this toolbar to 'true'.                       
   toolBarCloseStatus[tableElemId] = true;                      
                                                                 
   var tableElem = document.getElementById(tableElemId);      
   
   removeToolBar (event,tableElem);      
}

function removeToolBarOnMouseOut (event,elem)
{                  
    if (window.event)
    {
      event = window.event;
    }
       
    if ( elem == null )
    {
      elem = (event.target) ? event.target : event.srcElement; 	
    }             
    
    var relTarg; 
    
    if (_agent.isIE)
    {
        relTarg = event.toElement;
    }
    else
    {
        relTarg = event.relatedTarget;
    }    

    var enclosingPC = elem.id;
      while(relTarg && relTarg.nodeName!='BODY')
      {
        if( relTarg && relTarg.id && enclosingPC == relTarg.id)
          break;
        else 
          relTarg = relTarg.parentNode;
      }
      if(relTarg && relTarg.id && enclosingPC == relTarg.id)
      {
      if(toolBarCloseStatus[elem.id] == false)
          return;
      }
      else
      {
        removeToolBar (event,elem);     
        toolBarCloseStatus[elem.id] = false;                
        hovering = false; 
    }
}

/**
 *  This function hides the draped toolbar with the dropdown menu on an 
 *  onmouseout/ommouseleave event for components with hidden title bars
 */
function removeToolBar (event,elem)
{       
  if (event == null)
  {    
    // must be IE. get the source of the event now.
    event = window.event;    
    elem = window.event.srcElement;
  }       
  
  // Here, in this case where the title bar is turned OFF, elem represents the 
  // top level component table containing the body DIV. 
  // When titleBar is turned ON, the top level table will contain the header 
  // and the body DIVs.
  // The toolbarDiv in turn is the div holding the dropdown menu actionitem.                    
    
  // Get the toolBarDiv ID from the component table ID    
  var toolBarDivId = elem.id.substring(0, elem.id.indexOf("_table"))  
                                                            + '_toolbarDiv';                                                                                                                                                                                                                                                   
                                                             
  var toolBarDiv = document.getElementById(toolBarDivId); 
  
  // If currToolBarDiv is not null, it means a menu has been dropped down from 
  // the currently draped toolBarDiv.In that case, can't hide the toolBar here.
  // The toolBarDiv will be hidden along with the dropped down menu in the 
  // hideLastMenu function.     
  
  if ( !currToolBarDiv )
  {             
    toolBarDiv.style.display = "none";               
  }       
  
  preventEventPropagation(event);     
  
}

function restoreFromMin(event, elem)
{
  if (elem == null)
  {
    // must be IE. get the source of the event now.
    elem = window.event.srcElement;
    event = window.event;
  }   
  
  var toBeRestoredFrameId = elem.id.substring(0, elem.id.indexOf("_menuItemSource"));
  var frameElem = document.getElementById(toBeRestoredFrameId);
  //var frameContentHoldingDivID = toBeRestoredFrameId + '_div1';
  
  //var frameContentHoldingDiv = document.getElementById(frameContentHoldingDivID);

  // find the content area table and show it.
  // sDFChild1_t2 is peer of sDFChild1_div1
  var contentTableID = toBeRestoredFrameId + '_t2';
  var contentTable   = document.getElementById(contentTableID);
  
  if (contentTable != null && (contentTable != (void 0) ) )
  {
    //var contentTableParent = contentTable.parentNode;
    contentTable.style.display = '';
  }

  // now modify the menu item.
  // renderStateRestored
  var restoreMenuOptionId = elem.id;
  
  var restoreMenuHoldingDiv = findHoldingDiv(elem);
  
  // if the parent of the elem is DIV, then the call is from menu else it's from image.
  // if the call is from DIV, get the hidden div, show it and hide this div.
  
  var parentNodeType = findElemType(elem.parentNode);
  
  if (parentNodeType == 'DIV')
  {
    // Hide this div and show the hidden div
    //InnerSDF1_menuItemSource_normal -> change it to minimized
    var minimizeItemId = restoreMenuOptionId.substring(0, restoreMenuOptionId.lastIndexOf('normal')) + 'minimized';
    var minimizeItem   = document.getElementById(minimizeItemId);
    
    if (_agent.isIE)
    {
      minimizeItem.onclick = minimizeFrame;
    }
    else
    {
      minimizeItem.setAttribute('onclick', 'minimizeFrame(event, this);');
    }
    
    var minimizeDiv = findHoldingDiv(minimizeItem);
    minimizeDiv.style.display = '';
    restoreMenuHoldingDiv.style.display = 'none'; 
    
    // Check if restore menu option needs to be reinstated.
    reinstateRestoreMenu(toBeRestoredFrameId, restoreMenuOptionId);
  }
  else // must be image directly instead of menu option
  {
    // TODO Handle this case later.
  }
  
  hideLastMenuShown();  
  
  sendMessage(frameElem, elem.id, false);
  
  return false;
}


function findFormElem(elem)
{
  // keep moving up the hierarchy till you find FORM and then return the element
  var upNodeName = null; //parentNode
  if (elem.parentNode.localName) // Mozilla etc
  {
    upNodeName = elem.parentNode.localName;
  }
  else if (elem.parentNode.tagName) // IE only
  {
    upNodeName = elem.parentNode.tagName;
  }
  if ( (upNodeName == "form") || (upNodeName == "FORM") )
  {
    return (elem.parentNode);
  }
  else
  {
    return findFormElem(elem.parentNode);
  }   
  
}

function createAndStoreElement(elemName, elemValue, formElem)
{
  var tmpField = document.createElement("input");
  tmpField.type = "hidden";
  tmpField.name = elemName;
  tmpField.value = elemValue;
  formElem.appendChild(tmpField);
  tempSDFParams[elemName] = tmpField;
}

function removeElementFromForm(formElem)
{
  for (var tempParamName in tempSDFParams)
    formElem.removeChild(tempSDFParams[tempParamName]);
}

function sendMessage(elem, actionID, moveOperation)
{
  // Temp : shortest way of doing it;optimize the code later on.
  moveOperation = true;
  
  var formElem = findFormElem(elem);
  if (formElem)
  {
    var actionInputElems = document.getElementsByName('event');
    var actionInputElem = actionInputElems.item(0);
    if (actionInputElem)
    {
      actionInputElem.value = actionID;
    }
    var sourceInputElems = document.getElementsByName('source');
    var sourceInputElem = sourceInputElems.item(0);
    if (sourceInputElem)
    {
      sourceInputElem.value = actionID;
    }
    else
    {
      createAndStoreElement('source', actionID, formElem)
    }
    xmlObj = getXMLHTTP();

    var data = createNameValueString(formElem);    
    
    xmlObj.open(formElem.method.toUpperCase(), formElem.action, !moveOperation);
    xmlObj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlObj.setRequestHeader('Referer', formElem.action);
    if ( !moveOperation )
    {
        xmlObj.onreadystatechange = processResponse;
    }
    // Execute the request
    try 
    {
      xmlObj.send(data);
    }
    catch (e) 
    {
      alert("Could not send message to server.");
    }        

    if ( moveOperation )
    {        
        processStateToken();
    }    
  }
  else
  {
    alert('The page does not have a form element in it');
    // Can we do anything else here?
    return;
  }
  removeElementFromForm(formElem);
}

function processResponse()
{    
    if (xmlObj.readyState == 4) {            
        processStateToken();    
    }
}

function processStateToken()
{
    var responseString = xmlObj.responseText;                      

    var tempString1 = responseString.substring(responseString.indexOf('oracle.adf.faces.STATE_TOKEN"'),responseString.length);
    var tempString2;                
    
    if ( tempString1.indexOf('value="') != -1 )
    {
        tempString2 = tempString1.substring(tempString1.indexOf('value="')+7,tempString1.length);
    }
    else
    {
        tempString1 = responseString.substring(0,responseString.indexOf('oracle.adf.faces.STATE_TOKEN"'));    
        tempString2 = tempString1.substring(tempString1.lastIndexOf('value="')+7,tempString1.length);                    
    }
    
    var newStateTokenValue = tempString2.substring(0,tempString2.indexOf('"'));               
        
    var stateTokenObj = document.getElementsByName('oracle.adf.faces.STATE_TOKEN').item(0);              
    
    if ( stateTokenObj )
    {
        stateTokenObj.value = newStateTokenValue;               
    }
    
}

function getXMLHTTP()
{  
  var xmlHttpObj = null;
  try
  {    
    xmlHttpObj = new ActiveXObject("Msxml2.XMLHTTP")  
  }
  catch(e)
  {    
    try
    {      
      xmlHttpObj = new ActiveXObject("Microsoft.XMLHTTP")    
    } 
    catch(oc)
    {      
      xmlHttpObj = null;
    }  
  }  
  if( (!xmlHttpObj) && (typeof XMLHttpRequest != "undefined") )
  {    
    xmlHttpObj = new XMLHttpRequest();
  }  
  return xmlHttpObj;
}
