
  function cMenu (){
    var m_iWidth;
    var m_oChild;      
    var m_oEvent = new cEvent();
    var m_oDiv = null;
    var m_oSelf = this;
    var m_oItems = new Array();
    var m_iKey = cMenu.Instances.length;
    cMenu.Instances[cMenu.Instances.length] = this;
    var m_IsOnload = false;
    var m_idTimer;
    var m_TimerCount = 0;
    var m_oFormular = null;
    
    // -------------------------------------------------------------------    
    function getBody(){
      return document.getElementsByTagName("body")[0];
    }
    // -------------------------------------------------------------------            
    function removeAllMenuInstance(){
      if(cMenu.Selected != null){
        cMenu.Selected._remove();  // faster than below
      }
//      for(var ii = 0; ii < cMenu.Instances.length; ii ++){
//        cMenu.Instances[ii]._remove();         
//      }
    };
    // -------------------------------------------------------------------    
    function createElement(type, parent) {
      var el = null;
      if(document.createElementNS) {
        // use the XHTML namespace; IE won't normally get here unless
        // _they_ "fix" the DOM2 implementation.
        el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
      } 
      else{
        el = document.createElement(type);
      }
      if (typeof(parent) != "undefined" && parent != null) {
        parent.appendChild(el);
      }
      return el;
    };       
    // -------------------------------------------------------------------    
    function getAbsolutePos(el){
      var SL = 0, ST = 0;
      var is_div = /^div$/i.test(el.tagName);
      if (is_div && el.scrollLeft)
        SL = el.scrollLeft;
      if (is_div && el.scrollTop)
        ST = el.scrollTop;
      var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
      if (el.offsetParent) {
        var tmp = getAbsolutePos(el.offsetParent);
        r.x += tmp.x;
        r.y += tmp.y;
      }
      return r;
    };
    // -------------------------------------------------------------------    
    function getAbsoluteFinalPos(){
      var pos = getAbsolutePos(m_oChild);
      var oBody  = getBody();
      pos.x += oBody.scrollTop;
      pos.y += oBody.scrollLeft;
      pos.x += m_oChild.offsetWidth;
      pos.y += m_oChild.offsetHeight/2;
      return pos;
    }
    // -------------------------------------------------------------------
    function unit(value){
      if(value.toString().indexOf('%') != -1){
        return value;
      }
      return value + 'px';        
    };
    // -------------------------------------------------------------------    
    function show(){
      if(m_oItems.length == 0) return;

      removeAllMenuInstance();

      cMenu.Selected = m_oSelf;
      
      // Build the menu
      var pos = getAbsoluteFinalPos();
            
      m_oDiv = createElement('div');
      with(m_oDiv){
        id = 'id-menu-container';  // don't change the value of Id
        className = 'menu-container';
        style.left = unit(pos.x);
        style.top  = unit(pos.y);
        style.width  = unit(m_iWidth);
        style.zIndex = 1000;
        onmouseout = m_oEvent.bindEvent(m_oSelf.onmouseout, m_oSelf);
        onmouseup  = m_oEvent.bindEvent(m_oSelf.onmouseup , m_oSelf);
      }

      var oTable = createElement('table', m_oDiv);
      var oTbody = createElement('tbody', oTable);    
      with(oTable){
        cellSpacing = 0;
        cellPadding = 0;
        style.width  = unit('100%');      
        className = 'menu-table-body';      
      }
       
      for(var item = 0; item < m_oItems.length ; item++){
        var oTr = createElement('tr', oTbody);    
        var arr = m_oItems[item].get();
        var oTd = new Array();
        
        // Row
        with(oTr){
          className = 'menu-row';  
        }
        // Cells
        for(p in arr){
          if(p.toString().toLowerCase() == 'icone'){
            oTd[0] = createElement('td');    
            with(oTd[0]){
              className = 'menu-cell-' + p.toString().toLowerCase();
              style.borderTopWidth = arr['Sep'] == '-' ? unit(1) : unit(0);          
            }
            var oImage = createElement('img', oTd[0]);    
            with(oImage){
              className = oTd[0].className + '-image';
              src = arr['IconeUrl'] + '/' + arr['Icone'].getIcone();
            }            
          }
          if(p.toString().toLowerCase() == 'text'){
            oTd[1] = createElement('td');    
            with(oTd[1] ){
              className = 'menu-cell-' + p.toString().toLowerCase();
              style.borderTopWidth = arr['Sep'] == '-' ? unit(1) : unit(0);          
            }
            var oA = createElement('a', oTd[1] );    
            with(oA){
              className = oTd[1] .className + '-link';
              if(arr['MsgBox'] != ''){
                onclick = m_oEvent.bindEvent(m_oSelf.formular, arr);       
                href = '#';         
              }
              else{
                href = arr['Url'];                  
              }
              target      = arr['Target'];
              innerHTML   = arr['Text'];
              onmousedown = arr['onmousedown'];
              onmouseup   = arr['onmouseup'];
              onmousemove = arr['onmousemove'];
            }
          }
        }
        oTr.appendChild(oTd[0]);
        oTr.appendChild(oTd[1]);
      }

      // Append the menu to the body
      var oBody = getBody();
      if(!m_oFormular){
        m_oFormular = createElement('form',oBody); // we attach the form on the body because the menu (div) is delete when a mouse action is done 
        with(m_oFormular){                         // It's the reason we don't attach the form on the menu (div)
          style.display = 'none';  
        }
      }
      with(oBody){
        appendChild(m_oDiv);
        //onmouseup = m_oEvent.bindEvent(m_oSelf.onmouseup_body, m_oSelf);
        m_oEvent.AddEvent(oBody, 'mouseup', m_oSelf.onmouseup_body,false);
      }
    }
    // -------------------------------------------------------------------    
    this.formular = function(event) {
      var Item = this;
      var ret = confirm(Item.MsgBox);      
      if(ret){
        with(Item.Parent.getObjFormular()){
          target = Item.Target;  
          //innerHTML='<input type="hidden" name="test" value="4"></input>'; test to pass by post
          action = Item.Url;
          method = 'post';        
          submit();
        }
      }
    }    
    // -------------------------------------------------------------------    
    this.getObjFormular = function() {
      return m_oFormular;
    }    
    // -------------------------------------------------------------------    
    this.onmouseupChild = function (event){
      var evt = window.event || event;
      show();
    };
    // -------------------------------------------------------------------    
    this.onmouseup_body = function (event){ // on <body>
      var evt = window.event || event;
      if(m_IsOnload){
        m_oSelf._remove();
      }
      else{
        m_IsOnload = true;  // may be we can find better ????
      }
    };
    // -------------------------------------------------------------------    
    this.onmouseout = function (event){// on <div>
      var evt = window.event || event;
      if(m_oDiv == null) return;            
      var pos = getAbsoluteFinalPos();
      if((evt.clientX > pos.x && evt.clientX < (pos.x + m_oDiv.offsetWidth)) &&
         (evt.clientY > pos.y && evt.clientY < (pos.y + m_oDiv.offsetHeight))){
         return;
      }
      this._remove();
    };
    // -------------------------------------------------------------------    
    this.onmouseup = function (event){  // on <div>
      var evt = window.event || event;
      if(typeof(m_iKey) == 'undefined') return;
      m_IsOnload = false; // we clear this flag else the event is send to the body      
      var oBody  = getBody();
      //oBody.onmouseup = null;  // we delete else the event is send to the body
      // we do that because if we have link in the menu and we close directly the menu we don't have time to execute the link
      // we make a tempo
      m_idTimer = window.setInterval('cMenu.Instances['+ m_iKey +']._timer()',100);  // base time is 100 msec
    };
    // -------------------------------------------------------------------    
    this.setWidth = function(width){
      m_iWidth   = width;
    };
    // -------------------------------------------------------------------    
    this.appendChild = function(oObject){
      m_oChild = oObject;      
      with(m_oChild){
        onmouseup = m_oEvent.bindEvent(this.onmouseupChild, this);
      }
    };
    // -------------------------------------------------------------------        
    this.addItem = function(){
      var oItem = new cItem(this);
      m_oItems[m_oItems.length] = oItem;
      return oItem;
    }; 
    // -------------------------------------------------------------------        
    this._timer = function(){
      ++m_TimerCount;      
      if(m_TimerCount >= 1){// base time is 100 msec
        this._remove();
        m_TimerCount = 0;  
        window.clearInterval(m_idTimer);
      }
    };
    // -------------------------------------------------------------------    
    this._remove = function(){
      if(m_oDiv == null) return;      
      var oBody  = getBody();
      with(oBody){
        //onmouseup = null;
        m_oEvent.RemoveEvent(oBody,'mouseup',m_oSelf.onmouseup_body);
      }
      with(m_oDiv){
        onmouseout = null;
        onmouseup = null;
      }
      try{
        with(oBody){
          removeChild(m_oDiv);
        }
      }
      catch(err){
        // if the node doesnt'exist
      }
      m_oDiv = null;
      m_IsOnload = false;
      cMenu.Selected = null;
    };
  }  
  
  // -------------------------------------------------------------------      
  cMenu.Instances = new Array();  // All instance menu
  cMenu.Selected  = null;
  