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;
		       // get the menu
       var m = document.getElementById(id+"Container");
       // get the menu-item-container
       var mItemCont = m.firstChild.firstChild;
       // get the item-height
       var itemHeight = mItemCont.firstChild.offsetHeight;
       // get the item-count
       var itemCount = mItemCont.childNodes.length;
       // calc the height (+1 for the bottom shadow)
       var m_hight = (itemHeight * itemCount) +1; 
		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:0px; '
          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;

		// Änderung für IE | Ergänzung var
        for (var 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

		  // Änderung für IE | Ergänzung var
          for (var 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
 252.
         des Objekts element */

        var elem=element,tagname="",x=0,y=0;

        /* solange elem ein Objekt ist und die Eigenschaft offsetTop enthaelt
 256.
         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
 282.
         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;

      } 
