YAHOO.namespace('mzag.stack');

YAHOO.mzag.stack.Stack=function(id)
{
  // set member variables
  this.stackContainer=$(id);
  this.stackContainerId=id;
  
  this.stackItems=YAHOO.util.Dom.getElementsByClassName('mzag_gui_stack', 'div', this.stackContainer);
  this.stackItemBodyHeight=0;
  this.active=Cookie.get(this.stackContainer.id+'_active');
  for(var i=0; i<this.stackItems.length; i++)
  {
    this.stackItems[i].parent=this;
    this.stackItems[i].header=YAHOO.util.Dom.getElementsByClassName('mzag_gui_stackbar', 'div', this.stackItems[i])[0];
    this.stackItems[i].body=YAHOO.util.Dom.getElementsByClassName('mzag_gui_stackcontent', 'div', this.stackItems[i])[0];
    this.stackItems[i].id=i;
  }
 
  this.resize=function()
  {
    // determine active element
    for(var i=0; i<this.stackItems.length; i++)
    {
      if(this.stackItems[i].id==this.active)
        this.activeItem=this.stackItems[i];
    }
    if(!this.activeItem)
      this.activeItem=this.stackItems[0];
    // adjust height of all elements (set to 1 if there is not enough space)
    this.stackItemBodyHeight=$(this.stackContainerId).offsetHeight-this.activeItem.header.offsetHeight*this.stackItems.length-this.stackItems.length;
    if(isNaN(this.stackItemBodyHeight) || this.stackItemBodyHeight<1)
      this.stackItemBodyHeight=1;
    for(var i=0; i<this.stackItems.length; i++)
    {
      if(this.activeItem!=this.stackItems[i])
      {
        YAHOO.util.Dom.setStyle(this.stackItems[i].body, 'height', '1px');
        for(var j=0; j<this.stackItems[i].body.childNodes.length; j++)
        {
          var current=this.stackItems[i].body.childNodes[j];
          if(typeof current.style!='undefined')
            current.style.display='none';
        }
      }
      else
        YAHOO.util.Dom.setStyle(this.activeItem.body, 'height', this.stackItemBodyHeight+'px');
    }
    // show stack
    YAHOO.util.Dom.setStyle(this.stackContainer, 'visibility', 'visible');
  }

  // set initial size
  this.resize();

  // register click callbacks for the header bars of all elements
  for(var i=0; i<this.stackItems.length; i++)
  {
    YAHOO.util.Event.addListener(this.stackItems[i].header, 'click', function()
    {
      if(this.parent.activeItem==this || YAHOO.mzag.stack.animationRunning)
        return;
      for(var j=0; j<this.body.childNodes.length; j++)
      {
        var current=this.body.childNodes[j];
        if(typeof current.style!='undefined')
          current.style.display='block';
      }        
      // hide scrollbar of the expanding and imploding div
      subElement1=YAHOO.util.Dom.getElementsByClassName('mzag_gui_stackcontentshow', 'div', this.body)[0];
      YAHOO.util.Dom.setStyle(subElement1, 'overflow', 'hidden');
      subElement2=YAHOO.util.Dom.getElementsByClassName('mzag_gui_stackcontentshow', 'div', this.parent.activeItem.body)[0];
      YAHOO.util.Dom.setStyle(subElement2, 'overflow', 'hidden');
      // create animation
      anim=new YAHOO.mzag.stack.Animation(this.body, this.parent.activeItem.body, 1, this.parent.stackItemBodyHeight, 250,
        function()
        {
          YAHOO.util.Dom.setStyle(subElement1, 'overflow', 'auto');
          YAHOO.util.Dom.setStyle(subElement1, 'overflow', 'auto');
        }
      );
      //set new active element
      this.parent.activeItem=this;
      this.parent.active=this.id;
      Cookie.set(this.parent.stackContainer.id+'_active', this.id, 1);
      // run animation
      anim.run();
    }, this.stackItems[i], true);
  }

  // register window resize callback
  YAHOO.util.Event.addListener(window, 'resize', this.resize, this, true);
};

YAHOO.mzag.stack.animationRunning=false;
YAHOO.mzag.stack.Animation=function(element1_, element2_, start_, end_, duration_, onFinishCallback_)
{
  
  this.instanceId=YAHOO.mzag.stack.Animation.instances.length;
  YAHOO.mzag.stack.Animation.instances.push(this);
  this.element1=$(element1_);
  this.element2=$(element2_);
  this.start=start_;
  this.end=end_;
  this.duration=duration_;
  this.remaining=duration_;
  this.callback=onFinishCallback_;
  this.step=30;
  this.started=false;

  this.run=function()
  {
    YAHOO.mzag.stack.animationRunning=true;
    // cleanup and trigger callback
    if(this.remaining<=0)
    {
      this.element1.style.height=this.end+'px';
      this.element2.style.height=this.start+'px';
      if(this.callback)
        this.callback(this);
      YAHOO.mzag.stack.animationRunning=false;
      return;
    }
    // stop animation if started
    if(this.timer)
      clearTimeout(this.timer);
    // resize
    difference=this.remaining>0?Math.min(parseInt(this.element2.offsetHeight)-this.start, Math.round((this.end-this.start)/(this.duration/this.step))):0;
    this.resizeBy(difference, null, null);
    this.remaining-=this.step;
    // start timer
    this.timer=setTimeout("YAHOO.mzag.stack.Animation.instances["+this.instanceId+"].run()", this.step);
  }

  this.resizeBy=function(difference_)
  {
    var height1=this.element1.offsetHeight;
    var height2=this.element2.offsetHeight;
    difference_=parseInt(difference_);
    if(difference_>0)
    {
      this.element1.style.height=(height1+difference_)+'px';
      this.element2.style.height=(height2-difference_)+'px';
    }
  }
};
YAHOO.mzag.stack.Animation.instances=new Array();
