(function ($) {
    /**
     * 多标签容器。在多sheet报表中被使用到,如果需要使用代码控制sheet的跳转、展现等可以使用次类的方法。
     * @class FR.TabPane
     * @extends FR.Widget
     *
     * @cfg {JSON} options 配置属性
     * @cfg {Number} [options.width='100%'] 容器宽度
     * @cfg {Number} [options.height='100%'] 容器高度
     * @cfg {Number} [options.active=0] 当前活跃的tab索引
     * @cfg {'top'/'bottom'} [options.tabPosition='top'] tab控制器所在的位置,可以是底部或者顶部
     * @cfg {Number} [options.tabHeight=22] tab控制器的高度
     * @cfg {Boolean} [options.noControl=false] 是否不需要tab控制器
     * @cfg {Boolean} [options.defaultActiveIndex=0] 初始化完成后默认激活的tab索引
     * @cfg {Array} options.items tab容器的子组件
     */
    FR.TabPane = FR.extend(FR.Widget, /**@class FR.TabPane*/{

        _defaultConfig: function () {
            return $.extend(FR.TabPane.superclass._defaultConfig.apply(), {
                baseCls: "fr-tabpane",
                width: "100%",
                height: "100%",
                active: 0,
                tabPosition: "top", //tab所在位置,上|下
                tabHeight: 22,
                noControl: false,  //是否不需要tab控制按钮
                items: [],
                defaultActiveIndex: 0 //初始化后默认被激活的tab的位置索引
            });
        },

        _init: function () {
            FR.TabPane.superclass._init.apply(this, arguments);
            var opts = this.options;
            this.element.css({
                width: opts.width,
                height: opts.height
            });
            //生成配置信息
            var borderLayoutConfig = this._createConfig4TabPaneConfig();
            //整体布局
            var borderLayout = new FR.BorderLayout(borderLayoutConfig);
            borderLayout.doLayout();
            //生成所有的tab标签
            this.wrapWidth = 0; //记录所有标签总宽度
            this._initTabs();
            //选中默认tab
            if (this.tabBtns[opts.defaultActiveIndex]) {
                this.tabBtns[opts.defaultActiveIndex].setSelected();
            }
            this.isMoving = false;
            this.activeTabIndex = opts.defaultActiveIndex; //当前被激活tab的位置索引
            var self = this;
            this.tabsContent.parent().addClass(opts.baseCls + '-tabscontent-bg');
            $(window).resize(
                function () {
                    self.fireEvent(FR.Events.SCROLLCHANGE, self, self.activeTabIndex);
                }
            );
        },

        /**
         * 生成tabPane控件整体布局的配置信息
         * @private
         * @returns {*} 返回配置信息
         */
        _createConfig4TabPaneConfig: function () {
            var opts = this.options;
            var tabPos = opts.tabPosition;
            var contentCls = opts.baseCls + '-content';
            //tab内容层-tabPaneContent
            this.tabPaneContent = $('<div></div>').addClass(contentCls).addClass(contentCls + '-' + tabPos);
            //tab标签层-配置信息
            var tabControlConfig = this._createConfig4TabControl();
            var borderLayoutConfig = {
                renderEl: this.element,
                items: [
                    {
                        region: "center",
                        el: this.tabPaneContent
                    },
                    {
                        height: opts.tabHeight,
                        region: tabPos == 'top' ? 'north' : 'south',
                        el: tabControlConfig
                    }
                ]
            };
            return borderLayoutConfig;
        },

        /**
         * 生成标签和控制按钮的配置信息
         * @returns {JSON} 返回配置信息
         * @private
         */
        _createConfig4TabControl: function () {
            var self = this, opts = this.options;
            this.tabsContent = $('<div/>').addClass(opts.baseCls + '-tabscontent')
                .addClass(opts.baseCls + '-tabscontent-' + opts.tabPosition);
            var items = [
                {
                    region: "center",
                    el: $('<div/>').append(this.tabsContent)
                }
            ];
            //不需要tab控制按钮就不生成
            if (!this.options.noControl) {
                items.unshift({
                    region: "west",
                    el: {
                        type: 'horizontal',
                        widgetName: 'controlbuttons',
                        baseCls: 'fr-tabpane-controlbuttons',
                        alignment: 'center',
                        hgap: 3,
                        vgap: 2,
                        items: [
                            {
                                el: this._createTabControlBtn('arrow1', function () {
                                    if(self.isMoving){
                                        return;
                                    }
                                    self._moveViewToPos('start'); //移动到第一个tab
                                }),
                                width: 13
                            },
                            {
                                el: this._createTabControlBtn('arrow2', function () {
                                    if(self.isMoving){
                                        return;
                                    }
                                    var distance = self.stepDis;
                                    var realDis = self.tabsContent.offset().left - self.tabsWrap.offset().left;
                                    distance = Math.min(distance,realDis);
                                    self._moveViewToPos(distance);
                                }),
                                width: 13
                            },
                            {
                                el: this._createTabControlBtn('arrow3', function () {
                                    if(self.isMoving){
                                        return;
                                    }
                                    var distance = self.stepDis;
                                    var realDis = self.tabsWrap.offset().left + self.wrapWidth
                                        - self.tabsContent.offset().left - self.tabsContent.width();
                                    distance = Math.min(distance,realDis);
                                    distance = distance < 0?0:distance;
                                    self._moveViewToPos(- distance);
                                }),
                                width: 13
                            },
                            {
                                el: this._createTabControlBtn('arrow4', function () {
                                    if(self.isMoving){
                                        return;
                                    }
                                    self._moveViewToPos('end'); //移动到最后一个tab
                                }),
                                width: 13
                            }
                        ]
                    },
                    width: 72
                });
            }
            var tabControlConfig = {
                type: "border",
                items: items
            };
            return tabControlConfig;
        },

        /**
         * 生成tab控制按钮
         * @param {String} name 样式类名
         * @param {Function} handler 点击事件
         * @returns {jQuery} 返回按钮的DOM对象
         * @private
         */
        _createTabControlBtn: function (name, handler) {
            var iconbtn = new FR.IconButton({
                type: "iconbutton",
                baseClass: 'fr-edit-sheetcontrol-icon-box',
                handler: handler
            });
            $('<div>').addClass('fr-edit-sheetcontrol-icon-' + name).appendTo(iconbtn.element);
            return iconbtn.element;
        },

        /**
         * 初始化所有的tab
         * @private
         */
        _initTabs: function () {
            var opts = this.options;
            this.tabBtns = [];
            //用来装载所有的tab标签并用于平移
            this.tabsWrap = $('<ul/>').addClass(opts.baseCls + '-tabswrap').appendTo(this.tabsContent);
            if (!opts.items) {
                return;
            }
            if (!opts.tabs) {
                opts.tabs = [];
            }
            for (var i = 0; i < opts.items.length; i++) {
                this._addTabContent(opts.items[i]);
                this._addTabTag(i, opts.items[i]);
            }
        },

        /**
         * 添加一个tab的内容
         * @param {jQuery} item tab对象
         * @private
         */
        _addTabContent: function (item) {
            var tabs = this.options.tabs;
            if (item.tabContent) {
                var widget = FR.createWidget(item.tabContent);
                widget.element.appendTo(this.tabPaneContent);
                item.content = widget.element;
            } else {
                var content = $('<div/>').addClass("html-content").appendTo(this.tabPaneContent);
                item.content = content;
            }
            item.content.hide();
            tabs.push(item);
        },

        /**
         * 添加一个tab的标签
         * @param {Number} index 位置索引
         * @param {jQuery} item tab对象
         * @private
         */
        _addTabTag: function (index, item) {
            var self = this, items = this.options.items;
            //生成一个tab标签
            var config = {
                tabPane: this,
                name: item.title,
                index: index,
                isFirst: index === 0,
                isLast: index === items.length - 1,
                renderEl: $('<li/>').appendTo(this.tabsWrap),
                tabBtns: this.tabBtns,
                handler: function () {
                    if (self.activeTabIndex >= 0) {
                        self.options.tabs[self.activeTabIndex].content.hide();
                    }
                    self.activeTabIndex = index;
                    if (self.options.tabs[index].content) {
                        self.options.tabs[index].content.show();
                    }
                    self.showSheetContent(self.activeTabIndex);
                    self._moveViewToShow(self.activeTabIndex);
                }
            };
            var sheetBtn = new FR.SheetButton(config);
            this.tabBtns.push(sheetBtn);
            this.wrapWidth += sheetBtn.getWidth();
            this.stepDis = this.wrapWidth/this.tabBtns.length; //取平均数作为固定移动步长
        },

        /**
         * 使指定位置的tab移动到可完整显示
         * @param {Number} tabIndex tab的位置索引
         * @private
         */
        _moveViewToShow: function (tabIndex) {
            var tabObj = this.tabBtns[tabIndex].element; //当前选中DOM
            var view = this.tabsWrap;  //滑动主体DOM
            var bounds = this.tabsContent; //外边界DOM
            var boundsLeft = bounds.offset().left;
            var boundsRight = boundsLeft + bounds.width();
            var viewLeft = view.offset().left;
            var viewRight = viewLeft + this.wrapWidth;
            var tabLeft = tabObj.offset().left;
            var tabRight = tabLeft + tabObj.width();
            var dis = tabObj.width(); //理应移动的距离
            var realDis = 0; //实际可移动的距离
            if (tabLeft < boundsLeft) {
                //左出界,右移 +
                realDis = boundsLeft - viewLeft;
                realDis = Math.min(realDis, dis);
            } else if (tabRight > boundsRight) {
                //右出界,左移 -
                realDis = boundsRight - viewRight;
                realDis = Math.max(realDis, -dis);
            } else {
                return;
            }
            this._moveViewToPos(realDis);
        },

        /**
         * 所有tab移动一段距离或移动到某个位置
         * @param {Number/String/'start'/'end'} distance 距离,'start'表示移动到第一个tab标签,'end'表示移动到最后一个tab标签
         * @private
         */
        _moveViewToPos: function (distance) {
            var self = this;
            this.isMoving = true;
            if (distance == 'start') {
                //表示回到原点
                this.tabsWrap.animate({
                    'left': '0'
                }, 'fast', function(){
                    self.isMoving = false;
                });
            } else if (distance == 'end') {
                var pos = this.tabsContent.width() - this.wrapWidth;
                if(pos > 0){
                    pos = 0;
                }
                this.tabsWrap.animate({
                    'left': pos
                }, 'fast', function(){
                    self.isMoving = false;
                });
            }
            else {
                this.tabsWrap.animate({
                    'left': '+=' + distance
                }, 'fast', function(){
                    self.isMoving = false;
                });
            }
        },
        /**
         * 显示指定位置索引的sheet内容
         * @param {Number} position 位置索引
         */
        showSheetContent: function (position) {
            this.fireEvent(FR.Events.TABCHANGESTART, this, position);
            this.fireEvent(FR.Events.TABCHANGE, this, position);
            this.fireEvent(FR.Events.SCROLLCHANGE, this, position);
        },

        doResize: function (give) {
            this.element.css({
                width: give.width,
                height: give.height
            });
        },

        /**
         * 选中指定位置索引的Tab,并显示Tab内容
         * @param {Number} index 位置索引
         * @return {Boolean} 返回选择是否成功
         */
        selectTabAt: function(index){
            if(index >= 0){
                this.tabBtns[index].setSelected();
                return true;
            }
            return false;
        },

        /**
         * 获取指定位置索引的Tab的内容
         * @param {Number} index 要获取的tab的索引
         * @return {JSON} 返回Tab对象,其content属性表示Tab内容的DOM对象
         */
        getTabByIndex: function(index){
            if(index >=0){
                return this.options.tabs[index];
            }
            return {};
        },

        /**
         * 获取指定Tab标签名的Tab内容
         * @param {String} name Tab标签名
         * @return {JSON} 返回第一个与所给标签名匹配的Tab对象
         */
        getTabByName: function(name){
            if(!FR.isEmpty(name)){
                for(var i = 0;i< this.tabBtns.length;i++){
                    if(this.tabBtns[i].name == name){
                        return this.options.tabs[i];
                    }
                }
            }
            return {};
        },

        /**
         * 获取当前所选中的tab的位置索引
         * @returns {Number} 返回位置索引
         */
        getSelectedIndex: function(){
            return this.activeTabIndex;
        }

    });
    $.shortcut("tabpane", FR.TabPane);

    /**
     * Tab按钮
     * @class FR.SheetButton
     * @extends FR.Widget
     * @private
     */
    FR.SheetButton = FR.extend(FR.Widget, /**@class FR.SheetButton*/{

        _defaultConfig: function () {
            return $.extend(FR.SheetButton.superclass._defaultConfig.apply(), {
                tabPane: null, //传递进来的FR.TabPane对象
                tabBtns: [],  //传递进来的tabBtns属性
                isFirst: false,  //是否是第一个标签
                isLast: false,  //是否是最后一个标签
                index: 0, //标签位置索引
                minWidth: 60, //最小宽度
                handler: null,
                disabled: false,
                name: '',
                containerCls4btn: "fr-sheetbutton-container",
                intersectCls4btn: "fr-sheetbutton-intersect",
                firstPartCls4btn: "fr-sheetbutton-firstpart",
                middlePartCls4btn: "fr-sheetbutton-middlepart",
                thirdPartCls4btn: "fr-sheetbutton-thirdpart",
                endPartCls4btn: "fr-sheetbutton-endpart",
                button_class_prefix: "fr-sheet-icon-",
                button_closebtn_class: "fr-sheetbutton-closebutton"
            });
        },

        _init: function () {
            FR.SheetButton.superclass._init.apply(this, arguments);
            var o = this.options, self = this;
            var tabPos = o.tabPane.options.tabPosition;
            if (tabPos == 'top') {
                o.firstPartCls4btn += '-' + tabPos;
                o.middlePartCls4btn += '-' + tabPos;
                o.thirdPartCls4btn += '-' + tabPos;
                o.endPartCls4btn += '-' + tabPos;
            }
            this.element.addClass(o.containerCls4btn).attr("title", o.name);
            this._createTabBtnByName(o.name);
            //点击事件
            if ($.isFunction(o.handler)) {
                this.on(FR.Events.CLICK, o.handler.createDelegate(o.scope || this));
            }
            this.element.click(function () {
                if (self.isEnabled()) {
                    self.setSelected();
                }
            });
            this.width = this.element.width();
            this.fireEvent(FR.Events.AFTERINIT);
        },

        /**
         * 生成标签按钮
         * @param {String} name tab标签的文字内容
         * @private
         */
        _createTabBtnByName: function (name) {
            var o = this.options;
            var li = this.element;
            if (this.options.isFirst) {
                li.head = $('<span/>').addClass(o.firstPartCls4btn).appendTo(li); //首
            }
            li.middle = $('<span/>').addClass(o.middlePartCls4btn).text(name).appendTo(li); //中部-文字
            //设置文字部分最小宽度
            if(li.middle.width() < o.minWidth){
                li.middle.width(o.minWidth);
            }
            if (!o.isLast) {
                li.end = $('<span/>').addClass(o.thirdPartCls4btn).appendTo(li);  //尾-交叉,非最后tab
            } else {
                li.end = $('<span/>').addClass(o.endPartCls4btn).appendTo(li); //尾-最后一个tab
            }
        },

        /**
         * 获取当前sheet总宽度
         * @returns {Number} 返回当前sheet总宽度
         */
        getWidth: function(){
            return this.width;
        },
        /**
         * 选中当前tab
         */
        setSelected: function () {
            var o = this.options;
            if (this.isActive()) {
                return;
            }
            this.setActiveState(true);
            var activeIndex = o.tabPane.activeTabIndex;
            if (activeIndex >= 0 && activeIndex !== o.index) {
                o.tabBtns[activeIndex].setActiveState(false);
            }
            this.fireEvent(FR.Events.CLICK);
        },

        /**
         * 设置该tab的激活状态
         * @param {Boolean} state 是否激活
         */
        setActiveState: function (state) {
            var o = this.options;
            this.isActiveState = state;
            if (state) {
                this.element.addClass(o.containerCls4btn + "-active");
                if (!o.isFirst) {
                    o.tabBtns[o.index - 1].element.addClass(o.intersectCls4btn);
                }
            } else {
                this.element.removeClass(o.containerCls4btn + "-active");
                if (!o.isFirst) {
                    o.tabBtns[o.index - 1].element.removeClass(o.intersectCls4btn);
                }
            }
        },


        /**
         * 设置该tab的校验状态
         * @param {Boolean} isValid 是否符合校验规则
         */
        setValidState: function(isValid){
            var $dom = this.element, opts = this.options;
            var curIdx = opts.index;
            if(!isValid){
                if(opts.isFirst){
                    $dom.head.switchClass(opts.firstPartCls4btn + '-invalidate');
                }else{
                    var pre = opts.tabPane.tabBtns[curIdx - 1];
                    if(pre.isValid()){
                        pre.element.end.switchClass(opts.thirdPartCls4btn + '-invalidate-style3');
                    }else{
                        pre.element.end.switchClass(opts.thirdPartCls4btn + '-invalidate-style2');
                    }
                }
                $dom.middle.switchClass(opts.middlePartCls4btn + '-invalidate');
                if(opts.isLast){
                    $dom.end.switchClass(opts.endPartCls4btn + '-invalidate');
                }else{
                    if(opts.tabPane.tabBtns[curIdx + 1].isValid()){
                        $dom.end.switchClass(opts.thirdPartCls4btn + '-invalidate');
                    }else if(opts.tabPane.tabBtns[curIdx - 1].isValid()){
                        $dom.end.switchClass(opts.thirdPartCls4btn + '-invalidate-style2');
                    }
                }
            }else{
                if(opts.isFirst){
                    $dom.head.switchClass(opts.firstPartCls4btn);
                }else{
                    var pre = opts.tabPane.tabBtns[curIdx - 1];
                    if(pre.isValid()){
                        pre.element.end.switchClass(opts.thirdPartCls4btn);
                    }else{
                        pre.element.end.switchClass(opts.thirdPartCls4btn + '-invalidate');
                    }
                }
                $dom.middle.switchClass(opts.middlePartCls4btn);
                if(opts.isLast){
                    $dom.end.switchClass(opts.endPartCls4btn);
                }else{
                    if(opts.tabPane.tabBtns[curIdx + 1].isValid()){
                        $dom.end.switchClass(opts.thirdPartCls4btn);
                    }else{
                        $dom.end.switchClass(opts.thirdPartCls4btn + '-invalidate-style3');
                    }
                }
            }
            this.isValidState = isValid;
        },

        /**
         * 判断该tab是否符合校验
         * @returns {Boolean} 返回当前tab是否符合校验
         */
        isValid: function(){
            return this.isValidState !== false;
        },

        /**
         * 判断该tab是否为激活状态
         * @returns {Boolean} 返回当前tab是否为激活状态
         */
        isActive: function () {
            return this.isActiveState === true;
        },

        destroy: function () {
            this.element.empty();
        }
    });
    $.shortcut("sheetbutton", FR.SheetButton);
})(jQuery);