/**
 * Carib tabs
 * 
 * @copyright 2009 Magic Wand
 * @version $Id$
 */

ns('Carib.Tabs');


/**
 * Tab
 */
Carib.Tabs.Tab = function(config) {
  this.hide_timer = null;
  this.show_timer = null;
  
  $.extend(this, config);
  
  if(this.auto_init)
    this.init();
}

Carib.Tabs.Tab.prototype = {
  // configurable {
  /**
   * Tab selector
   */
  tab: '', //required
  /**
   * Body selector
   */
  body: '', // required
  offset: 0,
  auto_init: true,
  hide_delay: 750,
  show_delay: 250,
  fixed: false,
  zindex: 1000,
  // }
  
  init: function() {
    if(!this.fixed) {
      this._initEvents();
      this.deactivateTab();
    } else
      this.activateTab();
  },
  
  _initEvents: function() {
    this.getTabEl().bind('mouseover.tab', this.onTabMouseOver.createDelegate(this))
                   .bind('mouseout.tab', this.onTabMouseOut.createDelegate(this));
    this.getBodyEl().bind('mouseover.tab', this.onBodyMouseOver.createDelegate(this))
                    .bind('mouseout.tab', this.onBodyMouseOut.createDelegate(this));
  },
  
  _purgeEvents: function() {
    this.getTabEl().unbind('.tab');
    this.getBodyEl().unbind('.tab');
  },
  
  fix: function() {
    this._purgeEvents();
    this.fixed = true;
    this.getBodyEl().css('position', 'static');
    this.showBody();
    this.activateTab();
  },
  
  unfix: function() {
    this._initEvents();
    this.fixed = false;
    this.getBodyEl().css('position', 'absolute');
    this.hideBody();
    this.deactivateTab();
  },
  
  activateTab: function() {
    this.getTabEl().addClass('acttab');
  },
  
  deactivateTab: function() {
    this.getTabEl().removeClass('acttab');
  },
  
  startHideTimer: function() {
    this.stopHideTimer();
    this.stopShowTimer();
    
    var _this = this;
    this.hide_timer = setTimeout(function() {
      _this.hideBody();
    }, this.hide_delay);
  },
  
  stopHideTimer: function() {
    if(this.hide_timer === null) 
      return;
      
    clearTimeout(this.hide_timer);
    this.hide_timer = null;
  },
  
  startShowTimer: function() {
    this.stopShowTimer();
    this.stopHideTimer();
    
    var _this = this;
    this.show_timer = setTimeout(function() {
      _this.showBody();
    }, this.show_delay);
  },
  
  stopShowTimer: function() {
    if(!this.show_timer === null)
      return;
      
    clearTimeout(this.show_timer);
    this.show_timer = null;
  },
  
  showBody: function() {
    this.stopHideTimer();
    this.stopShowTimer();
    //this.getBodyEl().show().css('left', this.offset);
    this.getBodyEl().css('left', this.offset).css('z-index', !this.fixed ? this.zindex : 1).fadeIn('fast');
    this.getTabEl().trigger('showtab', [this]);
  },
  
  hideBody: function() {
    //this.getBodyEl().hide();
    this.stopHideTimer();
    this.stopShowTimer();
    this.getBodyEl().fadeOut('fast');
  },
  
  onBodyMouseOver: function(event) {
    this.stopHideTimer();
    this.activateTab();
  },
  
  onBodyMouseOut: function(event) {
    this.startHideTimer();
    this.deactivateTab();
  },
  
  onTabMouseOver: function(event) {
    //this.showBody();
    this.startShowTimer();
  },
  
  onTabMouseOut: function(event) {
    this.startHideTimer();
  },
  
  getTabEl: function() {
    return $(this.tab);
  },
  
  getBodyEl: function() {
    return $(this.body);
  }
}


/**
 * Tabs controller
 */
Carib.Tabs.Controller = function(config) {
  $.extend(this, config || {});
  
  if(this.auto_init)
    this.init();
}

Carib.Tabs.Controller.prototype = {
  // configurable {
  /**
   * Array of tabs
   */
  tabs: [],
  fixed: false,
  auto_init: true,
  /**
   * Fixator selector
   */
  fixator: false,
  /**
   * Cookie name to save fixation state
   */
  cookie: false,
  fix_image: '/i/arrow_l2.gif',
  unfix_image: '/i/arrow_l.gif',
  // }
  
  init: function() {
    if(this.fixator)
      this._initFixator();
      
    this._initTabs();
    
    if(this.fixed)
      this.fix();
    else
      this.unfix();
  },
  
  _initTabs: function() {
    for(var i = 0, l = this.tabs.length; i < l; i ++)
      this._initTab(this.tabs[i]); 
  },
  
  _initTab: function(tab) {
    tab.getTabEl().generateId().bind('showtab', this.onShowTab.createDelegate(this));
  },
  
  _initFixator: function() {
    this.getFixatorEl().click(this.onFixatorClick.createDelegate(this));
  },
  
  hideOtherTabs: function(tab) {
    var id = tab.getTabEl().attr('id');
    for(var i = 0, l = this.tabs.length; i < l; i ++) {
      var other = this.tabs[i];
      if(other.getTabEl().attr('id') != id)
        other.hideBody();
    }
  },
  
  saveState: function() {
    if(!this.cookie)
      return;
      
    document.cookie = this.cookie + '=' + (this.fixed ? 1 : 0) + ';path=/';
  },
  
  fix: function() {
    if(this.fix_image)
      $('img', this.getFixatorEl()).attr('src', this.fix_image);

    if(this.fixed)
      return;

    this.fixed = true;
    this.saveState();
    
    for(var i = 0, l = this.tabs.length; i < l; i ++)
      this.tabs[i].fix();
  },
  
  unfix: function() {
    if(this.unfix_image)
      $('img', this.getFixatorEl()).attr('src', this.unfix_image);
      
    if(!this.fixed)
      return;
      
    for(var i = 0, l = this.tabs.length; i < l; i ++)
      this.tabs[i].unfix();
      
    this.fixed = false;
    this.saveState();
  },
  
  toggleFixation: function() {
    if(this.fixed)
      this.unfix();
    else
      this.fix();
  },
  
  onShowTab: function(e, tab) {
    if(!this.fixed)
      this.hideOtherTabs(tab);
  },
  
  onFixatorClick: function() {
    this.toggleFixation();
    return false;
  },
  
  getFixatorEl: function() {
    return $(this.fixator);
  }
}
