      /*****************************************************
      * ypSlideOutMenu
      * 3/04/2001
      *
      * a nice little script to create exclusive, slide-out
      * menus for ns4, ns6, mozilla, opera, ie4, ie5 on
      * mac and win32. I've got no linux or unix to test on but
      * it should(?) work...
      *
      * --youngpup--
       
      * ?berarbeitet typo.intervation.de 2007
      *****************************************************/
       
      ypSlideOutMenu.Registry = []
      ypSlideOutMenu.aniLen = 450
      ypSlideOutMenu.hideDelay = 50
      ypSlideOutMenu.minCPUResolution = 10
       
      // constructor
      function ypSlideOutMenu(id, dir, left, top, width, height, parentid)
      {
        this.ie  = document.all ? 1 : 0
        this.ns4 = document.layers ? 1 : 0
        this.dom = document.getElementById ? 1 : 0
       
              //alert(id+"Container");
        if (this.ie || this.ns4 || this.dom) {
          var m_hight = document.getElementById(id+"Container").offsetHeight;
         
          this.id    = id
          this.dir     = dir
          this.orientation = dir == "left" || dir == "right" ? "h" : "v"
          this.dirType   = dir == "right" || dir == "down" ? "-" : "+"
          this.dim     = this.orientation == "h" ? width : height
          this.hideTimer   = false
          this.aniTimer  = false
          this.open   = false
          this.over   = false
          this.startTime   = 0
       
          this.sliding   = false
          this.parentid  = parentid
          this.showcount   = 0
       
          // global reference to this object
          this.gRef = "ypSlideOutMenu_"+id
          eval(this.gRef+"=this")
         
          this.initleft = left
          this.inittop = top
          this.initwidth = width
          this.initheight = height
          this.showcount = 0;
       
       
          // add this menu object to an internal list of all menus
          ypSlideOutMenu.Registry[id] = this
       
          var d = document
       
                      var strCSS = '<style type="text/css">';
                      strCSS += '#' + this.id + 'Container { visibility:hidden; '
          strCSS += 'left:' + left + 'px; '
          strCSS += 'top:' + top + 'px; '
          strCSS += 'overflow:hidden; z-index:10000; text-align:left}'
          strCSS += '#' + this.id + 'Container, #' + this.id + 'Content { position:absolute; '
          strCSS += 'width:' + width + 'px;padding-bottom:20px;margin-left:1px; '
          strCSS += 'height:' + m_hight + 'px; '
          strCSS += 'clip:rect(0 ' + width + ' ' + m_hight + ' 0); '
          strCSS += '}'
                      strCSS += '</style>';
      
                      d.write(strCSS)
       
          this.load()
        }
      }
       
      ypSlideOutMenu.set_level_one = function(vert) {
       
        ypSlideOutMenu.horz_vert = vert;
       
      }
      ypSlideOutMenu.writeCSS = function() {
        document.writeln('<style type="text/css">');
        for (var id in ypSlideOutMenu.Registry) {
          document.writeln(ypSlideOutMenu.Registry[id].css);
        }
        document.writeln('</style>');
      }
       
      ypSlideOutMenu.prototype.load = function() {
        var d = document
        var lyrId1 = this.id + "Container"
        var lyrId2 = this.id + "Content"
        var obj1 = this.dom ? d.getElementById(lyrId1) : this.ie ? d.all[lyrId1] : d.layers[lyrId1]
        if (obj1) var obj2 = this.ns4 ? obj1.layers[lyrId2] : this.ie ? d.all[lyrId2] : d.getElementById(lyrId2)
        // var temp
       
        if (!obj1 || !obj2) window.setTimeout(this.gRef + ".load()", 1000)
        else {
          this.container  = obj1
          this.menu  = obj2
          this.style    = this.ns4 ? this.menu : this.menu.style
          this.homePos  = eval("0" + this.dirType + this.dim)
          this.outPos  = 0
          this.accelConst = (this.outPos - this.homePos) / ypSlideOutMenu.aniLen / ypSlideOutMenu.aniLen
       
          // set event handlers.
          if (this.ns4) this.menu.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT);
          this.menu.onmouseover = new Function("ypSlideOutMenu.showMenu('" + this.id + "')")
          this.menu.onmouseout = new Function("ypSlideOutMenu.hideMenu('" + this.id + "')")
       
          //set initial state
          this.endSlide()
        }
      }
       
      ypSlideOutMenu.showMenu = function(id, layerid, idw, level)
      {
        var reg = ypSlideOutMenu.Registry
        var obj = ypSlideOutMenu.Registry[id]
        if(layerid) {
          idw.onactivate = function() { repositionMenu(idw, layerid, level); }
         
        }
         
        if (obj.container) {
          obj.over = true
       
          // close other menus.
          // for (menu in reg) if (id != menu) ypSlideOutMenu.hide(menu)
       
          // if this menu is scheduled to close, cancel it.
          if (obj.hideTimer) { reg[id].hideTimer = window.clearTimeout(reg[id].hideTimer) }
       
          obj.showcount++;
       
          // if this menu is closed, open it.
          if (!obj.open && !obj.aniTimer) reg[id].startSlide(true)
        }
      }
      
      ypSlideOutMenu.hideMenu = function(id)
      {
        // schedules the menu to close after <hideDelay> ms, which
        // gives the user time to cancel the action if they accidentally moused out
        var obj = ypSlideOutMenu.Registry[id]
       
        if (obj.container) {
          if (obj.hideTimer) window.clearTimeout(obj.hideTimer)
         
          obj.showcount--;
         
          obj.hideTimer = window.setTimeout("ypSlideOutMenu.hide('" + id + "')", ypSlideOutMenu.hideDelay);
        }
      }
       
      ypSlideOutMenu.hide = function(id)
      {
        var obj = ypSlideOutMenu.Registry[id]
        var reg = ypSlideOutMenu.Registry
        obj.over = false
       
        if (obj.hideTimer) window.clearTimeout(obj.hideTimer)
       
        // flag that this scheduled event has occured.
        obj.hideTimer = 0
       
        var close = true;
       
        for (menu in reg) {
        // for each child, if either
        // 1. the child is open or
        // 2. the child is closing (but hasn't closed yet)
        // then we don't close this menu.
          var pid = ypSlideOutMenu.Registry[menu].parentid;
          if(pid == id) {
            if (ypSlideOutMenu.Registry[menu].open) close = false;
            if (!ypSlideOutMenu.Registry[menu].open && ypSlideOutMenu.Registry[menu].sliding) close = false;
          }
        }
       
        // if this menu is open, close it.
        if (obj.open && !obj.aniTimer && close && !obj.showcount) obj.startSlide(false);
      }
       
      ypSlideOutMenu.prototype.startSlide = function(open) {
        this[open ? "onactivate" : "ondeactivate"]()
        this.open = open
        if (open) this.setVisibility(true)
        this.startTime = (new Date()).getTime() 
        this.sliding = true;
        this.aniTimer = window.setInterval(this.gRef + ".slide()", ypSlideOutMenu.minCPUResolution)
      }
       
      ypSlideOutMenu.prototype.slide = function() {
        var elapsed = (new Date()).getTime() - this.startTime
        if (elapsed > ypSlideOutMenu.aniLen) this.endSlide()
        else {
          var d = Math.round(Math.pow(ypSlideOutMenu.aniLen-elapsed, 2) * this.accelConst)
          if (this.open && this.dirType == "-")  d = -d
          else if (this.open && this.dirType == "+")  d = -d
          else if (!this.open && this.dirType == "-") d = -this.dim + d
          else                    d = this.dim + d
       
          this.moveTo(d)
        }
      }
       
      ypSlideOutMenu.prototype.endSlide = function() {
        this.aniTimer = window.clearTimeout(this.aniTimer)
        this.moveTo(this.open ? this.outPos : this.homePos)
        if (!this.open) this.setVisibility(false)
        this.sliding = false;
        if ((this.open && !this.over) || (!this.open && this.over) && (!this.parent || this.parent.open)) {
          this.startSlide(this.over)
        } else {
          var overchild = false;
          var reg = ypSlideOutMenu.Registry
          for (menu in reg) {
            var pid = ypSlideOutMenu.Registry[menu].parentid
            if (pid == this.id) overchild = ypSlideOutMenu.Registry[menu].over ? true : overchild
          }
          if(!overchild && this.parentid && !ypSlideOutMenu.Registry[this.parentid].over) ypSlideOutMenu.hide(this.parentid);
        }
      }
       
      ypSlideOutMenu.prototype.setVisibility = function(bShow) {
        var s = this.ns4 ? this.container : this.container.style
        s.visibility = bShow ? "visible" : "hidden"
      }
      ypSlideOutMenu.prototype.moveTo = function(p) {
        this.style[this.orientation == "h" ? "left" : "top"] = this.ns4 ? p : p + "px"
      }
      ypSlideOutMenu.prototype.getPos = function(c) {
        return parseInt(this.style[c])
      }
       
      // events
      ypSlideOutMenu.prototype.onactivate  = function() { }
      ypSlideOutMenu.prototype.ondeactivate = function() { }
       
      function getPosition(element) {
      /* der Aufruf dieser Funktion ermittelt die absoluten Koordinaten
         des Objekts element */
        
        var elem=element,tagname="",x=0,y=0;
        /* solange elem ein Objekt ist und die Eigenschaft offsetTop enthaelt
         wird diese Schleife fuer das Element und all seine Offset-Eltern ausgefuehrt */
         
        while ((typeof(elem)=="object")&&(typeof(elem.tagName)!="undefined"))
        {
        
          y+=elem.offsetTop;     /* Offset des jeweiligen Elements addieren */
          x+=elem.offsetLeft;    /* Offset des jeweiligen Elements addieren */
       
          tagname=elem.tagName.toUpperCase(); /* tag-Name ermitteln, Grossbuchstaben */
       
        /* wenn beim Body-tag angekommen elem fuer Abbruch auf 0 setzen */
       
          if (tagname=="HTML") {
            elem=0;
          
        }
        if (tagname=="BODY" && navigator.userAgent.indexOf("Opera")>-1) {
          elem=0;
        }
        if (tagname=="BODY" && !navigator.userAgent.indexOf("Opera")>-1) {
          elem=0;
        }
       
        /* wenn elem ein Objekt ist und offsetParent enthaelt
         Offset-Elternelement ermitteln */
          if (typeof(elem)=="object")
            if (typeof(elem.offsetParent)=="object")
              elem=elem.offsetParent;
        }
       
      /* Objekt mit x und y zurueckgeben */
        position=new Object();
        position.x=x;
        position.y=y;
        return position;
      }
      // this function repositions a menu to the speicified offset from center
      function repositionMenu(menu, offset, level) {
       
        /* Element-Objekt zur ID ermitteln */
        element=document.getElementById(offset);
         //alert(document.getElementById(offset).pageXOffset);
      /* Position bestimmen und melden */
        //alert(document.getElementById(offset).offsetWidth);
      // the new left position should be the center of the window + the offset
        var newLeft = getPosition(element);
       
        if(level)
          var erx = newLeft.x+document.getElementById(offset).offsetWidth;
        else {
          if(ypSlideOutMenu.horz_vert == "down") {
            erx = newLeft.x;
            newLeft.y = newLeft.y+ element.offsetHeight;
          }
          else {
            erx = newLeft.x + element.offsetWidth;
            newLeft.y = newLeft.y;
          }
        }
       
      // setting the left position in netscape is a little different than IE
        menu.container.style ? menu.container.style.left = erx + "px" : menu.container.left = newLeft.x;
        menu.container.style ? menu.container.style.top = newLeft.y + "px" : menu.container.top = newLeft.y;
      }
       
      // this function calculates the window's width - different for IE and netscape
      function getWindowWidth()
      {
        return window.innerWidth ? window.innerWidth : document.body.offsetWidth;
      } 
