﻿(function (window, $) {
	function Tabs(jParent, options) {
		var oOldTabs;
		if (!(this instanceof Tabs)) {
			return new Tabs(jParent, options);
		}
		if (!(jParent instanceof $)) {
			if (jParent.nodeType && jParent.nodeType == 1) {
				jParent = $(jParent);
			}
		}
		if (!jParent.length) {
			throw new Error('Неверныей объект элемента родителя');
		}
		oOldTabs = jParent.data('tabsObj');
		if (oOldTabs) {
			return oOldTabs;
		}
		this.jParent = jParent;
		this.oPageState = $(window).data('pageStateObj');
		this.optValues = $.extend(true, {}, this.defOptions, options);
		this.useHashBang = (this.optValues.watchHashBang 
							&& this.optValues.hashKey.length 
							&& typeof this.oPageState != 'undefined');
		this.prepareElements();
		this.jParent.data('tabsObj', this);
	}
	
	Tabs.prototype = {
		defOptions : {
			cssSelectors : {
				Buttons : 'div.js-tabs-head div.js-tab-btn',
				Tabs : 'div.js-tab'
			},
			cssClasses : {
				currentTab : 'cur',
				currentBut : 'cur-b'
			},
			Functions : {
				Show : 'show',
				Hide : 'hide',
				useCbk: true
			},
			disabledLink: null,
			onTabShow: null,
			watchHashBang: false,
			hashKey: 'tab'
		},
		prepareElements : function () {
			var cssSelectors = this.optValues.cssSelectors, oTabs = this, elName,
				hashKeyVal, tabNo, curTabSel = '.' + this.optValues.cssClasses.currentTab;
			for (var selName in cssSelectors) {
				if (cssSelectors.hasOwnProperty(selName) && cssSelectors[selName].length) {
					elName = 'j' + selName.substr(0, 1).toUpperCase() + selName.substr(1);
					this[elName] = this.jParent.find(cssSelectors[selName]);
					if (!this[elName].length) {
						throw new Error('Неверный селектор "' + selName + '" (' + this[elName].selector + ').');
					}
					switch (selName) {
					case 'Buttons':
						this[elName].each(function (index) {
							var jBtn = $(this);
							if (oTabs.optValues.disabledLink && jBtn.is(oTabs.optValues.disabledLink)) {
								jBtn.bind('click.Tabs', function (e) {
									e.preventDefault();
								});
							} else {
								jBtn.bind('click.Tabs', function (e) {
									e.preventDefault();
									oTabs.setCurTab(index);
								});
							}
						});
						break;
					case 'Tabs':
						if (this.useHashBang) {
							hashKeyVal = this.oPageState.getStateKeys(this.optValues.hashKey);
						}
						if (typeof hashKeyVal != 'undefined') {
							if (!isNaN(hashKeyVal)) {
								tabNo = hashKeyVal;
							} else {
								if (hashKeyVal.substr(0,2) == 'cl') {
									curTabSel = '.' + hashKeyVal.substr(2);
								} else if (hashKeyVal.substr(0,2) == 'id') {
									curTabSel = '#' + hashKeyVal.substr(2);
								}
							}
						}
						if (typeof tabNo == 'undefined') {
							if (this.setTabBySel(curTabSel) !== false) {
								return;
							}
						}
						this.setCurTab(tabNo);
						break;
					}
				}
			}
			/*this.jButtons.each(function (index) {
				if (!oTabs.jTabs.eq(index).length) {
					$(this).unbind('click.Tabs');
				}
			});*/
		},
		setTabBySel: function (selector, callback) {
			var jTab = this.jTabs.filter(selector), 
				tabNo = this.jTabs.index(jTab), curStateVal;
			if (this.useHashBang) {
				curStateVal = this.oPageState.oState[this.optValues.hashKey];
				if (curStateVal != tabNo && !(typeof curStateVal == 'undefined' && !tabNo)) {
					this.oPageState.addToState(this.optValues.hashKey, tabNo == 0 ? false : tabNo, 'replace', false);
				}
			}
			if (jTab.length && tabNo != -1) {
				this.setCurTab(tabNo);
				if (typeof callback == 'function') {
					callback.call(this, jTab);
				}
			} else {
				return false;
			}
		},
		setCurTab: function (index) {
			index = index || 0;
			var cssClasses = this.optValues.cssClasses, jSelTab = this.jTabs.eq(index), 
				oFuncNames = this.optValues.Functions, hashBang,
				curTabElm = 'jTabs', oTabs = this, jCurTab, 
				curStateVal;
			if (this.Animated === true || index == this.curTab || !jSelTab.length) {
				return false;
			}
			if (this.jCurTab && this.jCurTab.length) {
				curTabElm = 'jCurTab';
			}
			jCurTab = this[curTabElm];
			if (jCurTab.length > 1) { // больше одной их только при инициализации
				jCurTab.hide();
				jSelTab.show();
				oTabs.onTabSwitch(jSelTab, jCurTab, index);
			} else {
				if (oFuncNames.Hide != 'hide' && oFuncNames.useCbk !== false) {
					this.Animated = true;
					jCurTab[oFuncNames.Hide](function () {
						if (oFuncNames.Show != 'show') {
							jSelTab[oFuncNames.Show](function () {
								oTabs.Animated = false;
							});
						} else {
							jSelTab[oFuncNames.Show]();
							this.Animated = false;
						}
						oTabs.onTabSwitch(jSelTab, jCurTab, index);
					});
				} else {
					jCurTab[oFuncNames.Hide]();
					jSelTab[oFuncNames.Show]();
					this.onTabSwitch(jSelTab, jCurTab, index);
				}
			}
			this.curTab = index;
			this.jCurTab = jSelTab;
			this.jButtons.removeClass(cssClasses.currentBut).eq(index).addClass(cssClasses.currentBut);
			jCurTab.removeClass(cssClasses.currentTab);
			if (this.useHashBang) {
				curStateVal = this.oPageState.oState[this.optValues.hashKey];
				if (curStateVal != index && !(typeof curStateVal == 'undefined' && !index)) {
					this.oPageState.pushToState(this.optValues.hashKey, index == 0 ? false : index, 'replace');
				}
			}
		},
		onTabSwitch: function (jSelTab, jOldTab, tabNo) {
			jSelTab.addClass(this.optValues.cssClasses.currentTab);
			if (typeof this.optValues.onTabShow == 'function') {
				this.optValues.onTabShow.call(this, jSelTab);
			}
		}
	};
	
	$.fn.makeTabs = function (options) {
		Tabs($(this), options);
		return this;
	};

	/*$('div.js-tabs').makeTabs({
		cssSelectors : {
			Buttons : 'div.js-tabs-head div.js-tab-btn',
			Tabs : 'div.js-tab'
		},
		cssClasses : {
			currentTab : 'cur',
			currentBut : 'cur-b'
		},
		Functions : {
			Show : 'fadeIn',
			Hide : 'fadeOut'
		},
		onTabShow: function (jTab) {
			if (jTab.is('.trailers')) {
				jTab.find('object').fitToParent();
			}
		},
		watchHashBang: true
	});*/
})(self, jQuery);
