TDropdownMenu = function(menu) {
  this.menu = TDOM.getElement(menu);
  this.count = 0;
  this.speed = 0.15;
  this._anims = [];

  if (this.menu && this.menu.tagName.toUpperCase() == 'DL') {
    var dt = TDOM.firstChild(this.menu);
    while (dt && dt.nodeName.toUpperCase() != 'DT') {
      dt = TDOM.nextElement(dt);
    }
    while (dt) {
      var dd = TDOM.nextElement(dt);
      if (dd && dd.nodeName.toUpperCase() == 'DD') {
        dt[TDropdownMenu.ownAttr] = this.count;
        TEvents.listen(dt, 'mouseover', this.doOverDT, this);
        TEvents.listen(dt, 'mouseout', this.doOutDT, this);
        while (dd && dd.nodeName.toUpperCase() == 'DD') {
          dd[TDropdownMenu.ownAttr] = this.count;
          dd.style.display = 'none';
          TEvents.listen(dd, 'mouseout', this.doOutDD, this);
          TEvents.listen(dd, 'mouseover', this.doOverDD, this);
          TDOM.setStyle(dd, 'opacity', 0);
          dd = TDOM.nextElement(dd);
        }
        this.count++;
      }
      dt = dd;
    }
  }
}
TDropdownMenu.inherits(TEventDispatcher);
TDropdownMenu.ownAttr = "dropdown_menu_unique_id";;

TDropdownMenu.prototype.doOverDT = function(e) {
  this.openDT(e.currentTarget);
}

TDropdownMenu.prototype.doOutDT = function(e) {
  this.closeDT(e.currentTarget);
}

TDropdownMenu.prototype.doOverDD = function(e) {
  this.openDT(this.getDT(e.currentTarget));
}

TDropdownMenu.prototype.doOutDD = function(e) {
  this.closeDT(this.getDT(e.currentTarget));
}

TDropdownMenu.prototype.closeDT = function(dt) {
  var id = parseInt(dt[TDropdownMenu.ownAttr]);
  this.stopAnim(id);
  this.dispatch("close", dt);
  TDOM.removeClass(dt, 'open');
  var dd = TDOM.nextElement(dt);
  this._anims[id] = this._anims[id] || [];
  while (dd && dd.nodeName.toUpperCase() == 'DD') {
    this._anims[id].push(this.initAnim(dd, false));
    dd = TDOM.nextElement(dd);
  }
}

TDropdownMenu.prototype.openDT = function(dt) {
  var offset = -1;
  var id = parseInt(dt[TDropdownMenu.ownAttr]);
  this.stopAnim(id);
  this.dispatch("open", dt);
  TDOM.addClass(dt, 'open');
  var dd = TDOM.nextElement(dt);
  this._anims[id] = this._anims[id] || [];
  while (dd && dd.nodeName.toUpperCase() == 'DD') {
    var rec = TDOM.getBounds(dt);
    var rec2 = TDOM.getBounds(this.menu);
    dd.style.left = rec.left + 'px';
    dd.style.top = rec.top + rec.height + offset + 'px';
    dd.style.display = 'block';
    offset += rec.top - rec2.top + rec.height + offset;
    TDOM.addClass(dd, 'open');
    this._anims[id].push(this.initAnim(dd, true));
    dd = TDOM.nextElement(dd);
  }
}

TDropdownMenu.prototype.getDT = function(dd) {
  var dt = TDOM.previousElement(dd);
  while (dt && dt.nodeName.toUpperCase() != 'DT') {
    dt = TDOM.previousElement(dd);
  }
  return dt;
}

/**
 * Stop any pending animation on tab
 * @param {Integer} id: tab id
 */
TDropdownMenu.prototype.stopAnim = function (id) {
  var anims = this._anims[id];
  if (anims && anims.length) {
    while (anims.length > 0) {
      var anim = anims.shift();
      window.clearInterval(anim);
    }
  }
}

/**
 * Initialize an open or close animation
 * @param {Element} dd: dd element
 */
TDropdownMenu.prototype.initAnim = function (dd, open) {
  var speed = this.speed;
  var opacity = parseFloat(TDOM.getStyle(dd,'opacity'));
  var anim = window.setInterval(
      function () {
        if (open) {
          opacity += speed;
          opacity = opacity > 1 ? 1 : opacity;
          if (opacity >= 1) {
            window.clearInterval(anim);
          }
        } else {
          opacity -= speed;
          opacity = opacity < 0 ? 0 : opacity;
          if (opacity <= 0) {
            dd.style.display = 'none';
            window.clearInterval(anim);
          }
        }
        TDOM.setStyle(dd,'opacity',opacity);
      }, 35);
  return anim;
}

