function bid(id) { return document.getElementById(id); }

function Roll(id, dt, n, i) {
  var i=(i)?i:0, it;
  if (it = bid(id).itemObj) {
    it.UpDatePos(it.div.mw*i/n, it.div.mh*i/n);
    i++;
    if (i<=n) it.timer = setTimeout("Roll(\"" + id + "\", " + dt + ", " + n + ", " + i + ")", dt);
      else {
        clearTimeout(it.timer);
        it.timer = null;
        bid(id).style.overflow="visible";
      }
  }
}
  
function ItemSHEffect() {
  if(this.effect>=0 && this.effect<=22) {  // RevealTrans //
    if (!this.div.filters.revealtrans) {
      this.div.style.filter += ", revealtrans(duration=" + this.duration + ", transition=" + this.effect + ")";
    }
    if (this.div.filters.revealtrans) {
      this.div.style.display = "none";
      this.div.filters.revealtrans.Apply();
      this.div.style.display = "block";
      this.div.filters.revealtrans.Play();
    }
    return;
  }
  
  switch(this.effect) {
// -------------------------------
    case 50:      // BlendTrans //
// -------------------------------
      if (!this.div.filters.blendTrans) {
        this.div.style.filter += ", blendTrans(duration=" + this.duration + ")";
      }
      if (this.div.filters.blendTrans) {
        this.div.style.display = "none";
        this.div.filters.blendTrans.Apply();
        this.div.style.display = "block";
        this.div.filters.blendTrans.Play();
      }
      break;
// -------------------------------
    case 60:         // Rolling //
// -------------------------------
      this.div.style.overflow = "hidden";
      Roll(this.div.id, this.duration, this.rollN);
      break;
// -------------------------------
  }
}

function ItemObj(id, menu, opt) {
  this.parentMenu = menu;
  this.id = id;
  this.menu = null;
  this.caption = bid(opt[0]);
  this.div = bid(opt[1]);
  this.caption.itemObj = this;
  this.div.itemObj = this;
  this.timer = null;
  
  var i = this;
  do { i.div.style.display = "block"; } while(i=i.parentMenu.parentItem)
  this.div.mw = this.div.offsetWidth;
  this.div.mh = this.div.offsetHeight;
  var i = this;
  do { i.div.style.display = "none"; } while(i=i.parentMenu.parentItem)
  
  this.div.style.position = "absolute";

  this.pos = opt[2] || this.parentMenu.defPos;
  this.align = opt[3] || this.parentMenu.defAlign;
  this.effect = opt[6] || this.parentMenu.defEffect;
  this.duration = opt[7] || this.parentMenu.defDuration;
  this.rollN = opt[8] || this.parentMenu.gefRollN;
  
  this.activeClass = opt[4] || this.parentMenu.defActiveClass;
  this.passiveClass = opt[5] || this.parentMenu.defPassiveClass;
  
  if (this.passiveClass) this.caption.className = this.passiveClass;
  
  this.SHEffect = ItemSHEffect;
  
  this.UpDatePos = function(w, h) {
/*    var x=0, y=0;
    var cx = this.caption.offsetLeft;
    var cy = this.caption.offsetTop;
    var cw = this.caption.offsetWidth;
    var ch = this.caption.offsetHeight;
    switch(this.pos) {
      case "bottom": y = cy + ch; break;
      case "top": y = cy - h; break;
      case "left": x = cx - w; break;
      case "right": x = cx + cw; break;
    }
    switch(this.align) {
      case "bottom": y = cy + ch - h; break;
      case "top": y = cy; break;
      case "left": x = cx; break;
      case "right": x = cx + cw - w; break;
    }
    this.div.style.left = x + "px";
    this.div.style.top = y + "px";
    this.div.style.width = w + "px";
    this.div.style.height = h + "px";*/
  }
  
  this.Show = function() {
    this.UpDatePos(this.div.mw, this.div.mh);
    this.parentMenu.active = this.id;
    this.div.style.display = "block";
    if (this.activeClass) this.caption.className = this.activeClass;
    this.SHEffect();
  }
  
  this.Hide = function() {
    if (this.menu) for (var i=0; i<this.menu.items.length; i++) this.menu.items[i].Hide();
    clearTimeout(this.timer);
    this.timer = null;
    this.div.style.display = "none";
    if (this.passiveClass) this.caption.className = this.passiveClass;
  }
  
  function ActiveAll() {
    var i = this.itemObj, m = this.itemObj.parentMenu;
    do {
      m.mouseOn = i.id;
      m.Start();
    } while((i=m.parentItem) && (m=i.parentMenu))
  }
  
  this.caption.ActiveAll = ActiveAll;
  
  this.div.onmouseover = ActiveAll;
  
  this.caption.onmouseover = function() {
    with(this.itemObj) {
      if (id != parentMenu.active) {
        parentMenu.HideActive();
        Show();
      }
    }
    this.ActiveAll();
  }
  
  function ObjOut() {
    with(this.itemObj.parentMenu) {
      mouseOn = null;
      Start();
    }
  }
  
  this.caption.onmouseout = ObjOut;
  this.div.onmouseout = ObjOut;
  
  this.Add = function(opt) {
    if (!this.menu) {
      var s = this.parentMenu.name + ".items[" + this.id + "].menu";
      this.menu = new MenuObj(s, this.parentMenu.dt);
      this.menu.parentItem = this;
    }
    return this.menu.Add(opt);
  }
}

function MenuObj(name, dt) {
  this.name = name;
  this.timer = null;
  this.dt = dt;
  this.items = new Array();
  this.mouseOn = null;
  this.active = null;
  this.parentItem = null;
  
  this.defPos = "bottom";
  this.defAlign = "left";
  this.defEffect = -1;
  this.gefDuration = 1;
  this.gefRollN = 1;
  this.defActiveClass = null;
  this.defPassiveClass = null;
  
  this.Add = function(opt) {
    if (!bid(opt[0]) || !bid(opt[1])) return false;
    this.items[this.items.length] = new ItemObj(this.items.length, this, opt);
    return this.items.length-1;
  }
  this.Check = function() {
    if (this.mouseOn == null) {
      this.HideActive();
      this.active = null;
      clearInterval(this.timer);
      this.timer = null;
    }
  }
  this.Start = function() {
    if (this.timer) {
      clearInterval(this.timer);
      this.timer = null;
    }
    this.timer = setInterval(this.name+".Check();", this.dt);
  }
  this.HideAll = function() { for (var i in this.items) this.items[i].Hide(); }
  this.HideActive = function() { if (this.active!=null) this.items[this.active].Hide(); }
}

