/* This file has been modified by Henrik Bechmann (bechmann.ca; henrik@bechmann.ca) January 1, 2011
Modified Features:
  This file adds "toggle" and "toggle-each" capability for accordions.
  Also slide speed can be specified with configuration slideUpSpeed and slideDownSpeed options.

See end of file for most modifications.
For embedded modifications, search for "// modification by HB" (there are 5 embedded modifications)

Note: there is a design issue here, namely that the following should be separated:
  orientation: "vertical", "horizontal"
  effect: as listed, not including "horizontal"
  mode: "openpane" (default, standard), "toggle","toggle-each"

  This fix does not address this design issue, therefore this fix is a temporary hack to 
  enable basic modes (openpane, toggle, toggle-each).

  Installation: link this file in webpage header directly after the jquery tools link.
  Usage: 
    - for toggle and toggle-each, set the configuration effect to "toggle" or "toggle-each".
    - to alter slide speed set the configurations of slideUpSpeed and slideDownSpeed
*/

/**
 * @license 
 * jQuery Tools 1.2.5 Tabs- The basics of UI design.
 * 
 * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
 * 
 * http://flowplayer.org/tools/tabs/
 *
 * Since: November 2008
 * Date:    Wed Sep 22 06:02:10 2010 +0000 
 */  
(function($) {

  // static constructs
  $.tools = $.tools || {version: '1.2.5'};

  $.tools.tabs = {

    conf: {
      tabs: 'a',
      current: 'current',
      onBeforeClick: null,
      onClick: null, 
      effect: 'default',
      initialIndex: 0,      
      event: 'click',
      rotate: false,

      // 1.2
      history: false
    },

    addEffect: function(name, fn) {
      effects[name] = fn;
    }

  };

  var effects = {

    // simple "toggle" effect
    'default': function(i, done) { 
      this.getPanes().hide().eq(i).show();
      done.call();
    }, 

    /*
      configuration:
        - fadeOutSpeed (positive value does "crossfading")
        - fadeInSpeed
    */
    fade: function(i, done) {    

      var conf = this.getConf(),            
         speed = conf.fadeOutSpeed,
         panes = this.getPanes();

      if (speed) {
        panes.fadeOut(speed);  
      } else {
        panes.hide();  
      }

      panes.eq(i).fadeIn(conf.fadeInSpeed, done);  
    },

    // for basic accordions
    slide: function(i, done) {
      this.getPanes().slideUp(200);
      this.getPanes().eq(i).slideDown(400, done);       
    }, 

    /**
     * AJAX effect
     */
    ajax: function(i, done)  {      
      this.getPanes().eq(0).load(this.getTabs().eq(i).attr("href"), done);  
    }    
  };     

  var w;

  /**
   * Horizontal accordion
   * 
   * @deprecated will be replaced with a more robust implementation
   */
  $.tools.tabs.addEffect("horizontal", function(i, done) {

    // store original width of a pane into memory
    if (!w) { w = this.getPanes().eq(0).width(); }

    // set current pane's width to zero
    this.getCurrentPane().animate({width: 0}, function() { $(this).hide(); });

    // grow opened pane to it's original width
    this.getPanes().eq(i).animate({width: w}, function() { 
      $(this).show();
      done.call();
    });

  });  


  function Tabs(root, paneSelector, conf) {

    var self = this, 
       istoggle = (conf.effect == 'toggle' || conf.effect == 'toggle-each'), // modification by HB
       trigger = root.add(this),
       tabs = root.find(conf.tabs),
       panes = paneSelector.jquery ? paneSelector : root.children(paneSelector),       
       current;


    // make sure tabs and panes are found
    if (!tabs.length)  { tabs = root.children(); }
    if (!panes.length) { panes = root.parent().find(paneSelector); }
    if (!panes.length) { panes = $(paneSelector); }


    // public methods
    $.extend(this, {        
      click: function(i, e) {

        var tab = tabs.eq(i);                         

        if (typeof i == 'string' && i.replace("#", "")) {
          tab = tabs.filter("[href*=" + i.replace("#", "") + "]");
          i = Math.max(tabs.index(tab), 0);
        }

        if (conf.rotate) {
          var last = tabs.length -1; 
          if (i < 0) { return self.click(last, e); }
          if (i > last) { return self.click(0, e); }            
        }

        if (!tab.length) {
          if (current >= 0) { return self; }
          i = conf.initialIndex;
          tab = tabs.eq(i);
        }        

        // current tab is being clicked

        if (!istoggle)  { // modification by HB
          if (i === current) { return self; }
        } // modification by HB
        // possibility to cancel click action        
        e = e || $.Event();
        e.type = "onBeforeClick";
        trigger.trigger(e, [i]);        
        if (e.isDefaultPrevented()) { return; }

        // call the effect
        effects[conf.effect].call(self, i, function() {

          // onClick callback
          e.type = "onClick";
          trigger.trigger(e, [i]);          
        });      

        // default behaviour
        current = i;
        if (!istoggle) { // modification by HB
          tabs.removeClass(conf.current);  
          tab.addClass(conf.current);
        } // modification by HB

        return self;
      },

      getConf: function() {
        return conf;  
      },

      getTabs: function() {
        return tabs;  
      },

      getPanes: function() {
        return panes;  
      },

      getCurrentPane: function() {
        return panes.eq(current);  
      },

      getCurrentTab: function() {
        return tabs.eq(current);  
      },

      getIndex: function() {
        return current;  
      }, 

      next: function() {
        return self.click(current + 1);
      },

      prev: function() {
        return self.click(current - 1);  
      },

      destroy: function() {
        tabs.unbind(conf.event).removeClass(conf.current);
        panes.find("a[href^=#]").unbind("click.T"); 
        return self;
      }

    });

    // callbacks  
    $.each("onBeforeClick,onClick".split(","), function(i, name) {

      // configuration
      if ($.isFunction(conf[name])) {
        $(self).bind(name, conf[name]); 
      }

      // API
      self[name] = function(fn) {
        if (fn) { $(self).bind(name, fn); }
        return self;  
      };
    });


    if (conf.history && $.fn.history) {
      $.tools.history.init(tabs);
      conf.event = 'history';
    }  

    // setup click actions for each tab
    tabs.each(function(i) {         
      $(this).bind(conf.event, function(e) {
        self.click(i, e);
        return e.preventDefault();
      });      
    });

    // cross tab anchor link
    panes.find("a[href^=#]").bind("click.T", function(e) {
      self.click($(this).attr("href"), e);    
    }); 

    // open initial tab
    if (location.hash && conf.tabs == "a" && root.find("[href=" +location.hash+ "]").length) {
      self.click(location.hash);

    } else {
      if (conf.initialIndex === 0 || conf.initialIndex > 0) {
        self.click(conf.initialIndex);
      }
    }        

  }


  // jQuery plugin implementation
  $.fn.tabs = function(paneSelector, conf) {

    // return existing instance
    var el = this.data("tabs");
    if (el) { 
      el.destroy();  
      this.removeData("tabs");
    }

    if ($.isFunction(conf)) {
      conf = {onBeforeClick: conf};
    }

    // setup conf
    conf = $.extend({}, $.tools.tabs.conf, conf);    


    this.each(function() {        
      el = new Tabs($(this), paneSelector, conf);
      $(this).data("tabs", el); 
    });    

    return conf.api ? el: this;    
  };    

}) (jQuery); 

/* ===========================[ Extensions by Henrik Bechmann (bechmann.ca) ]===================================*/
// extend jquery tools tabs
$.extend($.tools.tabs.conf,{slideUpSpeed:400,slideDownSpeed:400});
$.tools.tabs.addEffect('slide',function(i, done) {
  var conf = this.getConf();
  this.getPanes().slideUp(conf.slideUpSpeed);
  this.getPanes().eq(i).slideDown(conf.slideDownSpeed, done);       
});
$.tools.tabs.addEffect('toggle',function(i, done) {
  var conf = this.getConf();
  var $tabs = this.getTabs();
  var $tab = $tabs.eq(i);
  if ($tab.hasClass(conf.current))
  {
    this.getPanes().eq(i).slideUp(conf.slideUpSpeed, done);
    $tabs.removeClass(conf.current);  
  }
  else
  {
    this.getPanes().slideUp(conf.slideUpSpeed);
    this.getPanes().eq(i).slideDown(conf.slideDownSpeed, done);
    $tabs.removeClass(conf.current);  
    $tab.addClass(conf.current);
  }
});

$.tools.tabs.addEffect('toggle-each',function(i, done) {
  var conf = this.getConf();
  var $tabs = this.getTabs();
  var $tab = $tabs.eq(i);
  if ($tab.hasClass(conf.current))
  {
    this.getPanes().eq(i).slideUp(conf.slideUpSpeed, done);
    $tab.removeClass(conf.current);  
  }
  else
  {
    this.getPanes().eq(i).slideDown(conf.slideDownSpeed, done);
    $tab.addClass(conf.current);
  }
});