ctlClientTabControlBase = _ctlCreateClass(ctlClientControl, {
	constructor: function(name){
		this.constructor.prototype.constructor.call(this, name);

        this.activeTabIndex = 0;
        this.callBackCount = 0;
        this.cookieName = "";
        this.emptyHeight = false;
        this.emptyWidth = false;
        this.tabAlign = "Left";
        this.tabPosition = "Top";
        this.tabCount = 0;
        this.tabs = [];

        this.TabClick = new ctlClientEvent();
        this.ActiveTabChanged = new ctlClientEvent();
        this.ActiveTabChanging = new ctlClientEvent();
        
        this.InitializeOnResize();
	},
	Initialize: function(){
        this.CorrrectCellsBounds();
        this.constructor.prototype.Initialize.call(this);
	},
    InitializeCallBackData: function(){
        var element = this.GetContentElement(this.activeTabIndex);
        if(element != null) element.loaded = true;
    },
    InitializeOnResize: function(){
        var element = this.GetMainElement();
        if(_ctlIsExists(element))
            element.onresize = new Function("ctlTCResize(\"" + this.name + "\");");	
    },

    GetTabsCell: function(){
        return this.GetChild("_TC");
    },
    GetTabElement: function(index, active){
        return this.GetChild("_" + (active ? "A" : "") + "T" + index);
    },
    GetContentsCell: function(){
        return this.GetChild("_CC");
    },
    GetContentElement: function(index){
        return this.GetChild("_C" + index);
    },
    GetLeftAlignCellElement: function(){
        return this.GetChild("_LAC");
    },
    GetRightAlignCellElement: function(){
        return this.GetChild("_RAC");
    },
    GetTabLayoutElement: function(element){
        if(!this.IsTopBottomTabPosition())
            return _ctlGetParentNode(element);
        return element;
    },

    GetActiveTabIndexInputElement: function(index){
        return _ctlGetElementById(this.name + "ATI");
    },

    IsTopBottomTabPosition: function(){
        return (this.tabPosition == "Top" || this.tabPosition == "Bottom");
    },

    CorrrectCellsBounds: function(){
        var mainElement = this.GetMainElement();
        if(mainElement == null || mainElement.offsetWidth == 0 || mainElement.offsetHeight == 0) return;

        mainElement.corrected = true;
   	    if(__ctlIE && !this.emptyHeight && this.tabAlign != "Justify"){
            if(this.IsTopBottomTabPosition())
                this.CorrectContentCellHeight();
            else
                this.CorrectAlignCellsHeight();
        }
        if(this.emptyHeight && !this.IsTopBottomTabPosition()){
            this.CorrectTabsCellHeight();
            if(__ctlIE)
                this.CorrectAlignCellsHeight();
        }
        if(this.emptyWidth && this.IsTopBottomTabPosition() && this.tabAlign != "Justify")
            this.CorrectTabsCellWidth();
        this.CorrectOperaTabsCellAlignment();
        this.CorrectOperaTabCellsAlignment();
    },
    CorrectTabsCellHeight: function(){
        var mainElement = this.GetMainElement();
        var tabsCell = this.GetTabsCell();
        if(mainElement != null && tabsCell){
            var leftAlignCell = this.GetLeftAlignCellElement();
            if(leftAlignCell != null)
                leftAlignCell.style.height = "auto";
            var rightAlignCell = this.GetRightAlignCellElement();
            if(rightAlignCell != null)
                rightAlignCell.style.height = "auto";
                
            tabsCell.style.height = "auto";
            tabsCell.style.height = mainElement.offsetHeight + "px";
            
            if(leftAlignCell != null && rightAlignCell == null)
                leftAlignCell.style.height = "100%";
            if(leftAlignCell == null && rightAlignCell != null)
                rightAlignCell.style.height = "100%";
            if(leftAlignCell != null && rightAlignCell != null){
                leftAlignCell.style.height = "50%";
                rightAlignCell.style.height = "50%";
            }
        }
    },
    CorrectTabsCellWidth: function(){
        var mainElement = this.GetMainElement();
        var tabsCell = this.GetTabsCell();
        if(mainElement != null && tabsCell){
            var leftAlignCell = this.GetLeftAlignCellElement();
            if(leftAlignCell != null)
                leftAlignCell.style.width = "auto";
            var rightAlignCell = this.GetRightAlignCellElement();
            if(rightAlignCell != null)
                rightAlignCell.style.width = "auto";
                
            tabsCell.style.width = "auto";
            tabsCell.style.width = mainElement.clientWidth;
            
            if(leftAlignCell != null && rightAlignCell == null)
                leftAlignCell.style.width = "100%";
            if(leftAlignCell == null && rightAlignCell != null)
                rightAlignCell.style.width = "100%";
            if(leftAlignCell != null && rightAlignCell != null){
                leftAlignCell.style.width = "50%";
                rightAlignCell.style.width = "50%";
            }
        }
    },
    CorrectContentCellHeight: function(){
        var mainElement = this.GetMainElement();
        var tabsCell = this.GetTabsCell();
        var contentsCell = this.GetContentsCell();
        if(mainElement != null && tabsCell != null && contentsCell != null){
            var tabsHeight = tabsCell.offsetHeight;
            tabsCell.style.height = tabsHeight + "px";
            contentsCell.style.height = "auto";
            contentsCell.style.height = (mainElement.clientHeight - tabsHeight) + "px";
        }
    },
    CorrectAlignCellsHeight: function(){
        var mainElement = this.GetMainElement();
        var tabsCell = this.GetTabsCell();
        if(mainElement != null && tabsCell != null){
            var leftAlignCell = this.GetLeftAlignCellElement();
            var rightAlignCell = this.GetRightAlignCellElement();
            var tabsTable = tabsCell.firstChild;
            if(tabsTable != null){
                if(leftAlignCell != null || rightAlignCell != null){
                    var tabsHeight = 0;
                    for(var i = 0; i < tabsTable.rows.length; i ++){
                        var cell = tabsTable.rows[i].cells[0];
                        if(cell != leftAlignCell && cell != rightAlignCell)
                            tabsHeight += cell.offsetHeight;
                    }
                    if(leftAlignCell != null)
                        leftAlignCell.style.height = "auto";
                    if(rightAlignCell != null)
                        rightAlignCell.style.height = "auto";
                    var correctionHeight = mainElement.clientHeight - tabsHeight;
                    if(leftAlignCell != null)
                        leftAlignCell.style.height = ((rightAlignCell != null) ? Math.round(correctionHeight / 2) : correctionHeight) + "px";
                    if(rightAlignCell != null)
                        rightAlignCell.style.height = ((leftAlignCell != null) ? Math.round(correctionHeight / 2) : correctionHeight) + "px";
                }
            }
        }
    },
    CorrectOperaTabsCellAlignment: function(){ // Fix for __ctlOpera bug
        if(!__ctlOpera || this.tabAlign != "Justify") return;
        if(!this.IsTopBottomTabPosition() && !this.emptyHeight) return;
        
        var element = this.GetTabsCell();
        _ctlSetElementDisplay(element, false);
        _ctlSetElementDisplay(element, true);
    },
    CorrectOperaTabCellsAlignment: function(){ // Fix for __ctlOpera bug
        if(!__ctlOpera || !this.IsTopBottomTabPosition()) return;

        var element = this.GetLeftAlignCellElement();
        if(element != null){ 
            _ctlSetElementDisplay(element, false);
            _ctlSetElementDisplay(element, true);
        }
        element = this.GetRightAlignCellElement();
        if(element != null){ 
            _ctlSetElementDisplay(element, false);
            _ctlSetElementDisplay(element, true);
        }
        for(var i = 0; i < this.tabCount; i ++){
            if(this.activeTabIndex == i) continue;
            element = this.GetTabElement(i, false);
            if(element != null){
                _ctlSetElementDisplay(element, false);
                _ctlSetElementDisplay(element, true);
            }
        }
    },
    
    FixControlSize: function(){
        this.FixElementSize(this.GetMainElement());
        this.FixElementSize(this.GetContentsCell());
    },
    UnfixControlSize: function(){
        this.UnfixElementSize(this.GetMainElement());
        this.UnfixElementSize(this.GetContentsCell());
    },
    FixElementSize: function(element){
        if(element == null) return;
        _ctlChangeStyleAttribute(element, "width", (__ctlIE ? element.clientWidth : element.offsetWidth) + "px");
        _ctlChangeStyleAttribute(element, "height", (__ctlIE ? element.clientHeight : element.offsetHeight) + "px");
    },
    UnfixElementSize: function(element){
        if(element == null) return;
        _ctlRestoreStyleAttribute(element, "width");
        _ctlRestoreStyleAttribute(element, "height");
    },
    
    ChangeTabState: function(index, active){
        var element = this.GetTabElement(index, true);
        if(element != null) _ctlSetElementDisplay(this.GetTabLayoutElement(element), active);
        element = this.GetTabElement(index, false);
        if(element != null) _ctlSetElementDisplay(this.GetTabLayoutElement(element), !active);
        element = this.GetContentElement(index);
        if(element != null) _ctlSetElementDisplay(element, active);
    },
    ChangeActiveTab: function(index, hasLink){
        var processingMode = this.autoPostBack ? "Server" : "Client";
        if(_ctlIsExists(this.RaiseActiveTabChanging))
            processingMode = this.RaiseActiveTabChanging(index);
        if(processingMode == "Client"){
            var element = this.GetContentElement(index);
            if(_ctlIsFunction(this.callBack) && element != null && !element.loaded){
                if(this.callBackCount == 0)
                    this.FixControlSize();
                this.DoChangeActiveTab(index);
                if(!element.loading){
                    this.callBackCount++;
                    element.loading = true;
                    
                    this.CreateLoadingPanelWithAbsolutePosition(element, this.GetContentsCell());
                    this.CreateCallback(index);
                }
                this.CorrectOperaTabCellsAlignment();
            }
            else{
                this.DoChangeActiveTab(index);

                this.CorrrectCellsBounds();
                this.CorrectOperaTabCellsAlignment();
                
                var activeContentElement = this.GetContentElement(this.activeTabIndex);
                var collection = ctlGetControlCollection();
                collection.AdjustControlsSize(activeContentElement, __ctlCheckSizeCorrectedFlag);

                if(_ctlIsExists(this.RaiseActiveTabChanged))
                    this.RaiseActiveTabChanged(index);
            }
        }
        else if(processingMode == "Server"  && !hasLink)
            this.SendPostBack("ACTIVATE:" + index);
    },
    DoChangeActiveTab: function(index){
        this.ChangeTabState(this.activeTabIndex, false);
        this.activeTabIndex = index;
        this.ChangeTabState(this.activeTabIndex, true);
        
        this.UpdateActiveTabIndexInputElement();
        this.UpdateActiveTabIndexCookie();
    },
    SetActiveTabIndexInternal: function(index, findLink, hasLink){
        if(this.activeTabIndex == index) return;
        
        if(findLink){
            var element = this.GetTabElement(index, false);
            var linkElement = (element != null) ? _ctlGetChildByTagName(element, "A", 0) : null;
            hasLink = (linkElement != null);
        }
        this.ChangeActiveTab(index, hasLink);
        if(findLink && linkElement != null){
            _ctlNavigateUrl(linkElement.href, linkElement.target);
        }
        this.UpdateHoverState(index);            
    },
    
    UpdateActiveTabIndexCookie: function(){
        if(this.cookieName == "") return;

        _ctlDelCookie(this.cookieName, this.activeTabIndex);
        _ctlSetCookie(this.cookieName, this.activeTabIndex);
    },
    UpdateActiveTabIndexInputElement: function(){
        var element = this.GetActiveTabIndexInputElement();
        if(element != null) element.value = this.activeTabIndex;
    },
    
    UpdateHoverState: function(index){
        var element = this.GetTabElement(index, true);
        if(element != null) ctlGetStateController().SetCurrentHoverElementBySrcElement(element);
    },
    
    OnResize: function(){
        var mainElement = this.GetMainElement();
        if(mainElement != null && !_ctlIsExists(mainElement.corrected))
            this.CorrrectCellsBounds();
    },
    OnTabClick: function(evt, index){            
        var processingMode = this.autoPostBack || this.IsServerEventAssigned("TabClick") ? "Server" : "Client";
        if(_ctlIsExists(this.RaiseTabClick))
            processOnServer = this.RaiseTabClick(index, evt);
            
        var element = this.GetTabElement(index, false);
        var linkElement = (element != null) ? _ctlGetChildByTagName(element, "A", 0) : null;
        hasLink = (linkElement != null);                                    
        if ((processingMode == "Client") || hasLink)
            this.SetActiveTabIndexInternal(index, true, true);
        else if (processingMode == "Server")
            this.SendPostBack("CLICK:" + index);
    },
    OnTabLinkClick: function(index, evt){
        if(_ctlIsExists(this.RaiseTabClick))
            processOnServer = this.RaiseTabClick(index, evt);
                
        if (this.processingMode == "Client")
            this.SetActiveTabIndexInternal(index, false, true);
    },
    OnCallbackInternal: function(result, isError){
        var pos = result.indexOf(__ctlCallBackSeparator);
        if(pos > -1){
            var callBackTabIndex = parseInt(result.substr(0, pos));
            var element = this.GetContentElement(callBackTabIndex);
            if(element != null) {
                result = result.substring(pos + __ctlCallBackSeparator.length);
                if(result != ""){
                    element.loaded = true;
                    element.loading = false;
                    element.innerHTML = result;
                    
                    this.callBackCount--;
                    if(this.callBackCount == 0){
                        this.UnfixControlSize();
                        this.CorrrectCellsBounds();
                        this.CorrectOperaTabCellsAlignment();
                    }
                    
                    if(!isError && _ctlIsExists(this.RaiseActiveTabChanged))
                        this.RaiseActiveTabChanged(callBackTabIndex);
                }
                else
                    this.SendPostBack("");
            }
        }
    },
    OnCallback: function(result){
        this.OnCallbackInternal(result, false);
    },
    OnCallbackError: function(result){
        this.OnCallbackInternal(result, true);
    }
});

ctlClientTabControl = _ctlCreateClass(ctlClientTabControlBase, {
});

ctlClientPageControl = _ctlCreateClass(ctlClientTabControlBase, {
});

function ctlTCResize(name){
    var tc = ctlGetControlCollection().Get(name);
    if(tc != null) tc.OnResize();
}
function ctlTCTClick(evt, name, index){
    var tc = ctlGetControlCollection().Get(name);
    if(tc != null) tc.OnTabClick(evt, index);
}
function ctlTCTLClick(evt, name, index, tabName){
    var tc = ctlGetControlCollection().Get(name);
    if(tc != null) tc.OnTabLinkClick(index, evt);
    evt.cancelBubble = true;
}