CLIENT_SIDE = typeof top != "undefined";
REG_EXP_SPACE = new RegExp("\\s+", 'g');

//menu implementation used serverside and clientside


function RegisterMenu(menu)
{
  var ret = 0;
  var menuarr;
  if (CLIENT_SIDE)
  {
    if (!top.menus)
      top.menus = new Array();

    menuarr = top.menus;

    menuarr[ret = menuarr.length] = menu;
  }
  return ret;
}

function getRegisteredMenu(id)
{
  var menuarr;
  if (CLIENT_SIDE)
  {
    menuarr=top.menus;
  }
  else
  {
    menuarr=menus;
  }
  return menuarr[id];
}

  //--------------------------------------------------------------------
  /**
   * ###Contructor for a Menu###
   *
   * @param close: bool: This parameter is only necessary for the top level menu.
   *    If this value is not set the top level menu is not hided if the mouse leaves
   *    this menu. This is the case for the normal menu in the user block.
   *    If the value is true, the menu is hided when the mouse leaves the menu. This
   *    should for example set for context menues opened by an icon.
   * @param obj: String: ###PARAMETER DESCRIPTION###
   * @param attrobj: Object: This parameter contains information about the object, where
   *    action should be performed. The members are:
   *      title: The title of the object
   *      url: The url of the object. This is typically the name of the object
   *      These values are used to create the necessary information in for example
   *      the mail link funktionality. This object can be set dynamically, befor
   *      a context menu is opened.
   * @param orientation: String: [top|left] This value defines the alignment of contained
   *      menuitems. If the orientation is top, menu items are aligend from left to right
   *      [item 1][item 2]...
   *      If the value is left, the menu items are aligned from top to bottom
   *      [item 1]
   *      [item 2]
   *      ...
   * @param frame: String: This parameter describes the HTML frame, where a submenu
   *      should be opened
   * @param frametop: bool: When frametop is true, the opened sub menu is placed at the
   *      top of the frame, and only the x coordinate is taken from the opening menu.
   *      If this value is false, the opened sub menu is placed at the left side of the
   *      frame, and only the y coordinate is taken from the openening menu.
   *      This seting is only relevant when frame is set.
   * @param relright: bool: When relright is true, the distancen from the right side of
   *      the frame is used to place the opened menu. This is necessary if the frame,
   *      where the sub menu is opened is not the left most frame.
   *      This seting is only relevant when frame is set.
   * @param container: String: This parameter spezifies, which frame contains a re-writeable
   *      html element (DIV in IE and Layer in NS).
   * @param cname: String: This parameter spezifies, which element should be used as constrained
   *      for the x position of the menu. This can be used in combination with the parameter
   *      relright=1.
   * @param containername: String: This parameter spezifies the name of the re-writeable
   *      html element.
   * @param width: String: This parameter spezifies the with of the menu. This value is used
   *      for the with attribute of an table. Typical values: "100%" or "600"
   * @param isiconbar: bool: When this value is set to true, menu items are visulized using,
   *      icons. If there is no icon configured for an menu item, the normal caption is displayed.
   * @param cssClass: String|void: defines the stylesheet class that should be used when
   *      creating the HTML; default: orientation=="left"-->"MenuList", otherwise "MenuBar"
   */
function Menu(caption,p)
{
  this.id_ = CLIENT_SIDE ? RegisterMenu(this) : 0;
  
  if (CLIENT_SIDE) {
    if (typeof top.menu_registeredMenus == "undefined") {
      top.menu_registeredMenus = [];
    }
    top.menu_registeredMenus[top.menu_registeredMenus.length] = this;
  }
  this.caption_=caption.replace(REG_EXP_SPACE, "&nbsp;");
  this.items_=new Array();
  this.created_=false;
  this.x_=0;
  this.y_=0;
  this.wasDown_=false;
  this.width_=null;
  if (p.close)
  {
    this.close_=p.close;
    this.child_=this;
  }
  else
    p.close_=false;
  if (p.savepos)
    this.useCookies_=p.savepos;
  else
    this.useCookies_=false;

  if (p.obj)
  {
    this.obj_=p.obj;
    if (typeof navigator != "undefined" && navigator.appVersion.indexOf("X11",0) == -1){
      if (typeof keyShortcuts!="undefined")
        keyShortcuts.setObj(p.obj);
    }
  }
  if (p.attrobj)
  {  // object:  attributes: title and url
    this.attrobj_=p.attrobj;
  }

  if (p.orientation)
    this.orientation_=p.orientation;
  else
    this.orientation_= "left";

  this.cssClass_=p.cssClass;
  if (!this.cssClass_) {
    if (this.orientation_=='left') {
      this.cssClass_="MenuItem";
    }
    else {
      this.cssClass_="MenuTitle";
    }
  }

//    if (p.frame && p.frame.indexOf('[')!=0) {
//      this.frame_ = "."+p.frame;
//    }
//    else {
    this.frame_ = p.frame;
//    }
  this.container_=p.container;
  this.containername_=p.containername;
  this.frametop_=p.frametop;
  this.relright_=p.relright;
  this.cname_=p.cname;
  this.xpos_ = p.xpos;
  this.ypos_ = p.ypos;
  this.menualignment_ = p.menualignment;

  if (p.width)
    this.width_=p.width;

  if (p.menuconf)
  {
    if (CLIENT_SIDE && typeof p.menuconf == "string")
    {
      eval("p.menuconf = " + p.menuconf + ";");
    }
    this.MenuConf_=p.menuconf;
  }
  else
  {
    if (typeof navigator != "undefined")
    {
      this.MenuConf_= DMC;
    }
  }

  if (p.isiconbar)
    this.isiconbar_=true;
  else
    this.isiconbar_=false;

  if (typeof p.showdisabledicons == "undefined" || p.showdisabledicons)
    this.showdisabledicons_=true;
  else
    this.showdisabledicons__=false;

  if (typeof navigator != "undefined")
  {
    mco=this.MenuConf_;

    if (mco.MenuWidth)
      this.width_=mco.MenuWidth;

    if (typeof mco.Margin !="number")
      mco.Margin=parseInt(mco.Margin);

    if (!mco.FontSize)
      mco.FontSize="+0";
    if (!mco.FontSizeAbs)
      mco.FontSizeAbs="";

    if (typeof mco.ItemDisColor == "undefined")
      mco.ItemDisColor=DMC.ItemDisColor;
  }
  this.hLays_=new Array();
  this.hanid_=-1;
}

function hw_addHand(p)
{
  if (!p)
    p={};
  p.ishandlel=true;
  newItem=new MenuItem("hand",p);
  newItem.menu_=this;
  this.items_[this.items_.length]=newItem;
  this.hanid_=this.items_.length-1;
}
Menu.prototype.addHand=hw_addHand

function hw_add(caption,p)
{
  if (!p.quickTestId && p.child) {
    p.quickTestId = p.child.caption_;
  }
  
  newItem= new MenuItem(caption,p);
  newItem.menu_=this;
  this.items_[this.items_.length]=newItem;
  if (newItem.child_)
    this.hasChild_=true;    
}
Menu.prototype.add=hw_add;

function hw_addItem(item)
{
  if (typeof item!="undefined" && item)
  {
    newItem= item;
    newItem.menu_=this;
    this.items_[this.items_.length]=newItem;
    if (newItem.child_)
      this.hasChild_=true;
  }
}
Menu.prototype.addItem=hw_addItem;

function hw_addSep()
{
  newItem= new MenuItem("",{isseperator:true});
  newItem.menu_=this;
  this.items_[this.items_.length]=newItem;
}
Menu.prototype.addSep=hw_addSep;

function hw_addHSpace()
{
  newItem= new MenuItem("",{isspace:true});
  newItem.menu_=this;
  this.items_[this.items_.length]=newItem;
}
Menu.prototype.addHSpace=hw_addHSpace;

//------------------------------------------------------------
// MenuItem implementations
//------------------------------------------------------------

  //--------------------------------------------------------------------
  /**
   * This is the contructor of a Menu Item
   *
   * @param maillink: bool: When this parameter is true, the in a parent menu
   *    passed attrobj is used to create a mailto link.
   * @param save: bool: When this parameter is true, the in a parent menu
   *    passed attrobj is used to fire the save.action and the save as dialog
   *    of the browser is triggered.
   * @param isseperator: bool: When this parameter is true, the item is displayed as
   *    seperator
   * @param isspace: bool: If this parameter is true, the item is dispayed without
   *    a caption but with maximal width requirements.
   * @param nohighlite: bool: When this parameter is true, there is no highlighting done
   *    on the item
   * @param isdisabled: bool: When this parameter is true, the the item is displayed
   *    "grayed". If it is has icons, and is displayed in an iconbar, the icondisabled
   *    is used.
   * @param icondefault: String: This icon is displayed as normal icon
   * @param icononmouseover: String: This icon is displayed, when the mous is over the item.
   * @param icondisabled: String: This icon is displayed, when the item has isdisabled set to true
   *    Icon setting are only used, when the menu has isiconbar set to true.
   * @param act: String: This action is added as "action" parameter, when the url is created
   * @param actp: String: This parameter is added as "action parameter" parameter, the
   *    url is created.
   * @param actmult: String: Same as act, but is used when more then one objects are selected.
   * @param actpmult: String: Same as actp, but is used when more then one objects are selected.
   * @param operation: String: ---
   * @param submit: bool: ---
   * @param target: String: When this parameter is set, the resulting page is displayed in an new
   *    window with the name of the value of "target".
   * @param targetmult: String: Same as target, but is used when more then one objects are selected.
   * @param winstyle: String: A newly opened window is opened with this style. The spezification is
   *    the same as the one used for the JavaScript command "window.open()".
   * @param name: String: The name attributes for form values of the checked objects
   * @param namemult: String: Same as name, but is used when more then one objects are selected.
   * @param op: bool: When this value is set to true, the function move is called.
   * @param opobj: bool: Same as op, but the "request.object" is the selected object.
   * @param url: String: The url, which is called, when the icon is clicked.
   * @param status: String: The value of this property is displayed in the status bar of the browser
   *    window, when the mouse moves over the item.
   * @param exec: String: The name of a function, which is called, when the item is clicked.
   * @param child: Menu: The child menu, which should be opened, when the item is clicked.
   * @param key: String: The shorcut key, which could be used to aktivate the menu item.
   * @param quickTestId: String|void: the html-id of the anchors around menu entries. These ids are 
   *   used for automated testing using the QuickTest-suite.
   */

function MenuItem(caption, p)
{
  this.id_ = CLIENT_SIDE ? RegisterMenu(this) : 0;
  
  if (p.quickTestId) {
    this.quickTestId_ = p.quickTestId;
  }
  
  this.child_=null;
  this.icondefault_=null;
  this.menu_=null;
  this.offsetComputed_=false;
  this.key_="";

  if (p.keepspaces) {
    this.keepspaces_=p.keepspaces;
    this.caption_=caption;
  } else {
    this.caption_=caption.replace(REG_EXP_SPACE, "&nbsp;");
  }

  if (typeof p.contexthelp == "boolean")
  {
    this.iscontexthelp_=p.contexthelp;
  }
  else
  {
    this.iscontexthelp_=false;
  }

  this.alignprevitem_=p.alignprevitem;

  if (p.print)
  {
    this.print_=true;
  }
  if (p.maillink)
  {
    this.maillink_=true;
  }
  if (p.save)
  {
    this.save_=true;
  }
  if (p.download)
  {
    this.download_=true;
  }

  if (typeof p.isseperator == "boolean")
  {
    this.isseperator_=p.isseperator;
    if (this.isseperator_)
      return;
  }
  else
    this.isseperator_=false;

  if (typeof p.isspace == "boolean")
  {
    this.isspace_=p.isspace;
    if (this.isspace_)
      return;
  }
  else
    this.isspace_=false;

  if (typeof p.nohighlite == "boolean")
    this.nohi_=p.nohighlite;
  else
    this.nohi_=false;

  if (typeof p.ishandlel == "boolean")
    this.ishanl_= p.ishandlel;
  else
    this.ishanl_=false;

  if (typeof p.ischecked == "boolean")
    this.ischecked_=p.ischecked;
  else
    this.ischecked_=false;

  if (typeof p.isdisabled == "string" && typeof navigator== "undefined")
  {
    this.isdisabled_=p.isdisabled;
  }
  else
  {
    if (typeof p.isdisabled == "boolean")
    {
      this.isdisabled_=p.isdisabled;
    }
    else if (typeof p.isdisabled == "string" && typeof navigator != "undefined")
    { // eval is no problem on clientside
      eval("this.isdisabled_ = " + p.isdisabled + ";");
    }
    else
    {
      this.isdisabled_=false;
    }
  }

  if (p.icondefault)
    this.icondefault_=p.icondefault;
  else
    this.icondefault_="";

  if (typeof p.icononmouseover != "undefined")
    this.icononmouseover_=p.icononmouseover;
  else
    this.icononmouseover_="";

  if (p.icondisabled)
    this.icondisabled_=p.icondisabled;
  else
    this.icondisabled_="";

  if (p.iwidth)
    this.iwidth_=p.iwidth;

  if (p.iheight)
    this.iheight_=p.iheight;

  if (p.act)
    this.act_=p.act;
  else
    this.act_="";
  if (p.actp)
    this.actp_=p.actp;
  else
    this.actp_="";

  if (p.actmult)
    this.actmult_=p.actmult;
  else
    this.actmult_="";
  if (p.actpmult)
    this.actpmult_=p.actpmult;
  else
    this.actpmult_="";

  if (p.operation)
    this.operation_=p.operation;
  else
    this.operation_="";

  if (typeof p.submit == "boolean")
    this.submit_=p.submit;
  else
    this.submit_=false;

  if (p.target)
    this.target_=p.target;
  else
    this.target_="";

  if (typeof p.targetmult != "undefined")
    this.targetmult_=p.targetmult;
  else
    this.targetmult_=this.target_;

  if (p.name)
    this.name_=p.name;
  else
    this.name_="";

  if (p.namemult)
    this.namemult_=p.namemult;
  else
    this.namemult_="";

  if (p.winstyle)
  {
    if (CLIENT_SIDE && typeof p.winstyle == "string")
    {
      eval("p.winstyle = " + p.winstyle + ";");
    }
    this.winstyle_=p.winstyle;
  }

  if (p.op)
    this.op_=p.op;
  else
    this.op_=false;

  if (p.opobj)
    this.opobj_=p.opobj;
  else
    this.opobj_=false;

  if (p.url)
    this.url_=p.url;
  else
    this.url_="";

  if (p.status)
    this.status_=p.status;
  else
    this.status="";

  if (p.exec)
  {
    if (typeof navigator != "undefined")
    {
      if (typeof p.exec == 'string')
        this.exec_=new Function('item',p.exec);
      else
        this.exec_=p.exec;
    }
    else
    {
      this.exec_=p.exec;
    }
  }
  else
    this.exec_="";

  if (p.child)
  {
    if (CLIENT_SIDE && typeof p.child == "string")
    {
      eval("p.child = " + p.child + ";");
    }
    this.child_=p.child;
    this.child_.parentItem_=this;
  }
  else
    this.child_=0;
  if (typeof navigator != "undefined")
  {
    if (navigator.appVersion.indexOf("X11",0) == -1)
    {
      if (!this.isdisabled_ && p.key && typeof keyShortcuts!="undefined")
      {
        this.key_=p.key;
        keyShortcuts.add(p);
      }
    }
  }
  else
  {
    if (p.key)
      this.key_=p.key;
  }
}

/**
 * Sets the html-id of the anchors around menu entries. These ids are used for automated 
 * testing using the QuickTest-suite.
 * 
 * @param theId: string: the quicktest id
 */
MenuItem.prototype.setQuickTestId = function (theId) {
  this.quickTestId_ = theId;
}

