/*
 * Copyright (c) 2001-2014,FineReport Inc, All Rights Reserved.
 */


/**
 * 开关控件
 *
 *      @example
 *      var $div = $('<div>').appendTo('body');
 *      var button = new FS.SwitchButton({
 *              renderEl : $div,
 *              value : true
 *      });
 *
 * @class FS.SwitchButton
 * @extends FR.Widget
 */
FS.SwitchButton = FR.extend(FR.Widget, {
    _defaultConfig: function () {
        return $.extend(FS.SwitchButton.superclass._defaultConfig.call(), {
            width: 128,
            height: 25,
            value: false,
            hoverCls: "fs_siwthbutton_hover",
            onTurnOn: function(){
                return true;
            },
            onTurnOff: function(){
                return true;
            }
        });
    },

    _init: function () {
        FS.SwitchButton.superclass._init.apply(this, arguments);
        var self = this;
        var o = this.options;
        var buttonBody = $("<div/>").attr("id", "fs_switchbutton_body").appendTo(this.element);
        var leftPart = $("<div/>").attr("id", "fs_switchbutton_left").appendTo(buttonBody)
            .hover(function () {
                if (!self.options.value) {
                    $(buttonBody).addClass(o.hoverCls);
                }
            },function () {
                $(buttonBody).removeClass(o.hoverCls);
            }).click(function () {
                $(buttonBody).removeClass(o.hoverCls);
                if(FR.applyFunc(self, o.onTurnOn, [], false) !== false){
                    self.setValue(true);
                }
            });
        var rightPart = $("<div/>").attr("id", "fs_switchbutton_right").appendTo(buttonBody)
            .hover(function () {
                if (self.options.value) {
                    $(buttonBody).addClass(o.hoverCls);
                }
            },function () {
                $(buttonBody).removeClass(o.hoverCls);
            }).click(function () {
                $(buttonBody).removeClass(o.hoverCls);
                if(FR.applyFunc(self, o.onTurnOff, [], false) !== false){
                    self.setValue(false);
                }
            });
        this.textAreaL = $("<div/>").addClass("fs_switchbutton_textarea").appendTo(leftPart);
        this.textAreaR = $("<div/>").addClass("fs_switchbutton_textarea").appendTo(rightPart);
        this.setValue(this.options.value);
    },

    /**
     * 更新按钮状态
     * @private
     */
    _refreshButton: function () {
        if (this.options.value) {
            //开启状态
            this.element.removeClass("fs_switchbutton_off");
            this.element.addClass("fs_switchbutton_on");
            this.textAreaL.text(FR.i18nText("FS-Generic-Simple_Opened"));
            this.textAreaR.text(FR.i18nText("FS-Generic-Turn_Off"));
        } else {
            //关闭状态
            this.element.removeClass("fs_switchbutton_on");
            this.element.addClass("fs_switchbutton_off");
            this.textAreaL.text(FR.i18nText("FS-Generic-Turn_On"));
            this.textAreaR.text(FR.i18nText("FS-Generic-Simple_Closed"));
        }
    },

    /**
     * 设置按钮开启/关闭
     */
    setValue: function (value) {
        var o = this.options;
        o.value = value;
        this._refreshButton();
        if (arguments[1] === true) {
            if (value) {
                if ($.isFunction(o.onTurnOn)) {
                    o.onTurnOn.call();
                }
            } else {
                if ($.isFunction(o.onTurnOff)) {
                    o.onTurnOff.call();
                }
            }
        }
    },

    /**
     * 获取按钮是否选中
     */
    getValue: function () {
        return this.options.value;
    }
});
$.shortcut("switch", FS.SwitchButton);

/**
 * 决策平台中所是用的Tab控件,用于展示多标签页
 *
 * @class FS.LTabPane
 * @extends FR.Widget
 */
FS.LTabPane = FR.extend(FR.Widget, {
    _defaultConfig: function () {
        return $.extend(FS.LTabPane.superclass._defaultConfig.call(), {
            height: 500,
            width: 400,
            headerCls : 'fs_ltabpane_tabs',
            baseCls: 'fs_ltabpane',
            tabsCls: 'fs_ltabpane_tabs_general',//选项卡标签类,用于管理标签普通样式
            selectedTabCls: 'fs_ltabpane_tabs_selected',//被选中的标签类
            hoverTabCls: 'fs_ltabpane_tabs_hover',//悬浮在选项卡标签上的效果类
            unselectedContentCls: 'fs_ltabpane_content_unselected',//隐藏的选项卡内容类
            selectedContentCls: 'fs_ltabpane_content_selected',//显示的选项卡内容类
            defaultIdx: 0,//初始化时,默认选中的标签,默认为第一个标签
            type: "ltabpanel",
            style: null,
            items: [],
            vgap: 25, //整个标签部分与内容部分的上下间距
            initAfterActions: [],  //标签第一次被点击后才开始加载内部元素,首次加载后事件
            initAfterAction : null, //标签第一个被点击时的事件,参数为点击的tab索引
            opAfterActions: [],  //标签每一次被点击后的操作
            tabLeft : 21,    //标签的left属性,21为第一个标签的left
            tabDistance : 35,
            marginLeft: 20
        });
    },
    _init: function () {
        FS.LTabPane.superclass._init.apply(this, arguments);
        var o = this.options;
        var self = this;
        if (o.widgetName) {
            this.element.attr("widgetName", o.widgetName);
        }
        this.element.addClass(o.baseCls);
        var n = o.items.length;
        //标签部分
        if (n > 0) {
            this.tabs = $('<div/>').addClass(o.headerCls);
            this.tabs.appendTo(this.element);
        }
        this.tabs.css('margin-bottom', o.vgap + 'px');
        //内容部分
        for (var i = 0; i < n; i++) {
            var tabDiv = this._createTabDiv(i);
            //注册点击事件
            tabDiv.on('click', function () {
                self.tabDivOnClick(this);
            });
            //注册悬浮事件
            tabDiv.on('mouseover', function () {
                //被选中的标签无hover效果
                if ($(this).hasClass(o.selectedTabCls)) {
                    return;
                }
                $(this).addClass(o.hoverTabCls);
            });
            //注册移出事件
            tabDiv.on('mouseout', function () {
                $(this).removeClass(o.hoverTabCls);
            });
            tabDiv.appendTo(this.tabs);
            var tabOuterWidth = tabDiv.outerWidth();
            if(o.items[i].width) {
                tabOuterWidth = o.items[i].width;
            }
            o.tabLeft += tabOuterWidth + o.tabDistance;
        }
        this.tabs.find('.' + o.tabsCls + '[tabindex=' + o.defaultIdx + ']').trigger('click');
    },

    tabDivOnClick : function(tabElement) {
        //点击后标签切换
        var o = this.options;
        if ($(tabElement).hasClass(o.selectedTabCls)) {
            return false;
        }
        this.removeSelected();
        var tabindex = $(tabElement).attr("tabindex");
        $(tabElement).addClass(o.selectedTabCls);
        //点击后内容切换
        this._contentSwitchTo(tabindex);
        return true;
    },

    _createTabDiv : function(index) {
        var o = this.options;
        return $('<div/>').attr('tabindex', index)
            .attr('unselectable', 'on')
            .css({left: o.tabLeft})
            .addClass(o.tabsCls).text(o.items[index].title);
    },

    removeSelected : function() {
        var o = this.options;
        var $selected = this.tabs.find('.' + o.selectedTabCls);
        if ($selected.length > 0) {
            $selected.css({left: $selected.get(0).oldValue});
            $selected.removeClass(o.selectedTabCls);
        }
    },

    getSelectedIndex : function() {
        var o = this.options;
        var selected = this.tabs.find('.' + o.selectedTabCls);
        if (selected.length > 0) {
            return parseInt(selected.attr("tabindex"));
        }
        return null;
    },

    /**
     * 点击标签后内容进行切换
     * @param idx : tab的下标
     */
    _contentSwitchTo: function (idx) {
        var o = this.options;
        if (!this._isLoaded(idx) || this.options.loadEveryTime === true) {
            this.element.children('div[contentindex=' + idx + ']').remove();
            var contentPane = $('<div/>')
                .attr('contentindex', idx)
                .css({'margin-left': o.marginLeft})
                .addClass(o.selectedContentCls)
                .appendTo(this.element);
            if (o.items[idx].content instanceof $) {
                o.items[idx].content.appendTo(contentPane);
            } else {
                o.items[idx].content.renderEl = contentPane;
                o.items[idx].content.style = o.style;   //往下传递style属性,以后可以用来统一样式
                this.container = FR.createWidget($.extend(o.items[idx].content, {
                    resultWidgets: this.options.resultWidgets
                }));
            }
            if ($.isFunction(o.initAfterActions[idx])) {
                o.initAfterActions[idx].apply(this);
            }
            if ($.isFunction(o.initAfterAction)) {
                o.initAfterAction.apply(this, [idx]);
            }
        }
        if ($.isFunction(o.opAfterActions[idx])) {
            o.opAfterActions[idx].apply(this);
        }
    },

    /**
     * 判断tab是否已经被加载过了
     * @param idx : tab的下标
     * @return boolean
     */
    _isLoaded: function (idx) {
        var o = this.options;
        var content = this.element.children('div[contentindex=' + idx + ']');
        //隐藏
        this.element.children('.' + o.selectedContentCls).addClass(o.unselectedContentCls).removeClass(o.selectedContentCls);
        //如果不是第一次加载,则直接显示;否则开始动态加载内容
        if (content.length !== 0) {
            //显示
            content.removeClass(o.unselectedContentCls).addClass(o.selectedContentCls);
            return true;
        }
        return false;
    }
});
$.shortcut("ltab", FS.LTabPane);

/**
 * 决策平台中各个标签页内部用到的Tab控件
 * @class FS.InsideTabPane
 * @extends FS.LTabPane
 */
FS.InsideTabPane = FR.extend(FS.LTabPane, {
    _defaultConfig : function() {
        return $.extend(FS.InsideTabPane.superclass._defaultConfig.call(), {
            baseCls : 'fs_inside_tabpane',
            headerCls : 'fs_inside_tab_header',
            tabsCls : 'fs_inside_tab',
            selectedTabCls : 'fs_inside_tab_selected',
            selectedContentCls : 'fs_inside_content_selected',
            tabNoRightBorderCls : 'fs_inside_tab_no_right_border',
            tabNoLeftBorderCls : 'fs_inside_tab_no_left_border',
            tabLeft : 0,    //标签的left属性,21为第一个标签的left
            tabDistance : 0,
            vgap : 0,
            marginLeft : 0,
            elementMarginLeft : 0
        })
    },

    _init : function() {
        FS.InsideTabPane.superclass._init.call(this, arguments);
        if(this.options.elementMarginLeft) {
            this.element.css('marginLeft', this.options.elementMarginLeft);
        }
    },

    tabDivOnClick : function(tabElement) {
        var o = this.options;
        var tabindex = parseInt($(tabElement).attr("tabindex"));
        if(o.items[tabindex].keepActive === true) {
            return ;
        }
        var activeChanged = FS.InsideTabPane.superclass.tabDivOnClick.call(this, arguments);
        if(!activeChanged) {
            return ;
        }
        if (o.afterTabClick && $.isFunction(o.afterTabClick[tabindex])) {
            o.afterTabClick[tabindex].apply(this);
        }
        var nextTab = o.items[tabindex + 1];
        var keepActiveTab;
        if(nextTab && nextTab.keepActive === true) {
            //下一个如果是一直激活状态的话,中间的border去掉。
            $(tabElement).addClass(o.tabNoRightBorderCls);
            keepActiveTab = this.tabs.find('.' + o.tabsCls + '[tabindex=' + (tabindex+1) + ']');
            keepActiveTab.addClass(o.tabNoLeftBorderCls);
            this.fixTabWidth(keepActiveTab, false, true);
        } else if(nextTab) {
            //先简单处理,目前使用的一直保持激活态的tab都在最右
            keepActiveTab = this.tabs.find('.' + o.tabNoLeftBorderCls);
            if(keepActiveTab.length > 0) {
                this.fixTabWidth(keepActiveTab, true, true);
            }
            this.tabs.find('.' + o.tabsCls).removeClass(o.tabNoRightBorderCls);
            this.tabs.find('.' + o.tabsCls).removeClass(o.tabNoLeftBorderCls);
        }
        this.fixTabWidth($(tabElement), true);
    },

    fixTabWidth : function(element, isGetActive, isKeepActive) {
        var o = this.options;
        var width = element.width();
        if(isGetActive) {
            //变成激活态的tab,宽度-2/-1
            if(isKeepActive || element.hasClass(o.tabNoRightBorderCls) || element.hasClass(o.tabNoRightBorderCls)) {
                element.width(width - 1);
            } else {
                element.width(width - 2);
            }
        } else {
            //失去激活态的tab,宽度+2/+1
            if(isKeepActive || element.hasClass(o.tabNoRightBorderCls) || element.hasClass(o.tabNoRightBorderCls)) {
                element.width(width + 1);
            } else {
                element.width(width + 2);
            }
        }
    },

    _createTabDiv : function(index) {
        var o = this.options;
        var keepActive = this.isTabKeepActive(index);
        var tabDiv = $("<div/>").attr('tabindex', index)
            .attr('unselectable', 'on').attr('keepActive', keepActive)
            .css({left: o.tabLeft}).addClass(o.tabsCls);
        if(o.items[index].title instanceof $) {
            tabDiv.append(o.items[index].title);
        } else {
            tabDiv.text(o.items[index].title);
        }
        if(keepActive) {
            tabDiv.addClass(o.selectedTabCls);
        }
        if(o.items[index].width) {
            //放到布局里,布局没在页面呈现前就开始初始化里面的控件了,outerWidth根本就取不到啊... 先这么处理了。
            tabDiv.width(o.items[index].width - (o.items[index].borderWidth ? o.items[index].borderWidth : 0));
        }
        return tabDiv;
    },

    removeSelected : function() {
        var o = this.options;
        var $selected = this.tabs.find('.' + o.selectedTabCls);
        if ($selected.length > 0) {
            for(var i = 0, len = $selected.length; i < len; i ++) {
                var selectedElement = $($selected.get(i));
                selectedElement.css({left: $selected.get(i).oldValue});
                if(selectedElement.attr("keepActive") != "true") {
                    selectedElement.removeClass(o.selectedTabCls);
                    this.fixTabWidth(selectedElement, false);
                }
            }
        }
    },

    isTabKeepActive : function(index) {
        return this.options.items[index].keepActive === true;
    },

    getActiveIndex: function() {
        var o = this.options;
        return parseInt(this.tabs.find('.' + o.selectedTabCls).attr("tabindex"));
    },

    getActiveTab: function() {
        var o = this.options;
        return this.element.find('.' + o.selectedContentCls);
    }
});
$.shortcut("insidetab", FS.InsideTabPane);

/**
 * 下拉设置面板
 * @class FS.FloatPane
 * @extends FR.Widget
 */
FS.FloatPane = FR.extend(FR.Widget, {
    _defaultConfig: function () {
        return $.extend(FS.FloatPane.superclass._defaultConfig.apply(this, arguments), {
            baseCls: 'fs-floatpane',
            width: 815,
            anchor: null,
            confirm: true,
            contentWidget: null,
            contentHeight: 260
        });
    },
    _init: function () {
        FS.FloatPane.superclass._init.apply(this, arguments);
        var o = this.options, self = this;
        this.element.appendTo(o.anchor);
        this.$content = $('<div class="fs-floatpane-content"/>')
            .css({
                height: o.contentHeight,
                width: o.width - 10
            }).hide().appendTo(this.element);
        var widget = FR.createWidget($.extend(o.contentWidget, {
            renderEl: $('<div/>').appendTo(this.$content),
            resultWidgets: o.resultWidgets
        }));
        var settingsMarginLeft = parseInt(FR.i18nText("FS-System-Settings_Button_Margin_Left") || 55);
        var settingsButtonWidth = parseInt(FR.i18nText("FS-System-Settings_Button_Width") || 50);
        var $btn = $('<div class="fs-floatpane-btn"/>').css({
            'margin-left': o.width - settingsMarginLeft,
            width : settingsButtonWidth
        }).click(
            function(){
                self.doSlide();
            }
        ).appendTo(this.element);
        this.$icon = $('<a class="fs-floatpane-icon fs-floatpane-down"/>').text(FR.i18nText("FS-System-Simple_Settings")).appendTo($btn);
    },
    doSlide: function(){
        this.$icon.switchClass("fs-floatpane-down", "fs-floatpane-up");
        this.$content.slideToggle('fast');
    }
});
$.shortcut('floatpane', FS.FloatPane);

/**
 * 下拉展开控件
 *
 *      @example
 *      var $div = $('<div style="position:absolute;width:400px;height:400px">').appendTo('body');
 *      var accordion = new FS.Accordion({
 *          renderEl : $div,
 *          items : [
 *              {
 *                  menu : '选项一',
 *                  content : {
 *                      type : 'llabel',
 *                      value : '选项一的内容'
 *                  }
 *              },
 *              {
 *                  menu : '选项二',
 *                  content : {
 *                      type : 'llabel',
 *                      value : '选项二的内容'
 *                  }
 *              }
 *          ]
 *      });
 *
 * @class FS.Accordion
 * @extends FR.Widget
 */
FS.Accordion = FR.extend(FR.Widget, {
    _defaultConfig: function () {
        return $.extend(FS.Accordion.superclass._defaultConfig.apply(this, arguments), {
            baseCls: 'fs-accordion',
            width: 731,
            items: []
        });
    },
    _init: function () {
        FS.Accordion.superclass._init.apply(this, arguments);
        var o = this.options;
        for(var i= 0, len = o.items.length; i < len; i++){
            var menu = o.items[i].menu;
            var content = o.items[i].content;
            var $menu = $('<div/>').addClass('fs-accordion-menu').click(
                function(){
                    $(this).children('div').toggleClass('fs-accordion-icon-fold');
                    $(this).next().slideToggle('fast');
                }
            ).appendTo(this.element);
            $('<div/>').addClass('fs-accordion-icon-unfold').appendTo($menu);
            $('<span/>').text(menu).appendTo($menu);
            var $context = $('<div/>').addClass('fs-accordion-content').hide().appendTo(this.element);
            var widget = FR.createWidget($.extend(content, {
                resultWidgets: o.resultWidgets
            }));
            widget.element.appendTo($context);
        }
    }
});
$.shortcut('accordion', FS.Accordion);

/**
 * 表格容器面板,主要为了解决是用TableLayout效率问题
 *
 *      @example
 *      var $div = $('<div style="position:absolute;width:400px;height:400px">').appendTo('body');
 *      var table = new FS.TablePane({
 *          renderEl : $div,
 *          rowSize : [30, 30],
 *          colSize : [120, 'fill'],
 *          items : [
 *              [{type : 'llabel', value : '第一行'}, {type : 'text', value : '用户名1'}],
 *              [{type : 'llabel', value : '第二行'}, {type : 'text', value : '用户名2'}],
 *              [{type : 'llabel', value : '第三行'}, {type : 'text', value : '用户名3'}]
 *          ]
 *      });
 *
 * @class FS.TablePane
 * @extends FR.Widget
 */
FS.TablePane = FR.extend(FR.Widget, {
    _defaultConfig: function () {
        return $.extend(FS.TablePane.superclass._defaultConfig.apply(this, arguments), {
            rowSize: [],
            colSize: [],
            hgap: 0,
            vgap: 0,
            items: []
        });
    },
    _init: function () {
        FS.TablePane.superclass._init.apply(this, arguments);
        this.$rows = [];
        var  o = this.options;
        for(var i = 0, size = o.rowSize.length; i<size;i++){
            var $row = $('<div class="fr-tablepane-row"/>').appendTo(this.element);
            for(var j = 0, len = o.colSize.length; j<len; j++){
                var $cell = $('<div class="fr-tablepane-item"/>').appendTo($row);
                var item = o.items[i][j];
                if(!item){
                    continue;
                }
                if(!item.type){
                    $cell.css({width: o.colSize[j], height: o.rowSize[i]}).append(item);
                }else{
                    var widget = FR.createWidget($.extend(item, {
                        resultWidgets: this.options.resultWidgets,
                        width: item.width?item.width:o.colSize[j],
                        height: item.height?item.height:o.rowSize[i],
                        renderEl: $cell
                    }));
                }
                if(i>0){
                    $cell.css({'margin-left': o.hgap});
                }
            }
            if(i>0){
                $row.css({'margin-top': o.vgap});
            }
            this.$rows.push($row);
        }
    },
    /**
     * 获取指定行的dom元素
     * @param index 行索引,从0开始
     */
    getRowAt: function(index){
        return this.$rows[index];
    },

    /**
     * 设置指定的行的可见性
     * @param {Array} rowIdxs 需要改变可见性的行编号组成的数组
     * @param {Boolean} isVisible 是否可见
     */
    setRowVisible: function(rowIdxs, isVisible){
        for(var i= 0,len = rowIdxs.length;i<len;i++){
            if(isVisible){
                this.$rows[rowIdxs[i]].show();
            }else{
                this.$rows[rowIdxs[i]].hide();
            }
        }
    }
});
$.shortcut('tablepane', FS.TablePane);

/**
 * 决策平台下可对单独选项禁用选取的多选组合框
 *
 *      @example
 *      var $div = $('<div style="position:absolute;width:400px;height:400px">').appendTo('body');
 *      var button = new FS.FSCheckBoxGroup({
 *              renderEl : $div,
 *              items : [{text : "第一", value : '0', text : "第二", value : '1'}]
 *      });
 *
 * @class FS.FSCheckBoxGroup
 * @extends FR.CheckBoxGroup
 */
FS.FSCheckBoxGroup = FR.extend(FR.CheckBoxGroup, {
    _init: function () {
        FS.FSCheckBoxGroup.superclass._init.apply(this, arguments);
    },

    _setItems: function (items) {
        var records = items || [];
        var self = this;
        $.each(records, function (idx, it) {
            if (self.options.adaptive) {
                var outter = $("<span></span>")
                    .addClass(self.sbox_class)
                    .appendTo(self.$container);
            } else {
                var outter = $("<span/>").addClass(self.sbox_class);
                var gridElement = {
                    column: idx % self.gridConfig.columns,
                    row: Math.floor(idx / self.gridConfig.columns),
                    el: outter
                };
                self.gridConfig.items.push(gridElement);
            }
            self.buttonArray[idx] = new FR.CheckBox({
                renderEl: $("<div/>").appendTo(outter),
                disabled: self.options.disabled || it.options.data.disabled,
                text: it.getShowValue(),
                fieldValue: it.getValue(),
                sessionID: self.options.sessionID,
                widgetName: self.options.widgetName,
                fontSize: self.options.fontSize
            });
            self.buttonArray[idx].on(FR.Events.BEFORESTATECHANGE,
                function () {
                    self.fireEvent(FR.Events.BEFORESTATECHANGE);
                });
            self.buttonArray[idx].on(FR.Events.STATECHANGE, function () {
                self.fireEvent(FR.Events.STATECHANGE, idx, this
                    .selected());
                if (self.options.chooseAll) {
                    var selectedItems = $('.fr-checkbox-checkon', self.$container);
                    var checkonCount = selectedItems.length - self.innerCheckBox.isSelected();
                    if (checkonCount === self.buttonArray.length) {
                        self.innerCheckBox.setSelectedWithoutEvent(true);
                    } else {
                        self.innerCheckBox.setSelectedWithoutEvent(false);
                    }
                }
                self.fireEvent(FR.Events.AFTEREDIT);
            });
        });
        this._checkChooseAll();
    }
});
$.shortcut('fscheckboxgroup', FS.FSCheckBoxGroup);


/**
 * 决策平台管理页面经常需要使用的标签,用于显示一般的文字
 *
 *      @example
 *      var $div = $('<div>').appendTo('body');
 *      var button = new FS.LLabel({
 *              renderEl : $div,
 *              value : "我是一个标签"
 *      });
 *
 * @class FS.LLabel
 * @extends FR.Label
 */
FS.LLabel = FR.extend(FR.Label, {
    _defaultConfig: function () {
        return $.extend(FS.LLabel.superclass._defaultConfig.call(), {
            levelStyle: 2,   //默认为二级标题,因为在FS中使用更为频繁
            firstStyleWidth: 730, //一级标题下划线长度
            verticalcenter: true,
            style: null
        });
    },

    _init: function () {
        var opts = this.options;
        switch (opts.levelStyle) {
            case 0:
                break;
            case 1:
                opts.fontfamily = 'SimSun';
                opts.color = '#676767';
                opts.fontsize = '14px';
                break;
            case 2:
                opts.fontfamily = 'Microsoft YaHei,STXihei,SimSun,sans-serif';
                opts.color = '#202020';
                opts.fontsize = '13px';
                break;
            default:
                break;
        }
        FS.LLabel.superclass._init.apply(this, arguments);
        if (opts.levelStyle === 1) {
            this.element.addClass('first_level_style');
            this.element.css('width', opts.firstStyleWidth);
        }
    }
});
$.shortcut("llabel", FS.LLabel);

/**
 * 可刷新,添加参数的列表控件
 * @class FS.ParameterGrid
 * @extends FR.Widget
 */
FS.ParameterGrid = FR.extend(FR.Widget, {
    _init: function () {
        FS.ParameterGrid.superclass._init.apply(this, arguments);
        this.createGrid();
    },

    createGrid: function () {
        var self = this;
        var gridConfig = {
            widgetName: this.options.widgetName,
            intervalColor: false,
            isHeadShow: true,
            items: [],
            columnsConfig: [
                {
                    key: 'name',
                    value: FR.i18nText('FS-Generic-WF_Name'),
                    width: 80,
                    onCellClick: function (rowIdx, colIdx, item, colCfg, $cell) {
                        self.text2widegt(78, item, 'name', $cell);
                    }
                }, {
                    key: 'type',
                    value: FR.i18nText("FS-Generic-Report_Type"),
                    width: 88,
                    onCellCreate: function (rowIdx, colIdx, item, colCfg) {
                        var $combo = new FR.ComboBoxEditor({
                            width: 88,
                            height: 25,
                            directEdit: false,
                            allowBlank: false,
                            value: item.type,
                            items: [
                                {value: "String", text: FR.i18nText("FS-Generic-Parameter_String")},
                                {value: "Integer", text: FR.i18nText("FS-Generic-Parameter_Integer")},
                                {value: "Double", text: FR.i18nText("FS-Generic-Parameter_Double")},
                                {value: "Boolean", text: FR.i18nText("FS-Generic-Parameter_Boolean")},
                                {value: "Formula", text: FR.i18nText("FS-Generic-Parameter_Formula")}
                            ],
                            listeners: [
                                {
                                    eventName: FR.Events.STOPEDIT,
                                    action: function () {
                                        item.type = this.getValue()
                                    }
                                }
                            ]
                        });
                        return $combo.element;
                    }
                }, {
                    key: 'value',
                    value: FR.i18nText("FS-Generic-Simple_Value"),
                    width: 120,
                    onCellClick: function (rowIdx, colIdx, item, colCfg, $cell) {
                        self.text2widegt(118, item, 'value', $cell);
                    }
                }, {
                    width: 40,
                    onHeadCellCreate: function (colIdx, colCfg) {
                        return $('<div class="refresh_parameter"/>').attr('title',FR.i18nText('FS-Template_Refresh_Parameter'))
                            .hover(function () {
                                $(this).addClass('refresh_blue-hover');
                            }, function () {
                                $(this).removeClass('refresh_blue-hover').removeClass('refresh_blue-click');
                            }).mousedown(function () {
                                $(this).addClass('refresh_blue-click');
                            }).mouseup(function () {
                                if (!self.reportletPath) {
                                    return;
                                }
                                $(this).removeClass('refresh_blue-click');
                                var parameters;
                                try {
                                    parameters = FS.Sync.ajax({
                                        url: FR.servletURL + "?op=fs_entry&cmd=genparameters",
                                        type: 'POST',
                                        data: {
                                            reportPath: self.reportletPath
                                        }
                                    });
                                } catch (e) {
                                    FR.Msg.toast("Parameter parse error!");
                                    return;
                                }
                                self.grid.refresh(parameters);
                            });
                    }
                }, {
                    width: 40,
                    onCellCreate: function (rowIdx, colIdx, item, colCfg) {
                        var self = this;
                        return $('<div class="delete_item"/>')
                            .hover(function () {
                                $(this).addClass('delete_item-hover');
                            }, function () {
                                $(this).removeClass('delete_item-hover').removeClass('delete_item-click');
                            }).mousedown(function () {
                                $(this).addClass('delete_item-click');
                            }).mouseup(function () {
                                $(this).removeClass('');
                                self.options.items.splice(rowIdx, 1);
                                self.refresh();
                            });
                    },
                    onHeadCellCreate: function (colIdx, colCfg) {
                        var self = this;
                        return $('<div class="add_parameter"/>').attr('title',FR.i18nText('FS-Template_Add_Parameter'))
                            .hover(function () {
                                $(this).addClass('add_blue-hover');
                            }, function () {
                                $(this).removeClass('add_blue-hover').removeClass('add_blue-click');
                            })
                            .mousedown(function () {
                                $(this).addClass('add_blue-click');
                            })
                            .mouseup(function () {
                                $(this).removeClass('add_blue-click');
                                self.addRowData({
                                    name: '',
                                    type: 'String',
                                    value: ''
                                });
                            }
                        );
                    }
                }
            ]
        };
        self.grid = new FR.QuickGrid(gridConfig);
        self.grid.element.appendTo(this.element);
    },

    /**
     * 参数转换成可编辑控件
     * @param width 控件宽度
     * @param item 数据
     * @param key 字段
     * @param $cell 单元格dom
     */
    text2widegt: function (width, item, key, $cell) {
        if (!$cell.data('editing')) {
            $cell.hide();
            var editor = new FR.TextEditor({
                renderEl: $('<div/>').insertBefore($cell),
                width: width,
                height: 25,
                value: item[key],
                listeners: [
                    {
                        eventName: FR.Events.STOPEDIT,
                        action: function () {
                            var val = this.getValue();
                            item[key] = val;
                            $cell.html(val).show();
                            this.destroy();
                            $cell.data('editing', false);
                        }
                    }
                ]
            });
            $cell.data('editing', true);
            editor.select();
        }
    },

    /**
     * 展现数据
     * @param data 要展现的数据
     */
    popData: function (data) {
        var self = this;
        if (data) {
            $.each(data, function (idx, item) {
                self.grid.addRowData(item);
            });
        }
    },

    /**
     * 获取数据
     */
    getData: function () {
        var data = [];
        $.each(this.grid.getValue(), function (i, item) {
            var resultItem = item;
            resultItem.value = FR.encodePrecentPlus(resultItem.value);
            data.push(resultItem);
        });
        return data;
    }
});
$.shortcut("parametergrid", FS.ParameterGrid);

/**
 * 颜色选择控件
 *
 *      @example
 *      var $div = $('<div style="position:absolute;left:20px;top:20px;width:400px;height:400px">').appendTo('body');
 *      var picker = new FS.ColorPicker({
 *          renderEl : $div
 *      });
 *
 * @class FS.ColorPicker
 * @extends FR.Widget
 */
FS.ColorPicker = FR.extend(FR.Widget, {
    _defaultConfig: function () {
        return $.extend(FS.ColorPicker.superclass._defaultConfig.apply(this, arguments), {
            baseCls: 'fs-colorpicker',
            width: 300,
            height: 100,
            barWidth: 204,
            onColorPick: null
        });
    },
    _init: function () {
        FS.ColorPicker.superclass._init.apply(this, arguments);
        this.redBar = this._createColorBar('cp-red');
        this.greenBar = this._createColorBar('cp-green');
        this.blueBar = this._createColorBar('cp-blue');
        var val = this.options.value;
        if(val){
            this.setValue(val);
        }
    },

    _createColorBar: function(colorCls){
        var o = this.options, self = this;
        var $wrap = $('<div class="picker-item"/>').appendTo(this.element);
        var $bar = $('<div class="picker-bar"/>')
            .width(o.barWidth).appendTo($wrap);
        $wrap.$color = $('<div class="picker-fill"/>').addClass(colorCls).appendTo($bar);
        $wrap.$spliter = $('<div class="picker-spliter"/>').appendTo($bar);
        var isEdge, edgeLeft=0;
        $wrap.$spliter.draggable({
            axis: 'h',
            onDrag: function(e) {
                var left = e.data.left;
                left = left || 0;
                var w = left+8;
                var val = parseInt(w/o.barWidth * 255);
                isEdge = false;
                if(val < 0){
                    val = 0;
                    w = 0;
                    isEdge = true;
                }else if(val>255){
                    val = 255;
                    w = o.barWidth;
                    isEdge = true;
                }
                left= w - 8;
                $wrap.$color.width(w);
                $wrap.$input.val(val);
                if(isEdge){
                    edgeLeft=left;
                    return false;
                }
                FR.applyFunc(self, o.onColorPick, [], false);
            },
            onStopDrag: function(e){
                if(isEdge){
                    $wrap.$spliter.css({left: edgeLeft+'px'});
                    return false;
                }
            }
        });
        $wrap.$input = $('<input class="picker-rgb"/>')
            .val(0)
            .keyup(function (e) {
                if (FR.isEmpty(this.value)) {
                    this.value = 0;
                } else if (/\d+/.test(this.value)) {
                    var n = parseInt(this.value, 10);
                    if (n < 0) {
                        n = 0;
                    } else if (n > 255) {
                        n = 255;
                    }
                    this.value = n;
                }
            }).blur(function () {
                var value = parseInt(this.value, 10);
                if (!$.isNumeric(value)) {
                    value = 0;
                    $(this).val(0);
                }
                value = value / 255 * o.barWidth;
                $wrap.$spliter.css({left: value - 8 + 'px'});
                $wrap.$color.width(value);
                FR.applyFunc(self, o.onColorPick, [], false);
            }).appendTo($wrap);
        return $wrap;
    },

    /**
     * 设置选中值
     * @param {String} color 颜色
     * @param value 值
     */
    setColorValue: function(color, value){
        var o = this.options, self = this;
        var barObj;
        switch (color){
            case 'red':
                barObj = this.redBar;
                break;
            case 'green':
                barObj = this.greenBar;
                break;
            case 'blue':
                barObj = this.blueBar;
                break;
            default :break;
        }
        barObj.$input.val(value);
        value = value /255 * o.barWidth;
        barObj.$spliter.css({left: value - 8 + 'px'});
        barObj.$color.width(value);
    },

    /**
     * 设置RGB值
     * @param {Object} value RGB对象
     */
    setValue: function(value){
        this.redBar.$input.val(value.r);
        this.setColorValue('red', value.r);
        this.greenBar.$input.val(value.g);
        this.setColorValue('green', value.g);
        this.blueBar.$input.val(value.b);
        this.setColorValue('blue', value.b);
    },

    /**
     * 获取RGB对象
     * @returns {{r: Number, g: Number, b: Number}}
     */
    getValue: function(){
        return {
            r: parseInt(this.redBar.$input.val()),
            g: parseInt(this.greenBar.$input.val()),
            b: parseInt(this.blueBar.$input.val())
        }
    },

    /**
     * 获取RGB字符串
     * @returns {String} rgb格式的字符串
     */
    getText: function(){
        var r = this.redBar.$input.val(),
            g = this.greenBar.$input.val(),
            b = this.blueBar.$input.val();
        return  'rgb('+r+','+g+','+b+')';
    }
});
$.shortcut("fscolorpicker", FS.ColorPicker);

/**
 * 配色选择控件
 *
 *      @example
 *      var $div = $('<div style="position:absolute;left:20px;top:20px;width:400px;height:400px">').appendTo('body');
 *      var color = new FS.ColorSchemeRadio({
 *          renderEl : $div,
 *          colorScheme : [
 *              {r : 1, g : 1, b : 1},
 *              {r : 100, g : 100, b : 100},
 *              {r : 40, g : 40, b : 40}
 *          ]
 *      });
 * @class FS.ColorSchemeRadio
 * @extends FR.RadioButton
 */
FS.ColorSchemeRadio = FR.extend(FR.RadioButton, {
    _defaultConfig: function () {
        return $.extend(FS.ColorSchemeRadio.superclass._defaultConfig.apply(), {
            height: 55,
            width: 80,
            left: 20,
            index: 0,
            colorBlockWidth: 40,
            colorScheme: [],
            colorSelectable: false,
            beforeSelect: null,
            onColorSelected: null
        });
    },

    _init: function () {
        FS.ColorSchemeRadio.superclass._init.apply(this, arguments);
        var o = this.options,
            $el = this.element;
        var width = Math.max(o.width, o.colorBlockWidth * o.colorScheme.length);
        $el.css({
            'height': o.height,
            'width': width,
            'position': 'relative',
            'float': 'left',
            'margin-left': o.left
        });
        this.$colorWrapper = $('<div class="fs-scheme-color-group"/>').appendTo($el);
        this.$borderContainer = $('<div class="fs-scheme-border-container"/>').appendTo($el);
        this.$selected = null;
        this._initColorBlocks();
    },

    _initColorBlocks: function () {
        var self = this;
        var left = 0;
        $.each(this.options.colorScheme, function (i, scheme) {
            var color = FS.Tools.getCssColor(scheme);
            var $block = $('<div class="fs-scheme-color"/>').css({
                'left': left,
                'background-color': color
            }).data('COLOR', scheme).appendTo(self.$colorWrapper);
            var $border = $('<div class="fs-scheme-color-border"/>').css({
                'left': left-3
            }).hide().appendTo(self.$borderContainer);
            $block.data('BORDER', $border);
            left += self.options.colorBlockWidth;
            $block.click(function (e) {
                self.setSelected(true);
                self.selectColorBlock($block);
            })
        })
    },

    /**
     * 设置选中的颜色块
     * @param {jQuery} $block 颜色块
     */
    selectColorBlock: function ($block) {
        if (this.options.colorSelectable) {
            $('.fs-scheme-color-border', this.$borderContainer).hide();
            $block.data('BORDER').show();
            if (this.$selected) {
                this.$selected.removeClass('selected');
            }
            this.$selected = $block;
            this.$selected.addClass('selected').css({'width': 40});
            // 传递选中块颜色参数
            FR.applyFunc(this, this.options.onColorSelected, [$block.data('COLOR'), $block], false);
        }
    },

    /**
     * 改变选中状态
     * @param selected 选中状态
     */
    setSelected: function (selected) {
        if (this.isSelected() === selected) {
            return;
        }
        if (FR.applyFunc(this, this.options.beforeSelect, [selected], false) === false) {
            if (selected === false) {
                $('.fs-scheme-color-border', this.$borderContainer).hide();
                if (this.$selected) {
                    this.$selected.removeClass('selected');
                    this.$selected = null;
                }
            } else {
                if (!this.$selected) {
                    this.selectColorBlock(this.$colorWrapper.children().eq(0));
                }
            }
            FS.ColorSchemeRadio.superclass.setSelected.apply(this, [selected]);
        }
    },

    /**
     * 批量设置颜色
     * @param {Array} scheme 颜色数组
     */
    setColorScheme: function (scheme) {
        this.element.empty();
        this.options.colorScheme = scheme;
        this._init();
    },

    /**
     * 设置被选中色块的颜色
     * @param {Object} color 颜色的CSS参数,以rgb数值表示
     */
    setSelectedColor: function (color) {
        this.$selected.css({
            'background-color': FS.Tools.getCssColor(color)
        }).data('COLOR', color);
    },

    /**
     * 获取选中的颜色
     * @returns {Object} 以rgb格式表示的颜色值
     */
    getSelectedColor: function(){
        return this.$selected.data('COLOR');
    },

    /**
     *获取配色组合
     * @returns {Array} 控件色块的颜色数组
     */
    getColorScheme: function () {
        var results = [];
        $.each(this.$colorWrapper.children(), function (index, block) {
            var color = $(block).data('COLOR');
            results.push(FS.Tools.getCssColor(color));
        });
        return results;
    },

    /**
     * 获取选中的颜色块的索引
     * @returns {Number} 选中的索引
     */
    getIndex: function () {
        return this.options.index;
    }
});
$.shortcut("colorschemeradio", FS.ColorSchemeRadio);