
  mxmenu.prototype.doOnWinResize = function()
  {
    documentX.moveElement(this.menuBarBase.id, documentX.elementLeft(this.menuBarBase.id), 0);
  }

  mxmenu.prototype.doOnScroll = function()
  {
    this.deactivateAll();
    //xSlideTo(this.menuBarBase.id, documentX.elementLeft(this.menuBarBase.id), documentX.getScrollTop() , 10);
  }

  // Create new mxmenu object .
  function mxmenu()
  {
    this.activatesWithClick = true;
    this.mxTracking = false;
    this.mxActive = false;
    this.menuBarBase  = null;
    this.horizontal = true;
    // defaults for where to show menus from primary bar
    this.hstyle = "below";// show menus below bar
    this.vstyle = "right";// show menus above bar

    this.mxall = new Array();

    this.menuBoxes  = new Array();
    this.selfref    = this;
    this.mxmenubar  = null;

    // define css style selectors for different element types

    // items boxes
    this.cssmxitemsbox       = 'mxitemsbox';
    this.cssmxitemsbar       = 'mxitemsbar';

    // item boxes
    this.cssmxitembox        = 'mxitembox';
    this.cssmxitemboxsel     = 'mxitemboxsel';
    this.cssmxbaritembox     = 'mxbaritembox';
    this.cssmxbaritemboxsel  = 'mxbaritemboxsel';

    // item icons
    this.cssmxitemicon       = 'mxitemicon';
    this.cssmxitemiconsel    = 'mxitemiconsel';
    this.cssmxbaritemicon    = 'mxbaritemicon';
    this.cssmxbaritemiconsel = 'mxbaritemiconsel';


    if (mxmenuManager)
    {
      mxmenuManager.addMenu(this.selfref);
    }
  }

  mxmenu.prototype.deactivateAll = function()
  {
    //if (!this.mxActive)
    //{
    //  return;
    //}
    this.mxTracking = false;
    var i;
    if (this.menuBoxes)
    {
      for (i=0; i<this.menuBoxes.length; ++i) {
        if (this.menuBoxes[i].mxmenuitemslevel > 0)
        {
          var mb= this.menuBoxes[i];
          mb.activeItems=null;
          mb.activeItem=null;
          documentX.hideElement(mb);
        }
      }
    }
    if (this.mxmenubar)
    {
      this.mxmenubar.activeItems=null;
      if (this.mxmenubar.activeItem)
      {
        this.selectItem(this.mxmenubar.activeItem,false);
      }
      this.toggleAllItems(this.mxmenubar,false);
    }
  }

  mxmenu.prototype.getMenuBoxById = function(mbid)
  {
    if (!utilsX.isString(mbid))
    {
      return null;
    }
    var teststr=mbid.toLowerCase();
    var mb;
    if (this.menuBoxes)
    {
      for (var i = 0; i < this.menuBoxes.length; ++i)
      {
        mb = this.menuBoxes[i];
        if (utilsX.isString(mb.id) )
        {
          if (teststr == mb.id.toLowerCase())
          {
            return mb;
          }
        }
      }
    }
    return null;
  }

  // called once for each element in menu container block .
  // if element is menuitem, keep track of it.
  // if element is menuitems, assign it to current menuitem.
  mxmenu.prototype.onWalk = function(e)
  {
    if (e)
    {
      var ix,temp,temps;
      e.mxmenu = this.selfref;
      e.ismxmenuitem=false;
      e.activeItems=null;
      e.mxitemboxes=null;
      e.mxitemicons=null;
      e.mxitems=null;
      if (utilsX.isString(e.className))
      {
        var sl=e.className.toLowerCase();
        if (sl=='mxmenuitem')
        {
          // got a menu item
          // get it's child menu parts
          e.ismxmenuitem = true;
          e.mxitemboxes = new Array();
          e.mxitemicons = new Array();
          e.mxall       = documentX.getElementsByTagName('',e);
          if (e.mxall)
          {
            for (ix=0;ix<e.mxall.length;++ix)
            {
              temp = e.mxall[ix];
              if (temp)
              {
                temp.mxmenuitem = e;
                if (utilsX.isString(temp.className))
                {
                  temps = temp.className.toLowerCase();
                  if ((temps == 'mxitembox') || (temps == 'mxbaritembox'))
                  {
                    e.mxitemboxes[e.mxitemboxes.length]=temp;
                  }
                  else if ((temps == 'mxitemicon') || (temps == 'mxbaritemicon'))
                  {
                    e.mxitemicons[e.mxitemicons.length]=temp;
                  }
                }
              }
            }
          }
          // look and see if the menu-item has a sub menu and attach
          if (utilsX.isString(e.id))
          {
            // menu sub-items are named the same as the parent menu item
            // with items appended . menu items must also be lowercase named
            var seid=e.id.toLowerCase();
            seid = seid + 'items';

            var subitems=this.getMenuBoxById(seid); // slower , ensures no id conflict
            //var subitems= documentX.getElementById(seid);// faster , bad if ids are not unique for multi menus
            if (subitems)
            {
              // assign references between menu item and items
              e.mxmenuitems=subitems;
              subitems.mxmenuitem=e;
            }
          }
          //alert(e.ismxmenuitem);
        }
        else if (sl == "mxmenuitems")
        {
          //alert('items');
          e.mxmenuitemslevel=1;
          e.ismxmenuitems=true;
          e.mxitems = documentX.getElementsByClassName('mxmenuitem',e);
          if (e.mxitems)
          {
            for (ix=0;ix<e.mxitems.length;++ix)
            {
              temp = e.mxitems[ix];
              if (temp)
              {
                temp.mxparentitems=e;
              }
            }
          }
          //documentX.moveElement(e,0,0);
          documentX.hideElement(e);
          //alert('assigned walkitem menuitems');
        }
        else if (sl == "mxmenubar")
        {
          e.ismxmenubar=true;
          e.ismxmenuitems=true;
          e.mxmenuitemslevel=0;
          this.mxmenubar=e;
          e.mxitems = documentX.getElementsByClassName('mxmenuitem',e);
          if (e.mxitems)
          {
            for (ix=0;ix<e.mxitems.length;++ix)
            {
              temp = e.mxitems[ix];
              if (temp)
              {
                temp.mxparentitems=e;
              }
            }
          }

          //alert('assigned walkitem menuitems');
        }
      }
    }
  }

  mxmenu.prototype.walktree = function()
  {
    var i,e;
    for (i=0;i<this.mxall.length;++i)
    {
      e = this.mxall[i];
      if (e)
      {
        this.onWalk(e);
      }
    }
  }

  //
  mxmenu.prototype.createMenu = function(AMenuBar,AItemsBase)
  {
    if ( utilsX.isString(AMenuBar) && (AMenuBar.length != 0) )
    {
      //alert('createMenu: tagString');
      if ( utilsX.isString(AItemsBase) && (AItemsBase.length != 0) )
      {
        this.menuItemsBase = documentX.getElementById(AItemsBase);
        if (!this.menuItemsBase)
        {
          // noop
        }

      }

      this.menuBarBase = documentX.getElementById(AMenuBar);


      //alert(this.menuBarBase);
      //alert(this.menuItemsBase);
      if (!this.menuBarBase)
      {
        alert('ERROR: Invalid id passed for menu bar base !');
        return false;
      }
      var xzall,i,e;
      xzall = documentX.getElementsByTagName('',this.menuBarBase);
      if (xzall)
      {
        for (i=0;i<xzall.length;++i)
        {
          e = xzall[i];
          if (e)
          {
            this.mxall[this.mxall.length]=xzall[i];
            if (utilsX.isString(e.className) && (e.className.toLowerCase()=='mxmenuitems'))
            {
              this.menuBoxes[this.menuBoxes.length]=e;
            }
          }
        }
      }
      xzall = documentX.getElementsByTagName('',this.menuItemsBase);
      if (xzall)
      {
        for (i=0;i<xzall.length;++i)
        {
          e = xzall[i];
          if (e)
          {
            this.mxall[this.mxall.length]=xzall[i];
            if (utilsX.isString(e.className) && (e.className.toLowerCase()=='mxmenuitems'))
            {
              this.menuBoxes[this.menuBoxes.length]=e;
            }
          }
        }
      }
      //alert(this.mxall.length);
      this.walktree();
      
      // move container for all the items boxes to 0,0 , because it gets created way off to
      // the top left so that it is not visible during loading.
      documentX.moveElement(this.menuItemsBase,0,0);
    }
    else
    {
      alert('ERROR: mxmenu - Invalid container string specified . Check the HTML id attributes of the container.');
    }
  }

  mxmenu.prototype.selectItem = function(mi,selected)
  {
    if (mi)
    {
      var i,e;
      var isrootlevel=false;
      if ((mi.mxparentitems && (mi.mxparentitems.mxmenuitemslevel==0)))
      {
        isrootlevel=true;
      }
      if (mi.mxitemboxes) {
	for (i = 0; i < mi.mxitemboxes.length; ++i) {
          e = mi.mxitemboxes[i];
          if (selected==true) {
            if (isrootlevel) {
              e.className = this.cssmxbaritemboxsel;
            }
            else {
              //e.className = this.cssmxitemboxsel;
            }
          }
          else
          {
            if (isrootlevel)
            {
              e.className = this.cssmxbaritembox;
            }
            else
            {
             //e.className = this.cssmxitembox;
            }
          }
	}
      }


      if (mi.mxitemicons)
      {
	for (i = 0; i < mi.mxitemicons.length; ++i)
        {
          e = mi.mxitemicons[i];
          if (selected==true)
          {
            if (isrootlevel)
            {
              e.className = this.cssmxbaritemiconsel;
            }
            else
            {
              e.className = this.cssmxitemiconsel;
            }
          }
          else
          {
            if (isrootlevel)
            {
              e.className = this.cssmxbaritemicon;
            }
            else
            {
              e.className = this.cssmxitemicon;
            }
          }
	}
      }
    }
  }

  mxmenu.prototype.toggleAllItems = function(mb,xselected)
  {
    if (mb && (mb.mxitems))
    {
      var i;
      for (i = 0; i < mb.mxitems.length; ++i)
      {
        this.selectItem(mb.mxitems[i],false);
      }
    }
    if (mb)
    {
      mb.activeItem = null;
    }
  }

  mxmenu.prototype.doMouseMove = function(evt)
  {
    if ((!evt) || (evt.isxEvent && !evt.target)) {
      alert('ERROR: bad event passed for mouse move !');
      return;
    }
    var xe22;
    if (evt.target) {
      xe22 = evt.target;
    } else {
      xe22 = evt;
    }
    var ele = xe22.mxmenuitem;
    if (!ele) {
      return;
    }
    // get parent box
    var mb = ele.mxparentitems;

    if (!mb) {
      //alert('ERROR: You have defined a menu item or element outside of a menuitems box');
      return;
    }
    else {
      //alert('overitems');
    }

    this.mxActive = true;
    if ((mb.activeItems) && (mb.activeItems.activeItems)) {
      documentX.hideElement(mb.activeItems.activeItems);
      mb.activeItems.activeItems = null;
      mb.activeItem=null;
    }

    if (mb.activeItems && (mb.activeItems.activeItem)) {
      this.selectItem(mb.activeItems.activeItem,false);
      mb.activeItems.activeItem=null;
    }

    if (ele) {
      if (mb.activeItem && (mb.activeItem != ele)) {
        this.selectItem(mb.activeItem,false);
        mb.activeItem=null;
      }

      if (mb.activeItem != ele) {
        this.toggleAllItems(mb,false);
        mb.activeItem = ele;
        this.selectItem(ele,true);
      }

      if ((mb.activeItems) && ((mb.activeItems) != (ele.mxmenuitems))) {
        documentX.hideElement(mb.activeItems);
        mb.activeItems = null;
        mb.activeItem=null;
      }
      if ((ele.mxmenuitems) && (mb.activeItems!=ele.mxmenuitems)) {
        this.toggleAllItems(ele.mxmenuitems,false);
        this.showItems(ele.mxmenuitems);
      }
    }

  }

  mxmenu.prototype.showItems = function(e) {
    if (this.activatesWithClick && (!this.mxTracking)) {
      return false;
    }
    if (!e) {
      alert('ERROR: function showItems , no element items');
    }
    documentX.showElement(e);

    var mi = e.mxmenuitem;
    var mb;
    mb = mi.mxparentitems;
    if (mb) {
      mb.activeItems = e;
    }

    if ((mb) && (mb.mxmenuitemslevel>0)) {
      //alert(documentX.elementTop(mi) + ':' + documentX.elementTop(mb) + ':' + documentX.elementY(mi) + ':' + documentX.elementY(mb));
      //alert(documentX.elementLeft(mb));
      if (this.hstyle=="below")
      {
        documentX.moveElement(e,documentX.elementLeft(mb) + documentX.elementWidth(mb) -4, documentX.elementTop(mb) + documentX.elementOffsetTop(mi));
      }
      else
      {
        documentX.moveElement(e,documentX.elementLeft(mb) + documentX.elementWidth(mb), documentX.elementTop(mb) + documentX.elementOffsetTop(mi) );
      }
    }
    else
    {
      if (this.horizontal==true)
      {
        if (this.hstyle=="below") {
          documentX.moveElement(e,documentX.elementOffsetLeft(mi),documentX.elementOffsetTop(mi) + documentX.elementHeight(mi)-documentX.elementHeight(this.menuBarBase)+documentX.getScrollTop());
        }
        else  {
          documentX.moveElement(e,xOffsetLeft(mi),documentX.elementOffsetTop(mi) - documentX.elementHeight(e));
        }
      }
      else {
        documentX.moveElement(e,xOffsetLeft(mi),documentX.elementOffsetTop(mi) + documentX.elementHeight(mi));
      }
    }
  }




