/**
 * Zalozky
 * *** objekt ktery umi zalozky ***
 * soubor muzete libovolne modifikovat i sirit dal, jen prosim ponechte v kodu tuto hlavicku
 * @author Michal Sobola
 * @revision 2009-11-03
 * 
 * nasazeni :
 * zakomentovane metody jsou nepovinne 
 **/

/**
  
  Zalozky = new Tabs(); // argument je jak se bude jmenovat promenna
  Zalozky.setTabMenu('menu'); // id menu
  // Zalozky.setTabElement('div'); // prvek, ktery je zalozka (vychozi je div)
  // Zalozky.setTabClassName('d_box'); // css trida zalozky (vychozi je d_box)
  // Zalozky.setActiveClass('active'); // trida aktivni polozky odkazu menu (vychozi je active)
  // Zalozky.setCookieName('showTab'); // jmeno cookie, kt. budeme ukladat (vychozi je showTab)
  // Zalozky.setCookieRemember(false); // nastavi, zda-li budeme uprednostnovat zalozky podle cookie
  // Zalozky.setActiveTabNo(0); // poradi zalozky, ktera bude zobrazena defaultne (vychozi je nulta)
  // Zalozky.setPlynulyPrechod(true); // budeme vyjizdej plynule (vychozi je ne)
  // Zalozky.setTimeoutValue(10); // hodnota timeoutu v milisec. pro vyjizdeni (vychozi je 10)
  // Zalozky.setDimension('x'); // smer, kterym vyjizdime zalozky (pokud vyjizdime) - v pripade ze je hodnota X - je nutne nastavit sirku zalozky (vychozi je Y)
  // Zalozky.setTabWidth(200); // pokud vyjizdime ze strany na stranu (osa X), je nutne nastavit css sirku objektu zalozek (nema vychozi hodnotu)
  Zalozky.init();

**/

/*
 * vrati cookie dle name
 * @param string Name
 */
function getCookie(Name) {
  replace = new RegExp(Name + "=[^;]+", "i");
  if (document.cookie.match(replace)) {
    return document.cookie.match(replace)[0].split("=")[1]
  }
  return null;
}

/*
 * nastavi cookie
 * @param string name
 * @param string value
 */
function setCookie(name, value) {
  expires = new Date();
  expires_str = expires.setDate(expires.getDate()+parseInt(365));
  document.cookie = name + "=" + value + "; expires=" + expires.toGMTString() + "; path=/";
}
 
function Tabs() 
{
  
  // id zalozkoveho menu
  var tabMenuId;

  // trida zalozky
  var tabClassName = 'dombox';
  
  // name elementu, ktery je zalozkou - pro rychlejsi vyfiltrovani
  var tabElement = 'div';
  
  // trida aktivniho odkazu zalozkoveho menu
  var activeClass = 'active';
  
  // jmeno cookie, kt. budeme ukladat
  var cookieName = 'showTab';
  
  // budeme uprednostnovat zalozky podle cookie?
  var cookieRemember = true;
  
  // poradi defaultne aktivni zalozky
  var activeTabNo = 0;
  
  // budeme vyjizdet plynule?
  var plynulyPrechod = false;
  
  // timeout v ms
  var timeoutValue = 10;
  
  // sirka zalozky - pro plynule vyjizdeni do strany
  var saveWidth = 0;
  
  // smer pri plynulem vyjizdeni - x | y
  var dimension = 'y';

  // zalozkove menu - pouze odkazy
  var tabMenu = [];
  
  // zalozkove divy
  var domTabs = [];
  
  // pocitadlo timeoutu
  var counter = 0;
  
  // bezici timeouty
  var runningTimeouts = [];
  
  // regular pro kotvu v url
  var locationHash = new RegExp('^#');
  
  // regular pro odkaz
  var anchorHash = new RegExp('^([^#]*)#');

  // aktualni kotva
  var kotva;
  
  // aktualni cookie
  var cookieShow;
  
  // aktivni index
  var activeIndex;

  // jmeno promenne, ve kt. je ulozena instance
  var actualObjectName;

  // sam svuj metlos
  var that = this;

  /*
   * nastavi zalozkove menu
   * @param string html id
   */
  this.setTabMenu = function(id)
  {
    tabMenuId = String(id);
    tabMenu = document.getElementById(id).getElementsByTagName('a');
  };
    
  /*
   * nastavi jmeno elementu, kt. budou zalozky - pro lepsi filtrovani
   * @param string elem html tag name       
   */
  this.setTabElement = function(elem)
  {
    tabElement = String(elem);
  };
  
  /*
   * nastavi html tridu zalozek
   * @param string html class    
   */
  this.setTabClassName = function(tabClassNameArg)
  {
    tabClassName = String(tabClassNameArg);
  };
  
  /*
   * nastavi aktivni tridu odkazu menu - mohou mit pouze jednu tridu   
   * @param string html class   
   */
  this.setActiveClass = function(activeClassArg)
  {
    activeClass = String(activeClassArg);
  };
  
  /*
   * jmeno cookie, kt.budmeme nastavovat
   * @param string cookieName      
   */
  this.setCookieName = function(cookieNameArg)
  {
    cookieName = String(cookieNameArg);
  };
  
  /*
   * nastavi, jestli u zalozek budeme uprednostnovat hodnotu ulozenou v cookie
   * @param bool remember   
   */
  this.setCookieRemember = function(remember)
  {
    cookieRemember = (remember ? true : false);
  };
  
  /*
   * nastavi cislo defaultne aktivni zalozky   
   * @param int no poradi zalozky zacinajici od 0
   */
  this.setActiveTabNo = function(no)
  {
    activeTabNo = parseInt(no);
  };
  
  /*
   * budou zalozky vyjizdet plynulym pohybem?
   * @param bool prechod
   */
  this.setPlynulyPrechod = function(prechod)
  {
    plynulyPrechod = (prechod ? true : false);
  };
  
  /*
   * nastavi hodnotu timeoutu v milisekundach
   * @param int value   
   */   
  this.setTimeoutValue = function(value)
  {
    timeoutValue = parseInt(value);
  };
  
  /*
   * nastavi smer plynuleho prechodu
   * @param string enum value (x | y)
   */
  this.setDimension = function(value)
  {
    if (value == 'x' || value == 'y') {
      dimension = value;
    }
  };
  
  /*
   * ulozi sirku zalozky - kvuli rozpinani do stran
   * @param int width
   */
  this.setTabWidth = function(width)
  {
    saveWidth = parseInt(width);
  };

  /*
   * inicializace
   */
  this.init = function()
  {
    domTabs = getElementsByTagAndClassName(tabElement, tabClassName);
    kotva = document.location.hash.replace(locationHash, '');
    cookieShow = getCookie(cookieName);

    if (kotva != '') {
      activeIndex = kotva.replace('#', '');
    } else if (cookieShow !== null && cookieRemember) {
      activeIndex = cookieShow;
    } else {
      activeIndex = domTabs[activeTabNo].id;
    }

    displayTabs();
    activateAnchors(true);
  };
  
  /*
   * preklikavani zalozek - funkce pridana na onclick odkazum
   * @param string link html href 
   */
  this.switchTab = function(link)
  {
    link = link.replace(anchorHash, '');

    activateAnchors(false, link);
    displayTabs(link, true);
    
    setCookie(cookieName, link);
    
    return false;
  };
  
  /*
   * ziskani danych elementu s urcitou html tridou
   * @param string htmlTagName jmeno html tagu
   * @param string htmlClassName jmeno html tridy      
   */
  function getElementsByTagAndClassName(htmlTagName, htmlClassName)
  {
    j = 0;
    elems = [];
    maybeElems = document.getElementsByTagName(htmlTagName);
    for (i = 0; i < maybeElems.length; i++) {
      if (maybeElems[i].className == htmlClassName) {
        elems[j] = maybeElems[i];
        j++;
      }
    }
    return elems; 
  }
  
  /*
   * pridani akce na onclick
   */
  function setOnclickAction(tabMenu, i)
  { 
    tabMenu[i].onclick = function() {
      // eval(actualObjectName + '.switchTab(this.href);');
      that.switchTab(this.href);
      return false;
    };
  }

  /*
   * zmena tridy odkazu, pridani akce na onclick
   * @param bool addOnclick s timto parametrem volame pouze pri loadu stranky
   * @param string toActivate hodnota odkazujici kotvy elementu, ktery bude aktivni       
   */
  function activateAnchors(addOnclick, toActivate)
  {
    // nepovinny argument
    if (toActivate === undefined) {
      toActivate = activeIndex;
    }
    
    // aktivace menu
    for (i = 0; i < tabMenu.length; i++) {
      href = tabMenu[i].href.replace(anchorHash, '');
      if (toActivate == href && typeof wasActivated === 'undefined') {
        tabMenu[i].className = activeClass;
        wasActivated = true;
      } else {
        tabMenu[i].className = '';
      }
      if (addOnclick) {
        setOnclickAction(tabMenu, i);
      }
    }
    
    // kdyby neco selhalo, aktivujeme prvni
    if (typeof wasActivated === 'undefined') {
      tabMenu[0].className += ' ' + activeClass;
    }
    
    // smazeme promennou kvuli dalsimu volani fce
    delete wasActivated;
  }

  /*
   * zobrazeni zalozek
   * @param string toActivate ID zalozky na zobrazeni
   * @param bool wasClicked pri loadu stranky preskocime pripadny plynuly efekt
   */
  function displayTabs(toActivate, wasClicked)
  {
    // nepovinne argumenty
    if (toActivate === undefined) {
      toActivate = activeIndex;
    }
    
    if (wasClicked === undefined) {
      wasClicked = false;
    }
    
    // zobrazeni zalozek
    for (i = 0; i < domTabs.length; i ++) {
      if (toActivate == domTabs[i].id && typeof wasDisplayed === 'undefined') {
        domTabs[i].style.display = 'block';
        toShow = domTabs[i];
        wasDisplayed = true;
      } else {
        domTabs[i].style.display = 'none';
      }
    }
    
    // kdyby neco selhalo, zobrazime prvni
    if (typeof wasDisplayed === 'undefined') {
      domTabs[0].style.display = 'block';
    }
    
    // smazeme promennou kvuli dalsimu volani fce
    delete wasDisplayed;

    // vyjizdime plynule?
    if (plynulyPrechod && wasClicked) {
      toShow.style.overflow = 'hidden';
      counter = 0;
      
      // zlikvidujeme bezici timeouty
      destroyTimeouts();
      
      // podminka pro vyjizdeni do strany nebo dolu
      if (dimension == 'x') {
        toShow.style.width = 0;
        runningTimeouts[counter] = setTimeout(function() { that.showElemX(toShow, counter); }, timeoutValue);
      } else if (dimension == 'y') {
        toShow.style.height = 0;
        runningTimeouts[counter] = setTimeout(function() { that.showElemY(toShow, counter); }, timeoutValue);
      }
    }
  }
  
  /*
   * zrusi vsechny probihajici timeouty
   */
  function destroyTimeouts() {
    for (i = 0; i < runningTimeouts.length; i++) {
      clearTimeout(runningTimeouts[i]);
    }
  }
  
  /*
   * plynule zobrazi zalozku shora dolu
   * @param object elem zalozky, se kt. pracujeme
   * @param int counter pocet probehlych timeoutu    
   */
  this.showElemY = function(elem, counter, extraFunction)
  { 
    if (extraFunction) {
      extraFunction();
    }
    counter++;
    if (elem.scrollHeight > elem.offsetHeight){
      posun = Math.round((elem.scrollHeight-elem.offsetHeight) / timeoutValue);
      if (posun < 1) {
        posun = 1;
      }
      elem.style.height = (elem.offsetHeight+posun) + 'px';
      runningTimeouts[counter] = setTimeout(function() { that.showElemY(elem, counter, extraFunction); }, timeoutValue);
    }
  };
  
  /*
   * plynule zobrazi zalozku ze strany na stranu
   * @param object elem zalozky, se kt. pracujeme
   * @param int counter pocet probehlych timeoutu    
   */
  this.showElemX = function(elem, counter)
  {
    counter++;
    if (saveWidth > elem.offsetWidth){
      posun = Math.round((saveWidth-elem.offsetWidth) / timeoutValue);
      if (posun < 1) {
        posun = 1;
      }
      elem.style.width = (elem.offsetWidth+posun) + 'px';
      runningTimeouts[counter] = setTimeout(function() { that.showElemX(elem, counter); }, timeoutValue);
    }
  };
  
  /*
   * rozsireni
   * pro plynule rozjeti jednoho prvku
   * @param string id HTML id prvku     
   */
  this.displayOne = function(id, self, originalLabel, onchangeLabel, extraFunction, origHeight) {
    toShow = document.getElementById(id);
    if (typeof extraFunction == 'undefined') {
      extraFunction = null;
    }
    if (!toShow.offsetHeight || (origHeight && origHeight == toShow.offsetHeight)) {
      if (self && onchangeLabel) {
        self.innerHTML = onchangeLabel;
      }
      toShow.style.height = (Number(origHeight) ? origHeight : 0);
      toShow.style.display = 'block';
      toShow.style.overflow = 'hidden';
      counter = 0;
      destroyTimeouts();
      runningTimeouts[counter] = setTimeout(function() { that.showElemY(toShow, counter, extraFunction); }, timeoutValue);
    } else {
      if (self && originalLabel) {  
        self.innerHTML = originalLabel;
      }
      toShow.style.height = (Number(origHeight) ? origHeight + 'px' : 0);
      if (!toShow.style.height) {
        toShow.style.display = 'none';
      }
    }
  }
}
