//  TabbedBox - A widget to display tabbed panels
//  
//  Version 1.0 

TabbedBox = Class.create();

TabbedBox.prototype = {
  initialize: function(element, options) {
    var options = Object.extend({
      // width       : 466,
      // height      : 319,
      transition: Effect.Transitions.sinoidal,
      duration:   0.75,
      fps:        25.0,
      debug       : false
    }, arguments[1] || {});
    this.options = options;

    this.element = $(element);
    if(! this.element) {
      if (this.options.debug) alert('TabbedBox: Element not found: "' + element + '"');
      return;
    }
    Element.cleanWhitespace(this.element);

    this.setStyles();

    // activate the first tab now
    this.showTab(this.element.childNodes[0]);
  },

  setStyles: function() {
    if (this.options.debug) alert('Setting styles.');
    var box = this.element;

    // set box style
    var boxWidth = this.options.width;
    var boxHeight = this.options.height;
    box.setStyle({ 
      boxWidth: boxWidth + 'px',
      height  : (boxHeight + 24) + 'px',
      border  : 'none'
    });

    // set tab style
    var boxTop = box.style.top;
    var boxLeft = box.style.left;
    $A(box.childrenWithClassName('tab')).each(
      function(tab) {
        var thisTab = $(tab);
        thisTab.makePositioned();
        thisTab.makeClipping();
        thisTab.setStyle({
          position    : 'absolute',
          top         : boxTop + 'px',
          left        : boxLeft + 'px',
          width       : boxWidth + 'px'
        });
      }
    );
    // set panel style
    $A(box.childrenWithClassName('tab-panel')).each( 
      function(panel) { 
        var thisPanel = $(panel);
        // small (2px) browser hack:
        var adjustWidth = /MSIE/.test(navigator.userAgent) ? 0 : -2;
        thisPanel.setStyle({
          width       : (boxWidth + adjustWidth) + 'px', 
          height      : boxHeight + 'px',
          border      : 'solid 1px black',
          borderTop   : 0, 
          margin      : 0,
          marginTop   : 0,

          overflowX   : 'hidden',
          overflowY   : 'auto',

          scrollbarBaseColor:     '#505050',
          scrollbarArrowColor:    '#fff',
          scrollbarTrackColor:    '#afafaf',
          scrollbar3dlightColor:  '#505050',
          scrollbarShadowColor:   '#808080'

        }); 
        Element.setOpacity(thisPanel, 0);
      }
    );
  },

  showTab: function(tabElement) {
    var newTab = $(tabElement);
    if (!newTab) {
      if (this.options.debug) {
        if (!tabElement) alert('Tab not specified.');
        else alert('Tab not found: ' + tabElement);
      }
      return;
    }

    if (this.options.debug) alert('Activating tab: ' + newTab.id);
    if (!newTab) return;
    // hide currently visible tab(s!)
    if (this.options.debug) alert('TabbedBox has ' 
      + tabbedBox.childNodes.length + ' children');
    for (var i=0; i < this.element.childNodes.length; i++) {
      var thisTab = this.element.childNodes[i];
      if (this.options.debug) alert('checking tab: ' + thisTab);
      if (Element.visible(thisTab)) {
        if (this.options.debug) alert('hiding tab: ' + thisTab);
        Element.hide(thisTab);
      }
      else {
        if (this.options.debug) alert('already hidden tab: ' + thisTab);
      }
    }
    if (this.options.debug) alert('Showing new tab ' + newTab.id);
    Element.cleanWhitespace(newTab);
    Element.setOpacity(newTab.childNodes[1], 1);
    Element.show(newTab);
  },

  selectTab: function (tabElement) {
    if (this.isFading) {
      return;
    }
    var newTab = $(tabElement);
    if (!newTab) {
      if (this.options.debug) {
        if (!tabElement) alert('Tab not specified.');
        else alert('Tab not found: ' + tabElement);
      }
      return;
    }
    if (this.options.debug) alert('Selecting tab: ' + newTab.id);
    // locate currently visible tab
    var oldTab;
    if (this.options.debug) alert('TabbedBox has ' 
      + this.element.childNodes.length + ' children');
    for (var i=0; i < this.element.childNodes.length; i++) {
      var thisTab = this.element.childNodes[i];
      if (Element.visible(thisTab)) {
        if (this.options.debug) alert('from old tab: ' + thisTab);
        oldTab=thisTab;
        break;
      }
    }
    if (newTab == oldTab) return;

    Element.cleanWhitespace(oldTab);
    Element.cleanWhitespace(newTab);

    var oldPanel = oldTab.childNodes[1];
    var newPanel = newTab.childNodes[1];

    // begin panel cross-fade
    new Effect.Parallel( 
      [
        new Effect.Fade(oldPanel, this.syncOpts()),
        new Effect.Appear(newPanel, this.syncOpts())
      ],
      {
        transition : this.options.transition,
        duration   : this.options.duration,
        fps        : this.options.fps,
        beforeStart: function() {
          this.isFading=1;
          Element.setOpacity(newPanel, 0);
          Element.show(newTab);
        }.bind(this),
        afterFinish: function() {
          Element.setOpacity(oldPanel, 0);
          Element.hide(oldTab);
          this.isFading=0;
        }.bind(this)
      }
    );
  },

  syncOpts: function() { 
    return {
      sync       : true,
      transition : this.options.transition,
      duration   : this.options.duration,
      fps        : this.options.fps
    };
  }

};
  
