/**
 * SimpleTabs - Unobtrusive Tabs with Ajax
 *
 * @example
 *
 * var tabs = new SimpleTabs($('tab-element'), {
 *       selector: 'h2.tab-tab'
 * });
 *
 * @version    1.0
 *
 * @license    MIT License
 * @author     Harald Kirschner <mail [at] digitarald.de>
 * @copyright  2007 Author
 */
var SimpleTabs = new Class({

   Implements: [Events, Options],

   /**
    * Options
    */
   options: {
      show: 0,
      selector: '.tab-tab',
      classWrapper: 'tab-wrapper',
      classMenu: 'tab-menu',
      classContainer: 'tab-container',
      onSelect: function(toggle, container, index) {
         toggle.addClass('tab-selected');
         container.setStyle('display', '');
      },
      onDeselect: function(toggle, container, index) {
         toggle.removeClass('tab-selected');
         container.setStyle('display', 'none');
      },
      onRequest: function(toggle, container, index) {
         container.addClass('tab-ajax-loading');
      },
      onComplete: function(toggle, container, index) {
         container.removeClass('tab-ajax-loading');
      },
      onFailure: function(toggle, container, index) {
         container.removeClass('tab-ajax-loading');
      },
      onAdded: Class.empty,
      getContent: null,
      ajaxOptions: {},
      cache: true
   },

   /**
    * Constructor
    *
    * @param {Element} The parent Element that holds the tab elements
    * @param {Object} Options
    */
   initialize: function(element, options) {
      this.element = $(element);
      this.setOptions(options);
      this.selected = null;
      this.build();
   },

   build: function() {
      this.tabs = [];
      this.menu = new Element('ul', {'class': this.options.classMenu});
      this.wrapper = new Element('div', {'class': this.options.classWrapper});

      if(this.element!=null)
      {
      this.element.getElements(this.options.selector).each(function(el) {
         var content = el.get('href') || (this.options.getContent ? this.options.getContent.call(this, el) : el.getNext());
         this.addTab(el.innerHTML, el.title || el.innerHTML, content);
      }, this);
      this.element.empty().adopt(this.menu, this.wrapper);

      if (this.tabs.length) this.select(this.options.show);
      }
   },

   /**
    * Add a new tab at the end of the tab menu
    *
    * @param {String} inner Text
    * @param {String} Title
    * @param {Element|String} Content Element or URL for Ajax
    */
   addTab: function(text, title, content) {
      var grab = $(content);
      var container = (grab || new Element('div'))
         .setStyle('display', 'none')
         .addClass(this.options.classContainer)
         .inject(this.wrapper);
      var pos = this.tabs.length;
      var evt = (this.options.hover) ? 'mouseenter' : 'click';
      var tab = {
         container: container,
         toggle: new Element('li').grab(new Element('a', {
            href: '#',
            title: title
         }).grab(
            new Element('span', {html: text})
         )).addEvent(evt, this.onClick.bindWithEvent(this, [pos])).inject(this.menu)
      };
      if (!grab && $type(content) == 'string') tab.url = content;
      this.tabs.push(tab);
      return this.fireEvent('onAdded', [tab.toggle, tab.container, pos]);
   },

   onClick: function(evt, index) {
      this.select(index);
      return false;
   },

   /**
    * Select the tab via tab-index
    *
    * @param {Number} Tab-index
    */
   select: function(index) {
      if (this.selected === index || !this.tabs[index]) return this;
      if (this.ajax) this.ajax.cancel().removeEvents();
      var tab = this.tabs[index];
      var params = [tab.toggle, tab.container, index];
      if (this.selected !== null) {
         var current = this.tabs[this.selected];
         if (this.ajax && this.ajax.running) this.ajax.cancel();
         params.extend([current.toggle, current.container, this.selected]);
         this.fireEvent('onDeselect', [current.toggle, current.container, this.selected]);
      }
      this.fireEvent('onSelect', params);
      if (tab.url && (!tab.loaded || !this.options.cache)) {
         this.ajax = this.ajax || new Request.HTML();
         this.ajax.setOptions({
            url: tab.url,
            method: 'get',
            update: tab.container,
            onFailure: this.fireEvent.pass(['onFailure', params], this),
            onComplete: function(resp) {
               tab.loaded = true;
               this.fireEvent('onComplete', params);
            }.bind(this)
         }).setOptions(this.options.ajaxOptions);
         this.ajax.send();
         this.fireEvent('onRequest', params);
      }
      this.selected = index;
      return this;
   }

});

