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

;(function($){
    /**
     * 下拉复选框控件
     *
     *     @example
     *     var $root = $('<div>').css({position : 'absolute', top : 5, left : 40}).appendTo('body');
     *     var editor = new FR.CheckBoxEditor({
     *           renderEl : $root,
     *           directEdit : true,
     *           allowBlank : true,
     *           widgetUrl : null,         //同下拉框
     *           returnArray : true,      //返回值是否以数组形式
     *           delimiter : ',',             //字符串返回值的分隔符
     *           startSymbol : '',          //起始符
     *           endSymbol : '',           //结束符
     *           fontSize : 14,
     *           width : 120,
     *           height : 24,
     *           maxCount : 10,
     *           items : [
     *               {text : "111", value : "aaa"},
     *               {text : "222", value : "bbb"},
     *               {text : "333", value : "ccc"},
     *               {text : "444", value : "ddd"}
     *           ]
     *      });
     *
     * @class FR.CheckBoxEditor
     * @extends FR.ComboBoxEditor
     *
     * @cfg {JSON} options 属性配置
     * @cfg {String} [options.delimiter=','] 结果分隔符
     * @cfg {String} [options.startSymbol=''] 起始符
     * @cfg {String} [options.endSymbol=''] 结束符
     */
    FR.CheckBoxEditor = FR.extend(FR.ComboBoxEditor, /**@class FR.CheckBoxEditor*/{
        /**
         * @private
         */
        _defaultConfig: function () {
            return $.extend(FR.CheckBoxEditor.superclass._defaultConfig.apply(), {
                delimiter: ',',
                startSymbol: '',
                endSymbol: '',
                itemCheckOnClass:'.fr-checkbox-checkon',
                itemCheckOffClass:'.fr-checkbox-checkoff'
            });
        },

        /**
         * @private
         */
        _init: function () {
            FR.CheckBoxEditor.superclass._init.apply(this, arguments);
            this.$view.addClass('fr-checkbox-list');
            this._initCheckBoxContainer();

            this.options.delimiter = this.options.delimiter.replace(/\\r/g, "\n");
        },

        /**
         * 初始化子项元素集合
         * @private
         */
        _initCheckBoxContainer: function () {
            if (!this.ck_el_array) {
                this.ck_el_array = [];
            }
        },

        /**
         * 设置下拉框的内容
         * @param {Array} items 内容集合
         * @private
         */
        _setItems: function (items) {
            var records = items || [];
            var sH = this.options.sonHeight;
            var count = this.options.maxCount || 10;
            var th = records.length > count ? (sH + 2) * count : (sH + 2) * records.length;
            this.$view.height(th + sH);
            this.tH = th + sH;
            this.modifyPosition();
            var self = this;
            this.initControlPane();
            this.innerCheckBox = self._createInnerCheckBox();

            this.innerCheckBox.on(FR.Events.CLICK, function () {
                self.editComp.val("");

                if (this.selected()) {
                    self.doSelectAll();
                } else {
                    self.deSelectAll();
                }
                self.editComp.focus();
            });
            this.$view.append(this.$controlPane);
            this.ck_el_array = [];
            this.addData2View(records);
        },

        initControlPane : function () {
            this.$controlPane = $("<div style='padding-right:20px'>").addClass('fr-checkbox-control');
        },

        _createInnerCheckBox : function(){
            var self = this;
            return new FR.CheckBox({
                renderEl: $("<div/>").appendTo(self.$controlPane),
                text: FR.i18nText("FR-Engine_Choose_All") + "/" + FR.i18nText("FR-Engine_Deselect_All")
            });
        },

        /**
         * 将值添加到DOM中
         * @param {Array} data 将值添加到dom中
         */
        addData2View: function (data) {
            var self = this;
            var start = this.ck_el_array.length;
            for (var i = start, len = start + data.length; i < len; i++) {
                var it = data[i - start];
                var container = $('<div/>').height(this.options.sonHeight).attr('title', it.getShowValue()).addClass('fr-combo-list-item').appendTo(this.$view);
                var checkBox = this._createItemCheckBox(container,it);
                if (this.inAllSelectModel === true || $.inArray(it.getShowValue(), self.text) !== -1) {
                    checkBox.setSelectedWithoutEvent(true);
                }
                this.ck_el_array[i] = checkBox;
            }
            if (!this.options.isInited) {
                var initArray;
                if (typeof this.options.value == 'string') {
                    initArray = this.options.value.split(this.options.delimiter);
                } else if (FR.isArray(this.options.value)) {
                    initArray = this.options.value;
                }
                if (!FR.isEmpty(initArray) && !FR.isEmptyArray(initArray)) {
                    $.each(this.ck_el_array, function (idx, item) {
                        //bug81322 实际值是1,array后台传过来是string,split之后是"1",这边统一转成字符串比较。
                        var valuestr = item.options.value + '';
                        var textstr = item.options.text + '';
                        if (initArray.indexOf(valuestr) != -1 || initArray.indexOf(textstr) != -1) {
                            item.changeBoxState(true);
                        } else if (item.isSelected()) {
                            item.changeBoxState(false);
                        }
                    });
                }
                this.options.isInited = true;
            }
            var selectedItems = $(this.options.itemCheckOnClass, this.$view);
            if (selectedItems.length == this.ck_el_array.length) {
                this.innerCheckBox.selected(true);
            }
            this.$view.__loadingMoreData__(false);
        },

        /**
         * 生成子项CheckBox
         * @param {jQuery} container 容器DOM
         * @param {JSON} data 数据对象
         * @returns {FR.CheckBox} 复选框控件对象
         * @private
         */
        _createItemCheckBox: function(container,data){
            var self = this;
            var checkbox = new FR.CheckBox({
                renderEl: $("<div/>").appendTo(container),
                text: data.getShowValue(),
                value: data.getValue(),
                listeners : [{eventName : FR.Events.STATECHANGE, action : function(){
                    self.editComp.val("");
                    self.fireEvent(FR.Events.CLICK);
                    if (!this.isSelected()) {
                        self.innerCheckBox.setSelected(false);

                        //有子checkbox被勾掉, 那就不是全选了
                        if(self.inAllSelectModel){
                            self.inAllSelectModel = false;
                        }
                    }
                    else {
                        var selectedItems = $(this.options.itemCheckOnClass, self.$view);
                        if (selectedItems.length == self.ck_el_array.length) {
                            self.innerCheckBox.setSelected(true);
                        }
                    }
                    self._refreshComponentValue(this);
                    self.editComp.focus();
                }}]
            });
            return checkbox;
        },

        /**
         * @private
         */
        _doBeforeSearch: function(){
            this.searchText = this.editComp.val();
        },

        /**
         * 键盘按键选定一个item后的事件
         * @private
         */
        _onEnterPressed: function () {
            var idx = this._getSelectedIndex();
            var focusedCheckBox = this.ck_el_array[idx];
            if(focusedCheckBox){
                focusedCheckBox.setSelected(!focusedCheckBox.isSelected());
            }
            this.collapse();
        },

        /**
         * 刷新checkbox
         * @param {FR.CheckBox} checkBox checkbox控件对象
         * @private
         */
        _refreshComponentValue: function (checkBox) {
            if(!this.text){
                this.text = [];
            }
            if (checkBox.isSelected()) {
                this.text.push(checkBox.getText());
            } else {
                this.text.remove(checkBox.getText());
            }
            this._setCompText(this.text);
            this.fireEvent(FR.Events.AFTEREDIT);
        },

        /**
         * 调整下拉表生成的位置
         */
        modifyPosition: function () {
            this.options.offset = {'top': this.element.offset().top, 'left': this.element.offset().left};
            this.tW = this.$view.width();
            FR.CheckBoxEditor.superclass.modifyPosition.apply(this, arguments);
        },

        /**
         * 添加数值,性能优化
         * @returns {*}
         */
        data2Add: function () {
            if (this.inAllSelectModel === true) {
                var data = [];
                var records = this.options.data.getRecords();
                var loadedDataCount = this.ck_el_array.length;
                for (var i = 0, len = records.length; i < this.options.limitData; i++) {
                    if(i + loadedDataCount >= len){
                        break;
                    }
                    data[i] = records[i + loadedDataCount];
                }
                return data;
            } else {
                return this.options.data.appendData();
            }
        },

        /**
         * 全选操作
         */
        doSelectAll: function () {
            var arr = [];
            var self = this;
            if(this.isFiltering()){
                $.each(this.ck_el_array, function (idx, it) {
                    it.setSelectedWithoutEvent(true);
                    arr.push(it.getText());
                });
            }else{
                if (!this.allRecords) {
                    this.inAllSelectModel = true;
                    var para = this.createDependencePara4Data();
                    para.parameter.startIndex = 0;
                    para.parameter.limitIndex = 0;
                    this.options.data.resetStatus(para);
                    this.allRecords = this.options.data.executeData();
                    this.options.data.records = this.allRecords;
                }
                $.each(self.allRecords, function (idx, record) {
                    arr.push(record.getShowValue());
                });
                $.each(this.ck_el_array, function (idx, it) {
                    it.setSelectedWithoutEvent(true);
                });
            }
            this.text = arr;
            this._setCompText(arr);
            self.fireEvent(FR.Events.AFTEREDIT);
        },

        /**
         * 反选操作
         */
        deSelectAll: function () {
            this.text = [];
            var self = this;
            $.each(this.ck_el_array, function (idx, it) {
                it.setSelectedWithoutEvent(false);
            });
            this.inAllSelectModel = false;
            this._setCompText(this.text);
            self.fireEvent(FR.Events.AFTEREDIT);
        },

        /**
         * 赋值函数
         * @param {String} value 所赋值
         * @private
         */
        _dealValueWithEvents: function (value) {
            var self = this;
            var oldValue = this.getValue();
            if (value == "") {
                this._setCompText([]);
                return;
            }
            var value_array;
            if (typeof value === "string") {
                if (!this.options.returnArray) {
                    if (value.startWith(this.options.startSymbol)) {
                        value = value.substring(this.options.startSymbol.length);
                    }
                    if (value.endWith(this.options.endSymbol)) {
                        value = value.substring(0, value.length - this.options.endSymbol.length);
                    }
                }
                value_array = value.split(this.options.delimiter);
            } else {
                value_array = $.makeArray(value);
            }
            var records = this.options.data.getRecords();
            var inList = false;
            if (records.length > 0) {
                $.each(value_array, function (idx, v) {
                    for (var i = 0, len = records.length; i < len; i++) {
                        if (records[i].getValue() == v) {
                            value_array[idx] = records[i].getShowValue();
                            inList = true;
                            break;
                        }
                    }

                })
            }
            if (!FR.equals(this.text, value_array)) {
                this.options.need2BuildList = true;
            }
            this.text = value_array;
            this._setCompText(value_array);
            if (arguments[1] !== false) {
                this.fireEvent(FR.Events.AFTEREDIT, value, oldValue);
            }
        },

        isValueInList: function() {
            return true;
        },

        /**
         * 取值函数
         * @returns {*} 返回数组或者字符串
         */
        getValue: function () {
            var self = this;
            var text_array = this._getCompText();
            if(!this.options.data){
                return;
            }

            var records = this.options.data.getLoadedRecords();
            var showValueMap={};
            var allValueMap={};
            for (var i = 0, len = records.length; i < len; i++) {
                showValueMap[records[i].getShowValue()]=records[i].getValue();
            }
            var dataSource = this.options.data.options.dataSource;
            $.each(text_array, function (idx, text) {
                var res = null;
                if(!self.isEmptyMap(allValueMap)){
                    res = allValueMap[text];
                }else{
                    res = showValueMap[text];
                }
                if (res == null && self.isEmptyMap(allValueMap) && dataSource._findAllValue) {
                    var resss = dataSource._findAllValue();
                    if(!FR.isEmpty(resss)){
                        for (var i = 0, len = resss.length; i < len; i++) {
                            allValueMap[resss[i].text]=resss[i].value;
                        }
                        res = allValueMap[text];
                    }
                }
                if (res == null && dataSource._findShowValue) {
                    res = dataSource._findShowValue(text_array[idx], false);
                }
                if (FR.isEmpty(res)) {
                    if (self.options.customData) {
                        text_array[idx] = text;
                    }
                } else {
                    text_array[idx] = res;
                }
            });

            if (this.options.returnArray) {
                return text_array;
            }
            var resultStr = this.options.startSymbol + text_array.join(this.options.delimiter) + this.options.endSymbol;
            return resultStr;
        },
        isEmptyMap:function(o){
            for(var item in o){
                if(item){
                    return false;
                }
            }
            return true;
        },

        /**
         * 获取显示值
         * @returns {*} 返回数组或者字符串
         */
        getText: function() {
            var text_array = this._getCompText();
            return this.options.returnArray ? text_array
                : this.options.startSymbol + text_array.join(this.options.delimiter) + this.options.endSymbol;
        },

        /**
         * 赋值编辑框内的文本内容
         * @param {Array} text 文本内容
         * @private
         */
        _setCompText: function(text){
            this.editComp.val(text.join(this.options.delimiter));
        },
        /**
         * 获取编辑框内的文本内容
         * @returns {Array} 返回数组格式的结果
         * @private
         */
        _getCompText: function() {
            return this.editComp.val().split(this.options.delimiter);
        },
        rebuild: function(items){
            this.reset();
            FR.CheckBoxEditor.superclass.rebuild.apply(this, arguments);
        },
        /**
         * 重置控件
         */
        reset: function () {
            this.ck_el_array = [];
            this.text = null;
            this.setValue('');
            this.shouldReBuildList();
            this.allRecords = null;
        }
    });
    $.shortcut("combocheckbox", FR.CheckBoxEditor);
})(jQuery);