﻿var fTabsIdSeed = 0;
//{
//  "DIV" : DIV,
//  "unswitchable" : false,
//  "parse": true|false
//  "tabs" : [
//    {
//      "title" : "text",
//      "name" : "name of tab",
//      "content" : "text or hml",
//      "isHtml" : "true",
//      "isActive" : "false",
//      "visible" : true,
//      "cls" : class name,
//      "contId" : "id of content"
//    }
//  ]
//}
published.Tabs = function (init) {
  if (typeof (init) === tUNDEFINED || init === null || typeof (init.DIV) === tUNDEFINED || init.DIV === null) throw "Tabs.ctor(init.DIV)";

  var tabs = this;
  WAVE.extend(tabs, WAVE.EventManager);
  fTabsIdSeed++;
  var fSeed = "wvTabs_" + fTabsIdSeed;
  var fAttributePrefix = "data-tabs-";

  var fDIV = init.DIV;
  var fDIVDisplay = WAVE.styleOf(fDIV, "display");
  var fUnswitchable = WAVE.strAsBool(init.unswitchable, false);
  var fParse = WAVE.strAsBool(init.parse, false);
  var fTabs = WAVE.isArray(init.tabs) ? init.tabs : [];
  var fTSeed = 0;

  var Tab = function(tabInit) {
    fTSeed++;
    tabInit = !WAVE.isObject(tabInit) ? {} : tabInit;

    var tab = this;
    var fTitle = WAVE.strDefault(tabInit.title, fTSeed.toString());
    var fContent = WAVE.strDefault(tabInit.content);
    var fIsHtml = WAVE.strAsBool(tabInit.isHtml, true);
    var fIsActive = WAVE.strAsBool(tabInit.isActive, false);
    var fId = WAVE.strDefault(tabInit.id, fSeed + "_" + fTSeed);
    var fName = WAVE.strDefault(tabInit.name, fTSeed.toString());
    var fVisible = WAVE.strAsBool(tabInit.visible, true);
    var fClass = WAVE.strDefault(tabInit.cls);
    var fCont = WAVE.get(tabInit, "cont", null);
    var fLi = WAVE.get(tabInit, "li", null);
    var baseDisplay;

    function renderContent() {
      if(fIsHtml)
        fCont.innerHTML = fContent;
      else
        fCont.innerText = fContent;
    }

    this.build = function(firstTime, visibilityChanged) {
      if (firstTime) {
        if (fLi === null) {
          var ulTabs = WAVE.id(fControlsIds.ulTabsId);
          ulTabs.insertAdjacentHTML("beforeend", "<li id='" + fId + "'></li>");
          fLi = WAVE.id(fId);
        }
        fLi.innerText = fTitle;
        fLi.onclick = function(){
          tabs.tabActive(fName);
        };
        if (visibilityChanged) baseDisplay = WAVE.styleOf(fLi, "display");
      }
      if (fCont === null) {
        var divId = "content_" + fId;
        var divTabs = WAVE.id(fControlsIds.divContentContId);
        divTabs.insertAdjacentHTML("beforeend", "<div id='" + divId + "' class='" + published.CLS_TABS_CONTENT_DIV + " " + fClass + "'></div>");
        fCont = WAVE.id(divId);
        renderContent();
      }
      fLi.style.display = fVisible ? baseDisplay : "none";
      WAVE.addClass(fCont, (fVisible && fIsActive) ? published.CLS_TABS_CONTENT_DIV_SHOWN : published.CLS_TABS_CONTENT_DIV_HIDDEN);
      WAVE.removeClass(fCont, (fVisible && fIsActive) ? published.CLS_TABS_CONTENT_DIV_HIDDEN : published.CLS_TABS_CONTENT_DIV_SHOWN);
    };

    this.activate = function() {
      fIsActive = true;
      WAVE.addClass(fCont, published.CLS_TABS_CONTENT_DIV_SHOWN);
      WAVE.removeClass(fCont, published.CLS_TABS_CONTENT_DIV_HIDDEN);
      WAVE.addClass(fLi, published.CLS_TABS_ACTIVE_TAB);
    };

    this.deactivate = function() {
      fIsActive = false;
      WAVE.addClass(fCont, published.CLS_TABS_CONTENT_DIV_HIDDEN);
      WAVE.removeClass(fCont, published.CLS_TABS_CONTENT_DIV_SHOWN);
      WAVE.removeClass(fLi, published.CLS_TABS_ACTIVE_TAB);
    };

    this.destroy = function() {
      return WAVE.removeElem(fCont.id) && WAVE.removeElem(fLi.id);
    };

    this.name = function() { return fName; };
    this.tab = function() { return fLi; };
    this.cont = function() { return fCont; };
    this.isActive = function(val) {
      if (typeof (val) === tUNDEFINED || val === null) return fIsActive;

      fIsActive = val;
    };
    this.content = function(val) {
        if (typeof (val) === tUNDEFINED || val === null) return fContent;

      fContent = val;
      renderContent();
    };
    this.title = function(val) {
        if (typeof (val) === tUNDEFINED || val === null) return fTitle;

      fTitle = val;
      fLi.innerText = fTitle;
    };
    this.visible = function(val) {
      if (typeof (val) === tUNDEFINED || val === null) return fVisible;

      fVisible = val === true;
      tab.build(false, true);
      var allInvisible = true;
      for(var i = 0, l = fTabs.length; i < l; i++) {
        var t = fTabs[i];
        if (t.visible() && fTabs[i].name() !== fName) {
          if (fIsActive && !fVisible)
            tabs.tabActive(t.name());
          allInvisible = false;
        }
      }
      if (allInvisible) {
        fDIVDisplay = WAVE.styleOf(fDIV, "display");
        fDIV.style.display = "none";
      } else {
        fDIV.style.display = fDIVDisplay;
      }
    };

    this.titleCtrl = function() { return fLi; };
    this.contentCtrl = function() { return fCont; };

    return tab;
  };

  for(var i = 0; i < fTabs.length; i++){
      fTabs[i] = new Tab(fTabs[i]);
  }

  var fControlsIds = {
    divTabsContId : "tabs_cont_" + fSeed,
    divContentContId : "content_cont_" + fSeed,
    ulTabsId : "ul_tabs_ " + fSeed
  };

  function activate(name){
    var result = null;
    for(var i = 0; i < fTabs.length; i++){
      var tab = fTabs[i];
      if(tab.name() === name){
        result = name;
        tab.activate();
      } else {
        tab.deactivate();
      }
    }
    return result;
  }

  function getTabByName(name) {
    for(var i = 0; i < fTabs.length; i++) {
      if (fTabs[i].name() === name) return fTabs[i];
    }
    return null;
  }

  this.DIV = function() { return fDIV; };

  this.tabs = function() { return fTabs; };

  this.unswitchable = function(value) {
    if (typeof(value) === tUNDEFINED) return fUnswitchable;

    fUnswitchable = value === true;
    for(var i = 0; i < fTabs.length; i++){
      var tab = fTabs[i];
      if(fUnswitchable){
        if(!fTabs[i].isActive())
          tab.tab().className += " " + published.CLS_TABS_LI_DISABLED;
      }
      else
        WAVE.removeClass(tab.tab(), published.CLS_TABS_LI_DISABLED);
    }
    return value;
  };

  this.tabByName = function(name) {
    if(typeof(name) === tUNDEFINED || name === null) return null;

    return getTabByName(name);
  };

  this.tabAdd = function(tabInit){
    var evtArgsBefore = { phase: published.EVT_PHASE_BEFORE, tabControl: tabs, tabInit: tabInit, abort: false };
    tabs.eventInvoke(published.EVT_TABS_TAB_ADD, evtArgsBefore);
    if (evtArgsBefore.abort === true) return;

    var tab = new Tab(tabInit);
    var ft = getTabByName(tab.name());
    if (ft !== null) {
      ft.destroy();
      fTabs.splice(fTabs.indexOf(ft), 1);
    }
    fTabs.push(tab);
    tab.build(true, false);
    if (tab.isActive() || tabs.tabActive() === null)
      tabs.tabActive(tab.name());

    tabs.eventInvoke(published.EVT_TABS_TAB_ADD, { phase: published.EVT_PHASE_AFTER, tabControl: tabs, tab: tab });

    return tab;
  };

  this.tabDelete = function(name){
    if(typeof(name) === tUNDEFINED || name === null) return false;

    var res = false;
    for(var i = 0; i < fTabs.length; i++){
      if(fTabs[i].name() === name){
        var tab = fTabs[i];

        var evtArgsBefore = { phase: published.EVT_PHASE_BEFORE, tabControl: tabs, tab: tab, abort: false };
        tabs.eventInvoke(published.EVT_TABS_TAB_REMOVE, evtArgsBefore);
        if (evtArgsBefore.abort === true) return res;

        res = tab.destroy();
        fTabs.splice(i, 1);
        if(tab.isActive() && fTabs.length > 0){
          activate(fTabs[0].name());
        }
        break;
      }
    }

    tabs.eventInvoke(published.EVT_TABS_TAB_REMOVE, { phase: published.EVT_PHASE_AFTER, tabControl: tabs, name: name, ok: res });
    return res;
  };

  this.tabActive = function(name){
    var result = null;
    if(typeof(name) === tUNDEFINED || name === null) {
      for(var i = 0; i < fTabs.length; i++) {
        if(fTabs[i].isActive()) {
          result = fTabs[i].name();
          break;
        }
      }
    } else {
      if(!fUnswitchable)
        if(tabs.tabActive() !== name) {
          result = activate(name);
          tabs.eventInvoke(published.EVT_TABS_TAB_CHANGED, name);
        }
    }
    return result;
  };

  this.tabContent = function(name, value) {
    if (typeof(name) === tUNDEFINED || name === null || WAVE.strEmpty(name)) return null;
    var tab = getTabByName(name);
    if (tab === null) return null;

    if (typeof(value) === tUNDEFINED) {
      return tab.content();
    }
    tab.content(value);
    return value;
  };

  this.tabTitle = function(name, value) {
    if (typeof(name) === tUNDEFINED || name === null || WAVE.strEmpty(name)) return null;
    var tab = getTabByName(name);
    if (tab === null) return null;

    if (typeof(value) === tUNDEFINED) {
      return tab.title();
    }
    tab.title(value);
    return value;
  };

  this.tabVisible = function(name, val) {
    if (typeof(name) === tUNDEFINED || name === null || WAVE.strEmpty(name)) return null;
    var tab = getTabByName(name);

    if (tab === null) return null;
    if (typeof(val) === tUNDEFINED) {
      return tab.visible();
    }

    val = val === true;
    tab.visible(val);
    return val;
  };

  function build() {
    var i, l, tab;

    if (fParse) {
      fTabs = [];
        var tabs = fDIV.getElementsByTagName("li");
        for(i = 0, l = tabs.length; i<l; i++) {
          var t = tabs[i];
          tab = {};
          tab.title = t.innerText;
          tab.name = WAVE.strDefault(t.getAttribute(fAttributePrefix + "name"));
          if (WAVE.strEmpty(tab.name)) tab.name = null;
          tab.isHtml = WAVE.strAsBool(t.getAttribute(fAttributePrefix + "isHtml"), true);
          tab.isActive = WAVE.strAsBool(t.getAttribute(fAttributePrefix + "isActive"), false);
          tab.visible = WAVE.strAsBool(t.getAttribute(fAttributePrefix + "visible"), true);
          tab.cont = WAVE.id(WAVE.strDefault(t.getAttribute(fAttributePrefix + "contId")));
          tab.li = t;
          fTabs.push(new Tab(tab));
        }
    } else {
      var html =
        "<div id='@divTabsId@' class='@ulContainer@'>" +
          "<ul id='@ulId@' class='@ulClass@'></ul>" +
        "</div>" +
        "<div id='@divContId@' class='@divClass@'></div>";

      fDIV.innerHTML = WAVE.strHTMLTemplate(html,
      {
        divTabsId : fControlsIds.divTabsContId,
        divContId : fControlsIds.divContentContId,
        ulId : fControlsIds.ulTabsId,
        ulClass : published.CLS_TABS_UL,
        divClass : published.CLS_TABS_CONTENT_CONTAINER,
        ulContainer : published.CLS_TABS_UL_CONTAINER
      });
    }

    if(fTabs.length === 0) return;

    var activeTab = null;
    var hit = false;
    for(i = 0; i < fTabs.length; i++) {
      tab = fTabs[i];
      if(tab.isActive() && tab.visible()){
        if(!hit){
          activeTab = tab.name();
          hit = true;
        } else {
          tab.isActive (false);
        }
      }
      tab.build(true, false);
    }
    if(!hit){
      i = 0;
      while(i < fTabs.length){
        if (fTabs[i].visible()) {
          activeTab = fTabs[i].name();
          fTabs[i].isActive(true);
          break;
        }
        i++;
      }
    }
    if (activeTab !== null)
      activate(activeTab);
  }
  build();

  return tabs;
};//Tabs