/**
 * @author ryzy(core), mgronek(extensions)
 */


function yuiRemoveBlur(path) {
	var arr = YAHOO.util.Selector.query(path);
	for (var k in arr) {
		arr[k].onfocus = function() {this.blur();return}
	}
}

/**
 * TabPages
 * Obiekt bierze mainEl i wstawia do niego TabView.
 * Utylizuje taby dostępne w labelParentEl
 * Bierze contentEl i treści z niego podpina pod pierwszego taba
 *
 * Przykład użycia:
 *
 <code>
page.includeJS.hiyuitabpages = typo3conf/ext/hi_yui_tabpages/res/hi_yui_tabpages.js

page.headerData.235 = TEXT
page.headerData.235.value (
<script type="text/javascript">
	Event.onContentReady('container2', function() {
		var tp = new HI_YUI_TabPages({
			mainEl: '#page div.left-content', // ul.yui-nav and div.yui-content will be inserted/rendered into this element
			labelParentEl: 'div.menu-tabs ul',
			contentEl: 'div.left-content div.my-tab-container', // tab view content will be inserted into this element. Must be inside of 'mainEl' (classname should be different than 'yui-content').
			cacheData: true
		});
		yuiRemoveBlur('.yui-nav a');
	});
</script>
)
 </code>

 *
 *
 *
 *
 * @param {Object} cnf: obiekt z konfiguracją (patrz opcje poniżej)
 *
 * @cnf {HTMLElement|String} mainEl: HTML element lub CSS selector do elementu, do którego trafi komponent TabView
 * @cnf {HTMLElement|String} labelParentEl: HTMLElement lub CSS selector do elementu z dziećmi, które zostaną użyte jako taby w TabView
 * @cnf {HTMLElement|String} contentEl: HTMLElement lub CSS selector do elementu, który zostanie użyty jako container wyświetlający treści tabów.
 * @cnf {Boolean} domSearchInsideMainEl: jeśli TRUE: w celu zwiększenia szybkości, labelParentEl oraz contentEl będą poszukiwane w środku mainEl (domyślnie TRUE)
 * @cnf {Boolean} cacheData: jeśli TRUE, treści w tabach nie będą keszowane tylko odświeżane przy każdym kliku
 */
HI_YUI_TabPages = function(cnf) {
	/**
	 * @description HTMLElement, który zawiera YAHOO.widget.TabView
	 * @type {HTMLElement}
	 * @private
	 */
	this.mainEl = null;

	/**
	 * @description HTMLElement, który zawiera elementy, które zostaną użyte jako taby w YAHOO.widget.TabView
	 * @type {HTMLElement}
	 * @private
	 */
	this.labelParentEl = null;

	/**
	 * @description HTMLElement, który zawiera content dla pierwszego taba, obok którego zostaną wyświetlone pozostałe taby
	 * @type {HTMLElement}
	 * @private
	 */
	this.contentEl = null;

	/**
	 * @type {YAHOO.widget.TabView}
	 * @private
	 */
	this.tabView = null;

	/**
	 * Określa, czy treści w tabach są keszowane (domyślnie TRUE) czy odświeżane przy każdym wejściu do taba
	 * @type {Boolean}
	 * @private
	 */
	this.cacheData = true;

	/**
	 * Przechowuje stan początkowy YAHOO.util.History przed skonstruowaniem Tabów
	 */
	this._tabViewInitState = null;

	this._clearURL = null;


	/**
	 * Utwórz aliasy dla zmiennych YAHOO lang, util, event
	 */
	Event = YAHOO.util.Event;
	Dom = YAHOO.util.Dom;
	Element = YAHOO.util.Element;
	Selector = YAHOO.util.Selector;
	lang  = YAHOO.lang;


	if (this._init(cnf)) {		// initialize tabView via YAHOO.util.History.onReady only
								// if a proper config is supplied
//alert('p_init');
		// fetch last state (if existed)
		tabViewBookmarkedState = YAHOO.util.History.getBookmarkedState("tabview");
		this._clearURL =  lang.isNull(tabViewBookmarkedState) ? true : false;

		// initial state is tab0 or bookmarked one;
		this._tabViewInitState = tabViewBookmarkedState || "tab0";


//console.log('@register', this._tabViewInitState);
		YAHOO.util.History.register("tabview", this._tabViewInitState, function(state){
			// This is called after calling YAHOO.util.History.navigate, or after the user
			// has trigerred the back/forward button. We cannot discrminate between
			// these two situations.

			// wniosek z powyzszego taki, ze jak wykomentuje ponizsza linie tabView.set - nie zmieniaja sie taby przy history.back

//console.log('@onStateChange');

			// TD: check if state.substr(3) is in range of count(tabView.elems)

			// "state" can be "tab0", "tab1" or "tab2".
				this.tabView.set("activeIndex", state.substr(3));


		}, this, true);


		// Use the Browser History Manager onReady method to instantiate the TabView widget.
		YAHOO.util.History.onReady(function(){
			var currentState;


			//        initTabView();
			this._makeTabs();
//console.log('@finished _makeTabs');
			// This is the tricky part... The onLoad event is fired when the user
			// comes back to the page using the back button. In this case, the
			// actual tab that needs to be selected corresponds to the last tab
			// selected before leaving the page, and not the initially selected tab.
			// This can be retrieved using getCurrentState:
//			currentState = YAHOO.util.History.getCurrentState("tabview");
//			this.tabView.set("activeIndex", currentState.substr(3));
		},
		this, true);	// verride current function context

		// Initialize the browser history management library.
		try {
			YAHOO.util.History.initialize("yui-history-field", "yui-history-iframe");
		}
		catch (e) {
			// The only exception that gets thrown here is when the browser is
			// not supported (Opera, or not A-grade) Degrade gracefully.
			//        initTabView();
//console.log('@err');
			this._makeTabs();


		}


//console.log('!@#' + this.tabView.get('activeIndex'));

	}
//	else { console.log('missed config'); }



}


/**
 * Inicjalizacja, wywszukiwanie podanych elementów
 * Rzuca wyjątki, jeśli nie znajdzie któregoś elementu
 *
 * @param {Object} cnf
 *
 * @return {Boolean} TRUE, jeśli znaleziono wymagane HTML elementy (mainEl, labelParentEl, contentEl)
 */
HI_YUI_TabPages.prototype._init = function(cnf) {

	// check for config options...
	if (!lang.isObject(cnf)) throw new Error('T3TabPages: no cnf object provided');
	if (!cnf.mainEl) throw new Error("T3TabPages: no 'mainEl' config property");
	if (!cnf.labelParentEl) throw new Error("T3TabPages: no 'labelParentEl' config property");
	if (!cnf.contentEl) throw new Error("T3TabPages: no 'contentEl' config property");

	// get mainEl where TabView will be inserted
	this.mainEl = lang.isString(cnf.mainEl) ? Selector.query(cnf.mainEl, Selector.document, true) : Dom.get(cnf.mainEl);
	if (!this.mainEl) throw new Error("T3TabPages: can't find 'mainEl' element!");

	var root = cnf.domSearchInsideMainEl ? this.mainEl : Selector.document;

	// get existing tabs' items/labels container
	this.labelParentEl = Selector.query(cnf.labelParentEl, root, true);
	if (!this.labelParentEl) throw new Error("T3TabPages: can't find 'labelParentEl' element!");

	// get container for tabs content...
	this.contentEl = lang.isString(cnf.contentEl) ? Selector.query(cnf.contentEl, root, true) : Dom.get(cnf.contentEl);
	if (!this.contentEl) throw new Error("T3TabPages: can't find 'contentEl' element!");

	// remaining cnf options...
	this.cacheData = cnf.cacheData || true;

	// make TabView object
	this.tabView = new YAHOO.widget.TabView(this.mainEl);
	this.tabView.CONTENT_PARENT_CLASSNAME = 'main';

	return true;
}

/**
 * Event Handler dla activeTabChange - zmien dodatkowo wpis w nawigacji
 * @param {Object} e
 */
HI_YUI_TabPages.prototype._onActiveTabChange = function(e) {
		YAHOO.util.History.navigate( 'tabview', 'tab' + this.getTabIndex(e.newValue) );

		// Update the UI of your module according to the "state" parameter
		// ponizsze jest niepotrzebne (?)
//		currentState = YAHOO.util.History.getCurrentState("tabview");
//		this.tabView.set("activeIndex", currentState.substr(3));
}

/**
 * Tworzy właściwy YAHOO.widget.TabView i dodaje do niego taby z elementów-dzieci znalezionych w this.labelParentEl
 */
HI_YUI_TabPages.prototype._makeTabs = function() {
	var labels = Dom.getChildren(this.labelParentEl);
//	console.log(labels, 'found labels');

	var matchedTab = this._getMatchedTab(labels);
//	console.log(matchedTab, 'matchedTab');

	for (var i in labels) {
		if (!lang.isNumber(parseInt(i))) continue;

		var aEl = Selector.query('a', labels[i], true);
		var prop = { cacheData: this.cacheData };

		// jesli zmatchowany tab/url zgodny z bieżącym tabem - zaladuj content z danej strony
		if (matchedTab == i) {
			prop.contentEl = this.contentEl;
		} else {
			prop.dataSrc = aEl.href + (aEl.href.indexOf('?') > -1 ? '&':'?') + 'type=508';
		}
//		console.log(prop, 'prop data prepared for new Tab');

		// utworz nowego taba
		var tab = new YAHOO.widget.Tab(labels[i], prop);
		YAHOO.plugin.Dispatcher.delegate(tab); // call dispatcher to execute JavaScript embeded in tab content (fetched via AJAX)

		this.tabView.addTab(tab);
	}

	var currentTabIndex = this._clearURL ? matchedTab : this._tabViewInitState.substr(3);
	this.tabView.selectTab(currentTabIndex);
//	console.log(currentTabIndex, 'currentTabIndex, matchedTab='+matchedTab);

	this.tabView.addListener("activeTabChange", this._onActiveTabChange);
}

HI_YUI_TabPages.prototype._getMatchedTab = function(labelElements) {
	var IS_REALURL = window.location.toString().search(/index\.php\\?\\?/) == -1;
	var currentHref = IS_REALURL ? this._getUrlIgnoreQuery(window.location.toString()) : this._getPageIdFromUrl(window.location.toString());
//	console.log(currentHref, 'currentHref');

	for (var i in labelElements) {
		if (!lang.isNumber(parseInt(i))) continue;

		var aEl = Selector.query('a', labelElements[i], true);
		var aElHref = IS_REALURL ? this._getUrlIgnoreQuery(aEl.href) : this._getPageIdFromUrl(aEl.href);
//		console.log(aElHref, ' current: '+currentHref);

		if (currentHref == aElHref) return i;
	}

	return 0;
}

/**
 * Strip from URL parts after ? (after # as well)
 * @return string
 */
HI_YUI_TabPages.prototype._getUrlIgnoreQuery = function(url) {
	url = url.indexOf('?') > -1 ? url.substr(0, url.indexOf('?')) : url;
	return url.indexOf('#') > -1 ? url.substr(0, url.indexOf('#')) : url;
}

/**
 * Get current page UID (from index.php?id=XXX)
 * @return integer
 */
HI_YUI_TabPages.prototype._getPageIdFromUrl = function(url) {
	var match = url.match(/\\?id=(\d+)/);
	return lang.isArray(match) && match[1] ? match[1] : 0;
}

