/**
 * Monitor Management Control Systems Ltd.
 * mpower
 * Revisions.
 * $Log: /JavaScript/mpower_menu.js $
 * 
 * 2     10/04/06 14:24 Gc
 *
 * 1     10/04/06 11:45 Gc
 * 2033793
 *
 * Who  When      SPR/CRN  Why
 * GC   10-04-06  2033793  Created
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

var _menu;                  // The menu array

var _maxLevels      = 0;    // The number of levels the menu contains (used for creating DIV's)

var _shortCutMenu   = null; // A reference to the shortcut menu
var _shortCutIndex  = null; // A reference to the index of the shortcut item in the shortcut menu


/**
 * An object for creating a menu. This allows different types of menu item to
 * be added to a menu.  As well as sub menus
 */
function Menu(){
  this.list             = new Array();      // The menu array of MenuItems
  this.hasParent        = false;            // Does this menu have a parent?
  this.parent;                              // The parent Menu
  this.setParentMenu    = setParentMenu;
  this.addItem          = addItem;
  this.addSeperator     = addSeperator;
  this.addShortcutItem  = addShortcutItem;
  this.addSubMenu       = addSubMenu;
}

// The following functions are required for the menu object
// setParentMenu
// addItem
// addSeperator
// addShorcutItem
// addSubMenu
//
// They should not be called outwith a menu object

/**
 * Set the parent of this menu
 * @param  a Menu object that is the parent of this menu
 */
function setParentMenu(p_parent){
  this.hasParent = true;
  this.parent = p_parent;
}


/**
 * add an item to the menu
 * @param   p_title         - the title of the menu item
 * @param   p_image         - an image to display
 * @param   p_hyperlink     - what to do on click
 * @param   p_index_prefix  - prefix used when this item is being added to a shortcut
 */
function addItem(p_title, p_image, p_hyperlink, p_index_prefix){
  var sIndex = getIndex(this);
  if (typeof p_index_prefix != "undefined"){
    sIndex = p_index_prefix + "@" + sIndex;
  }
  this.list[this.list.length] = new MenuItem(sIndex, getTerm(p_title), p_image, p_hyperlink, false, false);
}

/**
 * add a sepetator item to the menu
 */
function addSeperator(){
  this.list[this.list.length] = new MenuItem(""+getIndex(this), "", "", "", true, false);
}

/**
 * Add the shortcut menu.  This can then be added to dynamically
 * @param   p_title     - the title of the menu item
 * @param   p_image     - an image to display
 * @param   p_hyperlink - what to do on click
 */
function addShortcutItem(p_title, p_image, p_hyperlink){
  this.list[this.list.length] = new MenuItem(""+getIndex(this), getTerm(p_title), p_image, p_hyperlink, false, true);
}

/**
 * Add a sub menu to the current item
 * @param   p_menu    - the sub menu to add
 */
function addSubMenu(p_menu){
  var levels = getLevels(p_menu);
  top.headerFrame._maxLevels = Math.max(levels, top.headerFrame._maxLevels);
  this.list[this.list.length-1].setSubMenu(p_menu.list);
}

/**
 * An object for each menu item.  a MenuItem object contains all the info require to create a menu item.
 */
function MenuItem(p_id, p_title, p_image, p_hyperlink, p_seperator, p_shortcut){
  this.index      = ""+p_id;      // The index of this item from the root
  this.title      = p_title;      // The title of the menu item
  this.hyperlink  = p_hyperlink;  // The hyperlink of the menu item
  this.image      = p_image;      // The image
  this.subMenu    = new Array();  // The array of sub menu items
  this.isSeperator= p_seperator;  // Is this item a seperator?
  this.isShortcut = p_shortcut;   // Is this item the shortcut menu item?

  var aID = this.index.split("@");
  this.menuLevel  = aID.length-1; // The level of this menu

  this.toString   = toString;
  this.createTag  = createTag;
  this.setSubMenu = setSubMenu;
}

// The following functions are required for the MenuItem object
// toString
// setSubMenu
// createTab
//
// They should not be called outwith a MenuItem object

/**
 * Output the contents of the MenuItem as a String
 * @return String
 */
function toString(){
  if (this.isSeperator){
    return "index : " + this.index + "\nSeperator";
  }
  return "index : " + this.index + "\ntitle : " + this.title + "\nhyperlink : " + this.hyperlink + "\nimage : " + this.image + "\nsubMenu.length : " + this.subMenu.length + "\nmenuLevel : " + this.menuLevel + "\nisShortcut : " + (this.isShortcut?"true":"false");
}

/**
 * Set the sub menu of this item
 * @param   p_new_menu    - the sub menu
 */
function setSubMenu(p_new_menu){
  this.subMenu = p_new_menu;
}

/**
 * Create the TR tag for this MenuItem
 * @return String
 */
function createTag(){
  //alert(this.toString());
  var rval = "";
  if (this.isSeperator){
    rval += "<TR onMouseOver='hideMenu("+(this.menuLevel)+");'>";
    rval += "<TD WIDTH=16 CLASS=menuImage><HR WIDTH=100% noshade=true size=1></TD>";
    rval += "<TD CLASS=menuItem COLSPAN=3><HR WIDTH=100% noshade=true size=1></TD></TR>";
  }else{
    rval += "<TR HEIGHT=20 CLASS=menuItem onMouseOut='this.className=\"menuItem\"' ";
    rval += "onMouseOver='this.className=\"menuItemHov\";hideMenu("+(this.menuLevel)+");";

    if (this.subMenu.length > 0 || this.isShortcut){
      var ids = this.index.split("@");
      rval += " showMenu("+(this.menuLevel+1)+", top.headerFrame._menu";
      for (var level = 0; level < ids.length; level++){
        rval += "["+ids[level]+"].subMenu";
      }
      rval += ", this);";
    }

    rval += "'";

    if (this.hyperlink != ""){
      var re = new RegExp();
      rval += " onClick=\"closeMenu();"+this.hyperlink+"\"";
    }
    rval += ">";

    rval += "<TD CLASS=menuImage WIDTH=16>";
    if (this.image != ""){
      rval += "<IMG SRC='"+this.image+"'>";
    }else{
      rval += "&nbsp;";
    }
    rval += "</TD>";

    rval += "<TD WIDTH=160>&nbsp;"+this.title+"</TD><TD WIDTH=10>";
    if (this.subMenu.length > 0 || this.isShortcut){
      rval += "<IMG SRC='"+getImage("IMG_MENU_EXPAND")+"'>";
    }else{
      rval += "&nbsp;";
    }
    rval += "</TD></TR>";
  }
  //alert(rval);
  return rval;
}

/**
 * find the MenuItem that is the shortcut
 * @return MenuItem
 */
function getShortcutItem(){
  return top.headerFrame.findShortcut(top.headerFrame._menu);
}

/**
 * recursive function to find the shortcut menu
 * @param   p_menu    - the starting menu to search through
 * @return  MenuItem  - the shortcut MenuItem (or null if one not found)
 */
function findShortcut(p_menu){
  var shortCutItem = null;
  if (_shortCutMenu != null){
    return _shortCutMenu[_shortCutIndex];
  }else{
    for (var i in p_menu){
      if (p_menu[i].isShortcut){
        _shortCutMenu = p_menu;
        _shortCutIndex = i;
        shortCutItem = p_menu[i];
      }else if (p_menu[i].subMenu.length > 0){
        shortCutItem = findShortcut(p_menu[i].subMenu);
      }
    }
  }
  return shortCutItem;
}

/**
 * Rebuild the shortcut menu
 * @param p_menu_item   - the shortcut MenuItem
 * @param p_menu        - the menu to build
 */
function rebuildShortCuts(p_menu_item, p_menu){
  if (top.headerFrame._shortCutMenu == null){
    return;
  }
  p_menu_item.setSubMenu(p_menu.list);

  top.headerFrame._shortCutMenu[top.headerFrame._shortCutIndex] = p_menu_item;
}

/**
 * Set the menu
 * @param p_new_menu  - the main menu
 */
function setMenu(p_new_menu){
  top.headerFrame._menu = p_new_menu.list;
}

/**
 * initialise the menu structure and create all the DIVs required
 */
function initMenu(){
  if (_menu == null || _menu.length == 0){
    top.headerFrame.createMenu();
  }
  var menuDivs = "";
  for (var i = 0; i <= top.headerFrame._maxLevels; i++){
    menuDivs += "<DIV ID=menu"+i+" STYLE=\"z-index:9999;position:absolute;visibility:hidden\"></DIV>";
  }
  top.bodyFrame.getObject("mpower_menu").innerHTML = menuDivs;

  if (typeof top.bodyFrame.addShortcuts == "function"){
    top.bodyFrame.addShortcuts();
  }
}

/**
 * Try and initialise the menu - wait until it is ready
 */
var tryCount = 0;
function menuInit(){
  if (typeof top.headerFrame.createMenu == "function" && typeof top.bodyFrame.getObject("mpower_menu") != "undefined"){
    initMenu();
  }else{
    tryCount++;
    if (tryCount > 1000){ return; }
    setTimeout("menuInit()", 500);
  }
}


/**
 * show a menu
 * @param   menuLevel   - the level to show
 * @param   menuArray   - the menu item
 * @param   menuTag     - the tag the menu is being opened for
 */
function showMenu(menuLevel, menuArray, menuTag){

  var menuObj = top.bodyFrame.getObject("menu"+menuLevel);

  if (typeof menuObj != "undefined"){
    if (menuLevel == 0){
      top.bodyFrame.document.body.scrollTop = 0;
    }
    menuObj.innerHTML = buildMenu(menuLevel, menuArray);

    if (typeof menuTag != "undefined"){
    //alert(typeof menuTag.tagName);
      if (menuLevel == 0){
        menuObj.style.left = findPosX(menuTag) ;
        menuObj.style.top = top.bodyFrame.document.body.scrollTop;
      }else{
        //menuObj.style.left = findPosX(menuTag) + menuTag.offsetWidth;
        //menuObj.style.top = findPosY(menuTag);//menuTag.offsetHeight;
        menuObj.style.left = findPosX(menuTag) - menuObj.offsetWidth;

        var yPos = findPosY(menuTag);

        if (menuObj.offsetHeight + yPos > top.bodyFrame.document.body.offsetHeight){
          yPos = top.bodyFrame.document.body.offsetHeight - menuObj.offsetHeight + top.bodyFrame.document.body.scrollTop - 17; // take off 17 for the horizontal scroll bar
          yPos = Math.max(0, yPos);
        }
        menuObj.style.top = yPos;

      }

    }
    menuObj.style.visibility = "visible";
  }
}

/**
 * hide a menu
 * @param menuLevel - the level to hide
 */
function hideMenu(menuLevel){
  if (typeof menuLevel != "undefined" && typeof top.headerFrame != "undefined" && typeof top.headerFrame._maxLevels != "undefined"){
    for (var i = menuLevel+1; i <= top.headerFrame._maxLevels; i++){
      var menuObj = top.bodyFrame.getObject("menu"+i);
      menuObj.style.visibility = "hidden";
    }
  }
}

/**
 * build a menu
 * @param menuLevel - the level to build
 * @param menuArray - the array of MenuItems
 */
function buildMenu(menuLevel, menuArray){
  var rval = "<TABLE CLASS=menuTable cellpadding=0 cellspacing=0>";
  for (var i in menuArray){
    rval += menuArray[i].createTag();
  }
  rval += "</TABLE>";
  //alert(rval);
  return rval;
}

/**
 * find the levels a menu has
 * @param p_menu  - the menu to get the number of levels for
 */
function getLevels(p_menu){
  var rval = 0;
  if (p_menu.hasParent){
    rval = 1;
    rval += getLevels(p_menu.parent);
  }
  return rval;

}

/**
 * get the index for the current menu item
 * @param p_menu  - the current menu
 */
function getIndex(p_menu){
  var rval = p_menu.list.length;

  if (p_menu.hasParent){
    rval = getIndex(p_menu.parent) + "@" + rval;
  }

  return rval;
}

/**
 * find the X position of a passed in object
 * @param obj - the object
 */
function findPosX(obj){
  var curleft = 0;
  if (obj.offsetParent){
    while (obj.offsetParent){
      curleft += obj.offsetLeft
      obj = obj.offsetParent;
    }
  }else if (obj.x){
    curleft += obj.x;
  }
  return curleft;
}

/**
 * find the Y position of a passed in object
 * @param obj - the object
 */
function findPosY(obj){
  var curtop = 0;
  if (obj.offsetParent){
    while (obj.offsetParent){
      curtop += obj.offsetTop
      obj = obj.offsetParent;
    }
  }else if (obj.y){
    curtop += obj.y;
  }
  return curtop;
}


/**
 * Close the whole menu
 */
function closeMenu(){
  hideMenu(-1);
}

