var floatingMenu = {

init: function (floatingMenuId){
   floatingMenu.targetX = 0;
   floatingMenu.targetY = 0;
   floatingMenu.hasInner = typeof(window.innerWidth) == 'number';
   floatingMenu.hasElement = document.documentElement && document.documentElement.clientWidth;
   floatingMenu.menu = document.getElementById ? document.getElementById(floatingMenuId) : document.all ? document.all[floatingMenuId] : document.layers[floatingMenuId];
   if (document.layers)
      floatingMenu.initPrimary();
   else {
      floatingMenu.initPrimary();
      floatingMenu.initSecondary();
      }
   },

move: function () {
   if (document.layers) {
      this.menu.left = this.nextX;
      this.menu.top = this.nextY;
      }
   else {
      this.menu.style.left = this.nextX + 'px';
      this.menu.style.top = this.nextY + 'px';
      }
   },

computeShifts: function () {
   var de = document.documentElement;
   this.shiftX = this.hasInner ? pageXOffset : this.hasElement ? de.scrollLeft : document.body.scrollLeft;
   if (this.targetX < 0) {
      if (this.hasElement && this.hasInner) {
         // Handle Opera 8 problems
         this.shiftX += de.clientWidth > window.innerWidth ? window.innerWidth : de.clientWidth}
      else {
         this.shiftX += this.hasElement ? de.clientWidth : this.hasInner ? window.innerWidth : document.body.clientWidth;
         }
      }
   this.shiftY = this.hasInner ? pageYOffset : this.hasElement ? de.scrollTop : document.body.scrollTop;
   if (this.targetY < 0) {
      if (this.hasElement && this.hasInner) {
         // Handle Opera 8 problems
         this.shiftY += de.clientHeight > window.innerHeight ? window.innerHeight : de.clientHeight}
      else {
         this.shiftY += this.hasElement ? document.documentElement.clientHeight : this.hasInner ? window.innerHeight : document.body.clientHeight;
         }
      }
   },

doFloat: function() {
   var stepX, stepY;
   this.computeShifts();
   stepX = (this.shiftX + this.targetX - this.nextX) * .07;
   if (Math.abs(stepX) < .5) {
      stepX = this.shiftX + this.targetX - this.nextX;
      }
   stepY = (this.shiftY + this.targetY - this.nextY) * .07;
   if (Math.abs(stepY) < .5) {
      stepY = this.shiftY + this.targetY - this.nextY;
      }
   if (Math.abs(stepX) > 0 || Math.abs(stepY) > 0) {
      this.nextX += stepX;
      this.nextY += stepY;
      this.move();
      }
   setTimeout('floatingMenu.doFloat()', 20);
   },

addEvent: function(element, listener, handler) {
   if(typeof element[listener] != 'function' || typeof element[listener + '_num'] == 'undefined') {
      element[listener + '_num'] = 0;
      if (typeof element[listener] == 'function') {
         element[listener + 0] = element[listener];
         element[listener + '_num']++;
         }
      element[listener] = function(e) {
         var r = true;
         e = (e) ? e : window.event;
         for(var i = element[listener + '_num'] - 1; i >= 0; i--) {
            if(element[listener + i](e) == false)r = false;
            }
         return r;
         }
      }
   //if handler is not already stored, assign it
   for(var i = 0; i < element[listener + '_num']; i++)if(element[listener + i] == handler)return;
   element[listener + element[listener + '_num']] = handler;
   element[listener + '_num']++;
   },

initPrimary: function() {
   this.initSecondary();
   this.doFloat();
   },

initSecondary: function() {
   this.computeShifts();
   this.nextX = this.shiftX + this.targetX;
   this.nextY = this.shiftY + this.targetY;
   this.move();
   }

}
