/**
 * Extend an UL element to be used as tabset menu
 * Tabset menu are usually constructed with ul/li elements
 * but they are not necessary. You can buil a tabset with
 * divs for example in wich the root node is the tabset control
 * and any child is a tab.
 *
 * Use li.selected in css to define styles of selected tabs
 * Use li.over in css to define styles of active tabs
 *
 * @param {String | Element} tabset: UL element in document
 * @param {Integer} selected: index of the initial selected tab
 */
var TTabSet = function (tabset, selected) {
  this.count    = 0;
  this.tabset   = TDOM.getElement(tabset);
  this.selected = typeof selected == "number" || selected >= 0 ? selected : -1;

  // Initialize Tabset
  if (this.tabset) {
    var tab = TDOM.firstChild(this.tabset);
    while (tab) {
      var id = this.count++;
      tab[TTabSet.ownAttr] = id;
      this.selected == id ? TDOM.addClass(tab, 'selected') : TDOM.removeClass(tab, 'selected');
      TEvents.listen(tab, 'click', this.doClick, this);
      TEvents.listen(tab, 'mouseout', this.doOut, this);
      TEvents.listen(tab, 'mouseover', this.doOver, this);
      tab = TDOM.nextElement(tab);
    }
    this.selected = this.selected > this.count-1 ? -1 : this.selected;
  }
}
TTabSet.inherits(TEventDispatcher);
TTabSet.ownAttr = "tabset_tab_unique_id";

/**
 * Handle mouse out event on tabs
 * @param {TDOMEvent} e: DOM Event object
 */
TTabSet.prototype.doOut = function (e) {
  TDOM.removeClass(e.currentTarget, 'over');
}

/**
 * Handle mouse over event on tabs
 * Use li.over in css to define styles of active tabs
 *
 * @param {TDOMEvent} e: DOM Event object
 */
TTabSet.prototype.doOver = function (e) {
  TDOM.addClass(e.currentTarget, 'over');
}

/**
 * Handle click event on tabs
 * @param {TDOMEvent} e: DOM Event object
 */
TTabSet.prototype.doClick = function (e) {
  this.dispatch("click", e.currentTarget);
  this.select(e.currentTarget);
}

/**
 * Get a tab by his id
 * @param {Integer} id: tab id
 * @return {Element} tab
 */
TTabSet.prototype.getTabById = function (id) {
  var tab = TDOM.firstChild(this.tabset);
  while (tab) {
    if (tab[TTabSet.ownAttr] == id) {
      return tab;
    }
    tab = TDOM.nextElement(tab);
  }
  return null;
}

/**
 * Set selected tab index.
 * Change styles of current selected tab and tab to be
 * selected, and fire change event.
 * Use li.selected in css to define styles of selected tabs
 *
 * @param {Integer | Element} tab: tab index or tab itself
 */
TTabSet.prototype.select = function (tab) {
  if (typeof tab == 'number') {
    var id = tab;
    tab = this.getTabById(tab);
  } else {
    var id = tab[TTabSet.ownAttr];
  }
  if (id == this.selected) { return; }
  id = id > this.count-1 || id < 0 ? -1 : id;
  var old = this.getTabById(this.selected);
  var canchange = this.dispatch("canchange", old, tab, id) !== false;
  if (canchange) {
    if (old) {
      TDOM.removeClass(old, 'selected');
    }
    if (tab) {
      TDOM.addClass(tab, 'selected');
    }
    this.selected = id;
    this.dispatch("change", tab, id);
  }
}
