/**
 * Menu
 */
function Menu(idParent, idMenu, classItem, classOver, align, deltaX, deltaY) {

   /* Member */
   this.supermenu = null;
   this.arrSubMenus = new Array();
   this.arrMenuItems = new Array();
   this.isHidden = false;
   this.isOn = false;
   this.waitToHide = true;
   this.timeout = null;
   
   /* Konstruktor */
   this.Menu = function() {
      // doms
      this.domParent = document.getElementById(idParent);
      this.domMenu   = document.getElementById(idMenu);
      // optional
      if (typeof classItem  == 'undefined') classItem = '';
      if (typeof classOver  == 'undefined') classOver = '';
      if (typeof align  == 'undefined' || align==null) align = 'bottom';
      if (typeof deltaX == 'undefined' || deltaX==null) deltaX = 0;
      if (typeof deltaY == 'undefined' || deltaY==null) deltaY = 0;
      // an document haengen
      this.randID = ''+Math.random();
      this.randID = 'randID_'+this.randID.substring(2, this.randID.length);
      document[this.randID] = this;
      if (typeof document.menusystem == 'undefined')
         document.menusystem = new Array();
      document.menusystem.push(this);
      // Position absolut setzen
      this.domMenu.style.position = 'absolute';
      // Menu-Items sammeln
      this.collectMenuItems(this.domMenu);
      // SubMenu einordnen
      for (var i=0; i<document.menusystem.length-1; i++) {
         var oneMenu = document.menusystem[i];
         for (var j=0; j<oneMenu.arrMenuItems.length; j++) {
            if (this.domParent==oneMenu.arrMenuItems[j]) {
               oneMenu.addSubMenu(this);
               i=1000; // Ende
               break;
            }
         }
      }
      // Menu verstecken
      this.hideNow();
      // Maus-Effekte
      this.setHover(this.domParent, true, 'document.'+this.randID+'.on();');
      this.setHover(this.domParent, false, 'document.'+this.randID+'.off();');
      this.setHover(this.domMenu, true, 'document.'+this.randID+'.on();');
      this.setHover(this.domMenu, false, 'document.'+this.randID+'.off();');
      this.domParent.className = classItem;
      for(var l=0; l<this.arrMenuItems.length; l++) {
         this.arrMenuItems[l].className = classItem;
         this.setHover(this.arrMenuItems[l], true, 'this.className=\''+classOver+'\';');
         this.setHover(this.arrMenuItems[l], false, 'this.className=\''+classItem+'\';');
      }
   };
   
   /* MouseOver */
   this.on = function() {
      this.isOn = true;
      this.show();
      this.domParent.className = classOver;
      // SuperMenu benachrichtigen
      if (this.supermenu!=null)
         this.supermenu.show();
   };
   
   /* MouseOut */
   this.off = function() {
      this.isOn = false;
      this.hide(false);
   };
   
   /* anzeigen */
   this.show = function() {
      this.waitToHide = false;
      // andere verstecken
      for (var i=0; i<document.menusystem.length; i++) {
         if(document.menusystem[i]!=this)
            document.menusystem[i].hide(true);
      }
      if (this.timeout!=null)
      	window.clearTimeout(this.timeout);
		// SubMenu da?
		if(this.arrMenuItems.length>0) {
	      var pos = this.getPos(this.domParent);
	      var x = pos.x + deltaX;
	      var y = pos.y + deltaY;
	      if (align=='top')
	         y -= this.domMenu.offsetHeight;
	      else if (align=='left')
	         x -= this.domMenu.offsetWidth;
	      else if (align=='right')
	         x += this.domParent.offsetWidth;
	      else // Standard
	         y += this.domParent.offsetHeight;
	      this.domMenu.style.left = x;
	      this.domMenu.style.top  = y;
		}
      this.isHidden = false;
   };
   
   /* Menu verstecken vorbereiten */
   this.hide = function(bSofort) {
      if (this.isHidden || this.isOn || (this.waitToHide && !bSofort)) {
         this.waitToHide = false;
         return;
      }
      this.waitToHide = true;
      this.timeout = window.setTimeout('document.'+this.randID+'.hideNow();', bSofort ? 20 : 1000);
   };
   
   /* Menu echt verstecken */
   this.hideNow = function() {
      if (!this.waitToHide || this.isHidden || this.isOn) {
         this.waitToHide=false;
         return;
      }
      for (var i=0; i<this.arrSubMenus.length; i++) {
         if (!this.arrSubMenus[i].isHidden) {
            this.waitToHide=false;
            return;
         }
      }
      this.waitToHide = false;
      // Styles anpassen
      this.domMenu.style.left = -1000;
      this.domMenu.style.top  = -1000;
      this.domParent.className = classItem;
      // Status setzen
      this.isHidden = true;
      // SubMenus benachrichtigen
      for(var k=0; k<this.arrSubMenus.length; k++)
         this.arrSubMenus[k].hide(true);
      // SuperMenu benachrichtigen
      if (this.supermenu!=null && !this.supermenu.waitToHide)
         this.supermenu.hide(true);
   };

   /* selbst verwaltet: Super-Menu setzen */
   this.setTopMenu = function(supermenu) {
      this.supermenu = supermenu;
   };

   /* selbst verwaltet: Sub-Menus aufnehmen */
   this.addSubMenu = function(submenu) {
      this.arrSubMenus.push(submenu);
      submenu.setTopMenu(this);
   };

   /* Helper: Position des Parents ermitteln */
   this.getPos = function(el) {
		var r = { x: el.offsetLeft, y: el.offsetTop };
		if (el.offsetParent) {
			var tmp = this.getPos(el.offsetParent);
			r.x += tmp.x;
			r.y += tmp.y;
		}
		return r;
	};

   /* Helper: Attribut setzen */
   this.setHover = function(domNode, bOver, value) {
      var speicher = bOver ? 'myOver' : 'myOut';
      var oldValue = (typeof domNode[speicher]=='undefined') ? null : domNode[speicher];
      if(oldValue!=null) {
         if (oldValue.indexOf(value)!=-1) // gibts schon
            return;
         value = oldValue+value;
      }
      domNode[speicher] = value;
      if (bOver)
         domNode.onmouseover = function(){ eval(value); };
      else
         domNode.onmouseout  = function(){ eval(value); };
   };

   /* Helper: alle TD-Knoten mit ID bekommen */
   this.collectMenuItems = function(domStart) {
      if (domStart.nodeName.toLowerCase()=='td' && domStart.getAttribute('id')!=null && domStart.getAttribute('id').length>0) {
	      this.arrMenuItems.push(domStart);
      }
      else {   // nur oberste Ebene an TDs
         var childs = domStart.childNodes;
         for (var i=0; i<childs.length; i++) {
            this.collectMenuItems(childs[i]);
         }
      }
   };
   
   // Konstruktor aufrufen
   this.Menu();
}

