/**
 * @author ZhangHuihua@msn.com
 */
var navTab = {
    componentBox: null, // tab component. contain tabBox, prevBut, nextBut,
    // panelBox
    _tabBox: null ,
    _prevBut: null ,
    _nextBut: null ,
    _panelBox: null ,
    _moreBut: null ,
    _moreBox: null ,
    _currentIndex: 0 ,
    _op: {
        id: "navTab", step: 4 , stTabBox: ".navTab-tab", stPanelBox: ".navTab-panel", mainTabId: "main", close$: "a.close", prevClass: "tabsLeft", nextClass: "tabsRight" ,
        stMore: ".tabsMore", stMoreLi: "ul.tabsMoreList"
    } ,
    init: function(options) {
        if ($.History) {
            $.History.init();
        }
        var $this = this;
        $.extend(this._op, options);
        this.componentBox = $("#" + this._op.id);
        this.step = this._op.step;
        this._tabBox = this.componentBox.find(this._op.stTabBox);
        this._panelBox = this.componentBox.find(this._op.stPanelBox);
        this._prevBut = this.componentBox.find("." + this._op.prevClass);
        this._nextBut = this.componentBox.find("." + this._op.nextClass);
        this._moreBut = this.componentBox.find(this._op.stMore);
        this._moreBox = this.componentBox.find(this._op.stMoreLi);
        this._prevBut.on("click", function(event) {
            $this._scrollPrev()
        });
        this._nextBut.on("click", function(event) {
            $this._scrollNext()
        });
        this._moreBut.on("click", function() {
            $this._moreBox.show();
            return false;
        });
        $(document).on("click", function() {
            $this._moreBox.hide()
        });
        this._contextmenu(this._tabBox);
        this._contextmenu(this._getTabs());
        this._init();
        this._ctrlScrollBut();
    } ,
    _init: function() {
        var $this = this;
        this._getTabs().each(function(iTabIndex) {
            $(this).off("click").on("click", function(event) {
                $this._switchTab(iTabIndex);
            });
            $(this).find(navTab._op.close$).off("click").on("click", function() {
                $this._closeTab(iTabIndex);
            });
        });
        this._getMoreLi().each(function(iTabIndex) {
            $(this).find(">a").off("click").on("click", function(event) {
                $this._switchTab(iTabIndex);
            });
        });
        this._switchTab(this._currentIndex);
    } ,
    _contextmenu: function($obj) { // navTab右键菜单
        var $this = this;
        $obj.contextMenu("navTabCM", {
            bindings: {
                reload: function(t, m) {
                    $this._reload(t, true);
                }, closeCurrent: function(t, m) {
                    var tabId = t.attr("tabid");
                    if (tabId ) {
                        $this.closeTab(tabId);
                    } else {
                        $this.closeCurrentTab();
                    }
                }, closeOther: function(t, m) {
                    var index = $this._indexTabId(t.attr("tabid"));
                    $this._closeOtherTab(index > 0 ? index: $this._currentIndex);
                }, closeAll: function(t, m) {
                    $this.closeAllTab();
                }
            }, ctrSub: function(t, m) {
                var mReload = m.find("[rel=\"reload\"]");
                var mCur = m.find("[rel=\"closeCurrent\"]");
                var mOther = m.find("[rel=\"closeOther\"]");
                var mAll = m.find("[rel=\"closeAll\"]");
                var $tabLi = $this._getTabs();
                if ($tabLi.length < 2 ) {
                    mCur.addClass("disabled");
                    mOther.addClass("disabled");
                    mAll.addClass("disabled");
                }
                if ($this._currentIndex == 0 || t.attr("tabid") == $this._op.mainTabId ) {
                    mCur.addClass("disabled");
                    if(!t.attr("url")){
                        mReload.addClass("disabled");
                    }
                } else if ($tabLi.length == 2 ) {
                    mOther.addClass("disabled");
                }
            }
        });
    } ,
    _getTabs: function() {
        return this._tabBox.find("> li");
    } ,
    _getPanels: function() {
        return this._panelBox.find("> div");
    } ,
    _getMoreLi: function() {
        return this._moreBox.find("> li");
    } ,
    _getTab: function(tabid) {
        var index = this._indexTabId(tabid);
        if (index >= 0 ) {
            return this._getTabs().eq(index);
        }
    } ,
    getPanel: function(tabid) {
        var index = this._indexTabId(tabid);
        if (index >= 0 ) {
            return this._getPanels().eq(index);
        }
    } ,
    _getTabsW: function(iStart, iEnd) {
        return this._tabsW(this._getTabs().slice(iStart, iEnd));
    } ,
    _tabsW: function($tabs) {
        var iW = 0;
        $tabs.each(function() {
            iW += $(this).outerWidth(true);
        });
        return iW;
    } ,
    _indexTabId: function(tabid) {
        if (!tabid ) {
            return -1;
        }
        var iOpenIndex = -1;
        this._getTabs().each(function(index) {
            if ($(this).attr("tabid") == tabid ) {
                iOpenIndex = index;
                return;
            }
        });
        return iOpenIndex;
    } ,
    _getLeft: function() {
        return this._tabBox.position().left;
    } ,
    _getScrollBarW: function() {
        return this.componentBox.width() - 90;
    } ,
    _visibleStart: function() {
        var iLeft = this._getLeft(), iW = 0;
        var $tabs = this._getTabs();
        for (var i = 0; i < $tabs.length; i++) {
            if (iW + iLeft >= 0 ) {
                return i;
            }
            iW += $tabs.eq(i).outerWidth(true);
        }
        return 0;
    } ,
    _visibleEnd: function() {
        var iLeft = this._getLeft(), iW = 0;
        var $tabs = this._getTabs();
        for (var i = 0; i < $tabs.length; i++) {
            iW += $tabs.eq(i).outerWidth(true);
            if (iW + iLeft > this._getScrollBarW() ) {
                return i;
            }
        }
        return $tabs.length;
    } ,
    _scrollPrev: function() {
        var iStart = this._visibleStart();
        if (iStart >= this.step ) {
            this._scrollTab(-this._getTabsW(0, iStart - this.step));
        } else if (iStart > 0 ) {
            this._scrollTab(-this._getTabsW(0, iStart - 1));
        }
    } ,
    _scrollNext: function() {
        var iEnd = this._visibleEnd();
        if (iEnd + this.step <= this._getTabs().length ) {
            this._scrollTab(-this._getTabsW(0, iEnd + this.step) + this._getScrollBarW());
        } else if (iEnd < this._getTabs().length ) {
            this._scrollTab(-this._getTabsW(0, iEnd + 1) + this._getScrollBarW());
        }
    } ,
    _scrollTab: function(iLeft, isNext) {
        var $this = this;
        this._tabBox.animate({
            left: iLeft + "px"
        }, 200, function() {
            $this._ctrlScrollBut();
        });
    } ,
    _scrollCurrent: function() { // auto scroll current tab
        var iW = this._tabsW(this._getTabs());
        if (iW <= this._getScrollBarW() ) {
            this._scrollTab(0);
        } else if (this._getLeft() < this._getScrollBarW() - iW ) {
            this._scrollTab(this._getScrollBarW() - iW);
        } else if (this._currentIndex < this._visibleStart() ) {
            this._scrollTab(-this._getTabsW(0, this._currentIndex));
        } else if (this._currentIndex >= this._visibleEnd() ) {
            this._scrollTab(this._getScrollBarW() - this._getTabs().eq(this._currentIndex).outerWidth(true) - this._getTabsW(0, this._currentIndex));
        }
    } ,
    _ctrlScrollBut: function() {
        var iW = this._tabsW(this._getTabs());
        if (this._getScrollBarW() > iW ) {
            this._prevBut.hide();
            this._nextBut.hide();
            this._tabBox.parent().removeClass("tabsPageHeaderMargin");
        } else {
            this._prevBut.show().removeClass("tabsLeftDisabled");
            this._nextBut.show().removeClass("tabsRightDisabled");
            this._tabBox.parent().addClass("tabsPageHeaderMargin");
            if (this._getLeft() >= 0 ) {
                this._prevBut.addClass("tabsLeftDisabled");
            } else if (this._getLeft() <= this._getScrollBarW() - iW +0.5 ) {
                this._nextBut.addClass("tabsRightDisabled");
            }
        }
    } ,
    _switchTab: function(iTabIndex) {
        var $tab = this._getTabs().removeClass("selected").eq(iTabIndex).addClass("selected");
        this._getPanels().each(function(){
            // 防止iframe被隐藏后iframe滚动到最上面
            if($(".iframe-box",$(this)).length){
                $(this).css("visibility","hidden").height(0);
            }else{
                $(this).hide();
            }
        });
        var currentPanel = this._getPanels().eq(iTabIndex);
        if("hidden"===currentPanel.css("visibility")){
            currentPanel.css("visibility","visible").css("height","auto");
        } else {
            currentPanel.show()
        }
        this._getMoreLi().removeClass("selected").eq(iTabIndex).addClass("selected");
        this._currentIndex = iTabIndex;
        this._scrollCurrent();
        this._reload($tab);
    } ,
    _closeTab: function(index, openTabid) {
        this._getTabs().eq(index).remove();
        this._getPanels().eq(index).trigger(JUI.eventType.pageClear).remove();
        this._getMoreLi().eq(index).remove();
        if (this._currentIndex >= index ) {
            this._currentIndex--;
        }
        if (openTabid ) {
            var openIndex = this._indexTabId(openTabid);
            if (openIndex > 0 ) {
                this._currentIndex = openIndex;
            }
        }
        this._init();
        this._scrollCurrent();
        this._reload(this._getTabs().eq(this._currentIndex));
    } ,
    closeTab: function(tabid) {
        var index = this._indexTabId(tabid);
        if (index > 0 ) {
            this._closeTab(index);
        }
    } ,
    closeCurrentTab: function(openTabid) { // openTabid
        // 可以为空，默认关闭当前tab后，打开最后一个tab
        if (this._currentIndex > 0 ) {
            this._closeTab(this._currentIndex, openTabid);
        }
    } ,
    closeAllTab: function() {
        this._getTabs().slice(1).remove();
        this._getPanels().slice(1).trigger(JUI.eventType.pageClear).remove();
        this._getMoreLi().slice(1).remove();
        this._currentIndex = 0;
        this._init();
        this._scrollCurrent();
    } ,
    _closeOtherTab: function(index) {
        index = index || this._currentIndex;
        if (index > 0 ) {
            var str$ = ":eq(" + index + ")";
            this._getTabs().not(str$).slice(1).remove();
            this._getPanels().not(str$).slice(1).trigger(JUI.eventType.pageClear).remove();
            this._getMoreLi().not(str$).slice(1).remove();
            this._currentIndex = 1;
            this._init();
            this._scrollCurrent();
        } else {
            this.closeAllTab();
        }
    } ,
    _loadUrlCallback: function($panel) {
        $panel.find("[layoutH]").layoutH();
        $panel.find(":button.close").on("click", function() {
            navTab.closeCurrentTab();
        });
    } ,
    _reload: function($tab, flag) {
        flag = flag || $tab.data("reloadFlag");
        var url = $tab.attr("url");
        if (flag && url ) {
            $tab.data("reloadFlag", null);
            var $panel = this.getPanel($tab.attr("tabid"));
            if ($tab.hasClass("external") || url.isExternalUrl()) {
                navTab.openExternal(url, $panel);
            } else if(2 == flag) {
                $panel.loadUrl(url, {}, function() {
                    navTab._loadUrlCallback($panel);
                });
            } else {
                // 获取pagerForm参数
                var $pagerForm = $(".pagerForm", $panel);
                if(0==$pagerForm.length){
                    $panel.loadUrl(url, {}, function() {
                        navTab._loadUrlCallback($panel);
                    });
                } else {
                    $pagerForm.trigger("submit");
                }
            }
        } else {
            this.getCurrentPanel().trigger(JUI.eventType.resizeChart);
        }
    } ,
    reloadFlag: function(tabid,value) {
        var $tab = this._getTab(tabid);
        if ($tab ) {
            if (this._indexTabId(tabid) == this._currentIndex ) {
                this._reload($tab, true);
            } else {
                if(!value){
                    value = 1;
                }
                $tab.data("reloadFlag", value);
            }
        }
    } ,
    reload: function(url, options) {
        var op = $.extend({
            data: {}, navTabId: "", callback: null
        }, options);
        var $tab = op.navTabId ? this._getTab(op.navTabId): this._getTabs().eq(this._currentIndex);
        var $panel = op.navTabId ? this.getPanel(op.navTabId): this._getPanels().eq(this._currentIndex);
        if ($panel ) {
            if (!url ) {
                url = $tab.attr("url");
            }
            if (url ) {
                if ($tab.hasClass("external") ) {
                    navTab.openExternal(url, $panel);
                } else {
                    if ($.isEmptyObject(op.data) ) { // 获取pagerForm参数
                        var $pagerForm = $(".pagerForm", $panel);
                        op.data = $pagerForm.length > 0 ? $pagerForm.serializeArray(): {}
                    }
                    $panel.ajaxUrl({
                        type: "POST", url: url, data: op.data, callback: function(response) {
                            navTab._loadUrlCallback($panel);
                            if ("function" === typeof op.callback ) {
                                op.callback(response);
                            }
                        }
                    });
                }
            }
        }
    } ,
    getCurrentPanel: function() {
        return this._getPanels().eq(this._currentIndex);
    } ,
    checkTimeout: function() {
        var json = JUI.jsonEval(this.getCurrentPanel().html());
        if (json && json.statusCode == JUI.statusCode.timeout ) {
            this.closeCurrentTab();
        }
    } ,
    openExternal: function(url, $panel) {
        var ih = navTab._panelBox.height();
        $panel.html(JUI.frag["externalFrag"].replaceAll("{url}", url).replaceAll("{height}", ih + "px"));
    } ,
    /**
     * @param {Object}
     *            tabid
     * @param {Object}
     *            url
     * @param {Object}
     *            params: title, data, fresh
     */
    openTab: function(tabid, url, options) { // if found tabid replace tab,
        // else create a new tab.
        var op = $.extend({
            title: "New Tab" , changeTitle : true, data: {}, fresh: true, external: false, focusNewWindow:false
        }, options);
        var iOpenIndex = this._indexTabId(tabid);
        if (iOpenIndex >= 0 && !op.focusNewWindow) {
            var $tab = this._getTabs().eq(iOpenIndex);
            var $panel = this._getPanels().eq(iOpenIndex);
            if(op.changeTitle){
                $tab.find(">a").eq(0).attr("title", op.title).text(op.title);
                this._getMoreLi().eq(iOpenIndex).find(">a").attr("title",op.title).text(op.title);
            }
            if (op.fresh || $tab.attr("url") != url ) {
                $tab.attr("url", url);
                if (op.external || url.isExternalUrl() ) {
                    $tab.addClass("external");
                    navTab.openExternal(url, $panel);
                } else {
                    $tab.removeClass("external");
                    $panel.ajaxUrl({
                        type: "GET", url: url, data: op.data, callback: function() {
                            navTab._loadUrlCallback($panel);
                        }
                    });
                }
            }
            this._currentIndex = iOpenIndex;
        } else {
            if(op.focusNewWindow){
              tabid += Math.round(Math.random() * 10000000);
            }
            this._getPanels().eq(this._currentIndex).after("<div class=\"page unitBox\"></div>");
            this._getTabs().eq(this._currentIndex).after($("<li><a href=\"javascript:;\" class=\"close\"><i class=\"icon-remove-sign\"></i></a></li>").attr("tabid",tabid).prepend($("<a href=\"javascript:\"></a>").attr("title",op.title).text(op.title)));
            this._getMoreLi().eq(this._currentIndex).after($("<li></li>").append($("<a href=\"javascript:\"></a>").attr("title",op.title).text(op.title)));
            var $tabs = this._getTabs();
            var $tab = $tabs.eq(this._currentIndex+1);
            var $panel = this._getPanels().eq(this._currentIndex+1);

            if (op.external || url.isExternalUrl() ) {
                $tab.addClass("external");
                navTab.openExternal(url, $panel);
            } else {
                $tab.removeClass("external");
                $panel.ajaxUrl({
                    type: "GET", url: url, data: op.data, callback: function() {
                        navTab._loadUrlCallback($panel);
                    }
                });
            }
            if ($.History) {
                setTimeout(function(){
                    $.History.addHistory(tabid, function(hash){
                        var i = navTab._indexTabId(hash);
                        if (i >= 0) {
                            navTab._switchTab(i);
                        }
                    }, tabid);
                }, 10);
            }
            this._currentIndex = this._currentIndex + 1;
            this._contextmenu($tabs.eq(this._currentIndex));
        }
        this._init();
        this._scrollCurrent();
        this._getTabs().eq(this._currentIndex).attr("url", url);
    }
};