﻿var TabsControl = Class.create();
TabsControl.prototype = {
	initialize: function(control, options) {
	    this.options = {
          focusFirstAccessibleElement: false,
          defaultActiveTabNumber: null
        }
        Object.extend(this.options, options || {});
          
		this.control = $(control);
		if(!this.control) return;
		this.controlId = "#" + this.control.id;
		
		// получаем список закладок и навешиваем для них обработку событий
		var tabs = $$(this.controlId+" ul.tabs")[0];
		$A(cssQuery("li div > a", tabs)).each((function(tabLink) {
			var tabLinkHref = tabLink.getAttribute("href").match(/[-_\w]+$/i)[0];
			// псевдозакладка
			if(Element.hasClassName(tabLink, "pseudotab")) {
				var pseudotabDiv = $(tabLinkHref); // div с ссылками на скрытые закладки (на который задана ссылка)
				pseudotabDiv.style.zIndex = 1000;
				pseudotabDiv.style.display = "none";
				Event.observe(tabLink, "focus", (function(e) { this.pseudotabLink_onfocus(pseudotabDiv, e); }).bind(this), false);
				Event.observe(tabLink, "focusout", (function(e) { this.pseudotabLink_onfocusout(pseudotabDiv, e); }).bind(this), false);
				Event.observe(tabLink, "mouseover", this.pseudotabLink_onmouseover, false);
				Event.observe(tabLink, "mouseleave", (function(e) { this.pseudotabLink_onmouseleave(pseudotabDiv, e); }).bind(this), false);
				Event.observe(tabLink, "click", (function(e) { this.pseudotabLink_onclick(pseudotabDiv, e); }).bind(this), false);
				Event.observe(pseudotabDiv, "mouseleave", (function(e) { this.pseudotabDiv_onmouseleave(tabLink, e); }).bind(this), false);
				Event.observe(pseudotabDiv, "focusout", (function(e) { this.pseudotabDiv_onfocusout(pseudotabDiv, tabLink, e); }).bind(this), false);
				
				// получаем список ссылок на скрытые закладки и на эти ссылки навешиваем обработку события onclick
				$A(cssQuery("ul > li > a", pseudotabDiv)).each((function(pseudotabDivLink) {
					var pseudotabDivLinkHref = $(pseudotabDivLink.getAttribute("href").match(/[-_\w]+$/i)[0]);
					var tabLink = $(pseudotabDivLinkHref); // закладка(<а>), на которую задана ссылка
					Event.observe(pseudotabDivLink, "click", (function(e) { this.pseudotabDivLink_onclick(pseudotabDiv, tabLink, e); }).bind(this), false);
				}).bind(this));
			}
			// обычная закладка
			else {
				var tabPage = $(tabLinkHref); // div с содержимым, соответствующий данной закладке (на который задана ссылка)
				Event.observe(tabLink, "click", (function(e) { this.tabLink_onclick(tabPage, e); }).bind(this), false);
			}
		}).bind(this));
		
		if(this.options.defaultActiveTabNumber != null) {
		    var firstTab = $$(this.controlId + " ul.tabs li a")[this.options.defaultActiveTabNumber];
		    this.simulateClick( firstTab ); // имитируем клик по n-ной закладке, чтобы вызвать обработку
		}
	},
	
	simulateClick : function( node )
	{
	    if ( node == null )
	        return false;
	        
	    if ( Prototype.Browser.IE )
	    {
	        // MSIE event
	        node.fireEvent("onclick");
	    }
	    else
	    {
	        // FireFox event model
	        var evt = document.createEvent( "MouseEvents" );
	        evt.initMouseEvent( "click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null );
	        node.dispatchEvent( evt );
	    }
	},
	
	activateTab : function( tabnum )
	{
	    // имитируем клик по n-ной закладке, чтобы вызвать обработку панели
	    this.simulateClick( $$(this.controlId + " ul.tabs li a")[tabnum] );
    },
    
	// функция возвращает активную закладку (ссылку)
	getActiveTabLink: function() {
		var tabs = $$(this.controlId + " ul.tabs")[0];
		var activeTabLinks = $A(cssQuery("li.active > a", tabs));
		if(activeTabLinks.length > 0) return activeTabLinks[0];
	},
	
	netxTab: function() {
		var tabs = $$(this.controlId + " ul.tabs")[0];
		var activeTabs = $A(cssQuery("li.active > a", tabs));
			
		if(activeTabs.length > 0) 
		{
			var activeTab = activeTabs[0];			
			// определяем след закладку путём отсечения 'tabLink' и добавления 1
			var idxNextTab = parseInt( activeTab.getAttribute( "id" ).substring(7) );
		    var next = $$(this.controlId + " ul.tabs li a")[idxNextTab];
		    if ( next != null ) next.fireEvent("onclick"); // имитируем клик по n-ной закладке, чтобы вызвать обработку    
		}
	},
	
	prevTab: function() {
		var tabs = $$(this.controlId + " ul.tabs")[0];
		var activeTabs = $A(cssQuery("li.active div > a", tabs));
			
		if(activeTabs.length > 0) 
		{
			var activeTab = activeTabs[0];			
			// определяем след закладку путём отсечения 'tabLink' и добавления 1
			var idxNextTab = parseInt( activeTab.getAttribute( "id" ).substring(7) ) - 2;
			if ( idxNextTab >= 0 )
			{
		        var prev = $$(this.controlId + " ul.tabs li a")[idxNextTab];
		        if ( prev != null ) prev.fireEvent("onclick"); // имитируем клик по n-ной закладке, чтобы вызвать обработку    
		    }
		}
	},		
	
	// обработка события onclick для закладки
	// стили закладок:
	//	active - активная в данный момент закладка
	//	hidden - закладка, скрытая по умолчанию
	//	visible - закладка, скрытая по умолчанию, которую отображаем до тех пор, пока не покажем другую закладку, скрытую по умолчанию
	tabLink_onclick: function(tabPage, e) {	    
		var tabLink = Event.element(e);	
		if ( tabLink.tagName.toLowerCase() == "span"  )
		{
		    tabLink = tabLink.parentNode;
		}   
		var tabs = $$(this.controlId+" ul.tabs")[0];
		// сброс активной закладки
		var activeTabs = $A(cssQuery("li.active", tabs));
		var visibleTabs = $A(cssQuery("li.visible", tabs)); // закладки, скрытые по умолчанию, но которые были открыты
		if(activeTabs.length > 0 ) 
		{
			var activeTab = activeTabs[0];
			Element.removeClassName(activeTab, "active"); // делаем неактивной ранее активную закладку
			if ( activeTab.childNodes.length > 1 ) // FireFox returns emnty #text tags around DIV
			{
			    Element.removeClassName(activeTab.childNodes[1], "active");			
			    var activeTabPage = $(activeTab.childNodes[1].childNodes[0].getAttribute("href").match(/[-_\w]+$/i)[0]); // скрываем див с содержимым, соответствующий ранее активной закладке
			    activeTabPage.style.display = "none";
			}
			else
			{
			    Element.removeClassName(activeTab.childNodes[0], "active");			
			    var activeTabPage = $(activeTab.childNodes[0].childNodes[0].getAttribute("href").match(/[-_\w]+$/i)[0]); // скрываем див с содержимым, соответствующий ранее активной закладке
			    activeTabPage.style.display = "none";
			}
		}

		//			for ( i = 0; i < activeTab.childNodes.length; ++i )
		//	    alert( activeTab.childNodes[i].value );

		//Element.addClassName(tabLink.parentNode, "active");
		Element.addClassName(tabLink.parentNode.parentNode, "active"); // делаем активной закладку, по который был произведен клик
		// активация новой закладки
		if( Element.hasClassName(tabLink.parentNode.parentNode, "hidden") )  
		{ // если делаем активной закладку, скрытую по умолчанию, меняем ее класс с hidden на visible
			Element.addClassName(tabLink.parentNode.parentNode, "visible");
			Element.removeClassName(tabLink.parentNode.parentNode, "hidden");
			// если уже отображается закладка, скрытая по умолчанию, то ее скрываем
			// в результате всегда показываем только одну закладку из скрытых по умолчанию
			if(visibleTabs.length > 0) 
			{
				Element.addClassName(visibleTabs[0], "hidden");
				Element.removeClassName(visibleTabs[0], "visible");
			}
		}
		tabPage.style.display = "block"; // показываем див с содержимым, соответствующий закладке, по который был произведен клик
		if(this.options.focusFirstAccessibleElement) Element.focusFirstAccessibleElement(tabPage, true); // устанавливаем фокус на первый элемент в показанном диве
		Event.stop(e);
	},
	
	// обработка события onfocus для псевдозакладки
	pseudotabLink_onfocus: function(pseudotabDiv, e) {
		var pseudotabLink = Event.element(e);
		var offsets = Position.positionedOffset(pseudotabLink);	
		if(pseudotabDiv.style.display != "none") return;
		pseudotabDiv.style.display = "block"; // показываем div с ссылками на скрытые закладки
		pseudotabDiv.style.top = offsets[1] + pseudotabLink.offsetHeight - 1 + "px"; // позиционируем div в зависимости от положения псевдозакладки
		pseudotabDiv.style.left = offsets[0] + "px";
		this.adjustiFrame(pseudotabDiv);
	},
	
	// обработка события onfocusout для псевдозакладки
	pseudotabLink_onfocusout: function(pseudotabDiv, e) {
		// если фокус перешел на див с ссылками на скрытые закладки или на его содержимое, то возврат
		if(e.toElement == pseudotabDiv || Element.isChild(pseudotabDiv, e.toElement)) return;
		// иначе скрываем див с ссылками на скрытые закладки
		pseudotabDiv.style.display = "none";
		this.adjustiFrame(pseudotabDiv);
	},
	
	// обработка события onmouseover для псевдозакладки
	pseudotabLink_onmouseover: function(e) {
		var pseudotabLink = Event.element(e);
		pseudotabLink.fireEvent("onfocus");
	},
	
	// обработка события onmouseleave для псевдозакладки
	pseudotabLink_onmouseleave: function(pseudotabDiv, e) {
		if(e.toElement == pseudotabDiv || Element.isChild(pseudotabDiv, e.toElement)) return;
		pseudotabDiv.style.display = "none";
		this.adjustiFrame(pseudotabDiv);
	},
	
	// обработка события onclick для псевдозакладки
	pseudotabLink_onclick: function(pseudotabDiv, e) {
		var pseudotabLink = Event.element(e);
		if(pseudotabDiv.style.display == "none") {	
			pseudotabLink.fireEvent("onfocus");
		}
		else Event.stop(e);	
	},
	
	// обработка события onfocusout для дива с ссылками на скрытые закладки
	pseudotabDiv_onfocusout: function(pseudotabDiv, tabLink, e) {
		// если фокус перешел на псевдозакладку или на одного из детей дива с ссылками на скрытые закладки, то возврат
		if(e.toElement == tabLink || Element.isChild(pseudotabDiv, e.toElement)) return;
		// иначе скрываем див
		pseudotabDiv.style.display = "none";
		this.adjustiFrame(pseudotabDiv);
	},
	
	// обработка события onmouseleave для дива с ссылками на скрытые закладки
	pseudotabDiv_onmouseleave: function(tabLink, e) {
		var pseudotabDiv = Event.element(e);
		if(e.toElement == tabLink || Element.isChild(pseudotabDiv, e.toElement)) return;
		pseudotabDiv.style.display = "none";
		this.adjustiFrame(pseudotabDiv);
	},
	
	// обработка события onclick для ссылки на скрытую закладку
	pseudotabDivLink_onclick: function(pseudotabDiv, tabLink, e) {
		pseudotabDiv.style.display = "none"; // скрываем див с ссылками на скрытые закладки
		tabLink.fireEvent("onclick");
		Event.stop(e);
	},
	
	// настройка размеров, положения и отображения фрейма в зависимости от соответствующих параметров дива с ссылками на скрытые закладки
	adjustiFrame: function(div) {
		if (!$("tabPageFrame")) {	
			var newNode = document.createElement("iFrame");
			newNode.setAttribute("id", "tabPageFrame");
			newNode.setAttribute("src", "javascript:false;");
			newNode.setAttribute("scrolling", "no");
			newNode.setAttribute("frameborder", "0");
			div.parentNode.appendChild(newNode);
		}
		
		iFrameDiv = $("tabPageFrame");
		
		try {
			iFrameDiv.style.position = "absolute";
			iFrameDiv.style.width = div.offsetWidth;
			iFrameDiv.style.height = div.offsetHeight;
			iFrameDiv.style.top = div.style.top;
			iFrameDiv.style.left = div.style.left;
			iFrameDiv.style.zIndex = div.style.zIndex-1;
			iFrameDiv.style.display = div.style.display;
		} 
		catch(e) {}
	},
	
	show: function() {
	    this.control.style.display = "block";
	},
	
	hide: function() {
	    this.control.style.display = "none";
	}
}
