/**
 * Tag显示的下拉复选框控件
 * @class FR.TagCheckBoxEditor
 * @extends FR.CheckBoxEditor
 */
FR.TagCheckBoxEditor = FR.extend(FR.CheckBoxEditor, /**@class FR.TagCheckBoxEditor*/{

    _defaultConfig: function () {
        return $.extend(FR.TagCheckBoxEditor.superclass._defaultConfig.apply(), {
            //标签样式的基础类
            tagBaseClass: 'fr-tageditor',
            //文本编辑框的最小宽度
            minWidth4Edit: 24,
            //标签间距
            tagMargin: 4,
            //动画速度
            animateSpeed: 100
        });
    },

    _init: function () {
        FR.TagCheckBoxEditor.superclass._init.apply(this, arguments);
        this._initTagContainer();
        this.startTagIdx = -1; //Sean: 用于标识所生成的第一个tag在this.value中的索引位置
        this.widthFix = 0;
        if(FR.Browser.isIE6Before()){
            this.widthFix = 4;
        }
    },

    _editCompBlur: function () {
        if (this.options.watermark && this.text && this.text.length > 0) {
            //Sean: 带tag的控件需要延后处理水印,因为input在失焦后肯定是没有值的,会产生水印。
            this.removeWaterMark.defer(0, this);
        }
    },

    /**
     * 编辑框失焦后,判断是否符合规则等执行事件
     * @private
     */
    _editCompBlurValidValue: function () {
        //只需要校验是否为空即可
        if (this.options.allowBlank === false && (!this.text || this.text.length === 0)) {
            this.errorMsg = this.options.errorMsg || FR.i18nText("FR-Base_NOT_NULL_Des");
            this.invalidateCss();
        } else {
            this.validateCss();
        }
        //为啥要重新构建? 重新构建会导致69633, 第二次下拉的时候数据用了错误的缓存.
//        this.options.need2BuildList = true;
        this.searchText = "";
        var val = this.editComp.val();
        if(val != ""){
            val = this._getEditTagFullValue(val);
            this._appendTagFromInput(val);
            this.editComp.val("");
            this._editCompBlur();
        }
    },

    _doBeforeSearch: function () {
        //Sean: Override. Do Nothing.
    },

    /**
     * 初始化Tag层
     * @private
     */
    _initTagContainer: function () {
        var opts = this.options;
        opts.minWidth4Edit = Math.max(2*opts.fontSize, opts.minWidth4Edit);
        //所有tag的容器层
        var height = this.editComp.height(),
            tagClz = opts.tagBaseClass;
        //所有tag的容器外层(限制显示宽度)
        this.tagContainer = $('<div/>').addClass(tagClz + '-container').height(height)
            .prependTo(this.triggerTextComp);
        //所有tag的容器内层(自适应内容宽度,用于左右平移显示)
        this.tagWrap = $('<span/>').addClass(tagClz + '-wrapper').appendTo(this.tagContainer);
    },

    /**
     * 绑定tag事件
     * @param {jQuery} tag tag对象
     * @private
     */
    _bindEvent2Tag: function (tag) {
        var self = this, o = this.options;
        //点击事件
        tag.click(function () {
            self._setTagSelect($(this));
        });
        //双击事件
        tag.dblclick(function () {
            if(o.directEdit !== false && o.customData !== false){
                self._editTag($(this));
            }
        });
    },

    /**
     * 对Tag进行编辑
     * @param {jQuery} tagObj 需要编辑的Tag对象
     * @private
     */
    _editTag: function (tagObj) {
        var index = this.tagWrap.children().index(tagObj) + this.startTagIdx + 1;
        tagObj.hide();
        var tagEditComp = $("<input type='text'/>").addClass('fr-tageditor-tag-edit')
            .val(tagObj.text())
            .css({
                width: tagObj.outerWidth(),
                'font-size': this.options.fontSize
            })
            .insertAfter(tagObj);
        this.isTagEditing = true;
        var self = this;
        tagEditComp.blur(function () {
                self.collapse();
                self.isTagEditing = false;
                var value = $(this).val();
                $(this).remove();
                if (value === "") {
                    self._removeTag(tagObj);
                }else{
                    tagObj.text(value);
                    value = self._getEditTagFullValue(value);
                    self._spliceTagData(index, value);
                    tagObj.show();
                    self._loadMoreTags(self.text);
                    self._modifyTagPosition();
                    self._moveViewToShow(tagObj);
                }
                self.fireEvent(FR.Events.STOPEDIT);
            }
        );
        tagEditComp.keyup(function(e) {
            var key = e.keyCode;
            if (!FR.isNavKeyPress(e)) {
                self._spliceTagData(index, tagEditComp.val());
                self.fireEvent(FR.Events.AFTEREDIT);
            }else if(key === FR.keyCode.ENTER){
                $(this).blur();
            }
        });
        tagEditComp.focus();
    },
    /**
     * @param {Array} text 文本内容集合
     * @private
     */
    _setCompText: function (text) {
        if(this.tagWrap){
            this.tagWrap.empty();
            this.startTagIdx = text.length - 1;
            this._loadMoreTags(text);
            this._modifyTagPosition();
            this._moveViewToShow();
        }else{
            FR.TagCheckBoxEditor.superclass._setCompText.apply(this, arguments);
        }
    },

    /**
     * 分步加载Tag
     * @param {Array} text 文本内容集合
     * @protected
     */
    _loadMoreTags: function(text){
        if(this.startTagIdx >= 0){
            var minWidth4Tags = this.element.width() - this.options.minWidth4Edit - this.btnWidth;
            while (this.tagWrap.width() < minWidth4Tags && this.startTagIdx >= 0) {
                this._createTagFromText(text[this.startTagIdx]).prependTo(this.tagWrap);
                this.startTagIdx--;
            }
        }
    },
    /**
     * 从文本内容生成一个Tag
     * @param {String} text 文本内容
     * @protected
     */
    _appendTagFromInput: function (text) {
        if (this.checkValid(text)) {
            if ($.inArray(text, this.text) === -1) {
                this._pushTagData(text);
                this._createTagFromText(text).appendTo(this.tagWrap);
                this._modifyTagPosition();
                this._moveViewToShow();
                var checkArr = $.grep(this.ck_el_array, function (ck_el) {
                    return ck_el.getText() == text;
                })
                if (checkArr && checkArr[0]) {
                    checkArr[0].changeBoxState(true);
                }
                this.fireEvent(FR.Events.AFTEREDIT);
            }
        } else {
            FR.Msg.toast(this.errorMsg);
        }
    },

    _getEditTagFullValue: function(newText) {
        return newText;
    },

    _pushTagData: function(text) {
        if (!this.text) {
            this.text = [];
        }
        this.text.push(text);
    },
    _spliceTagData: function(idx, newText) {
        if (newText == undefined) {
            this.text.splice(idx, 1);
        } else {
            this.text.splice(idx, 1, newText);
        }
    },
    /**
     * 移除一个Tag
     * @param {jQuery} tagObj tag对象
     * @param {Boolean} isLast 是否排在最后的Tag
     * @private
     */
    _removeTag: function (tagObj, isLast) {
        if (isLast) {
            this.text.pop();
        } else {
            var index = this.tagWrap.children().index(tagObj) + this.startTagIdx + 1;
            this._spliceTagData(index);
        }
        var $next = tagObj.next();
        tagObj.remove();
        this.fireEvent(FR.Events.AFTEREDIT);
        this.inAllSelectModel = false;
        this.options.need2BuildList = true;
        this._loadMoreTags(this.text);
        this._modifyTagPosition();
        this._setTagSelect($next);
    },

    _getCompText: function () {
        this.text = this.text || [];
        return this.text.slice(0);//Sean:不传递指针,所以使用slice(0)最快地clone一个数组
    },

    /**
     * 将输入的文本信息生成Tag
     * @param {String} text 文本内容
     * @returns {*|jQuery} 返回生成的Tag对象
     * @private
     */
    _createTagFromText: function (text) {
        var opts = this.options;
        var t = text;
        if ($.isArray(text)) {
            t = text[text.length - 1];
        }
        //不生成空文本的tag
        if (FR.isEmpty(t)) {
            return $('');
        }
        var height = this.editComp.height();
        var tagClz = this.options.tagBaseClass;
        //tag层
        var tagSpan = $("<span/>").addClass(tagClz + '-tag')
            .text(t)
            .css({
                'line-height': height + 'px',
                'margin': '0 ' + opts.tagMargin / 2 + 'px',
                'font-size': this.options.fontSize
            });
        //绑定事件
        this._bindEvent2Tag(tagSpan);
        return tagSpan;
    },

    /**
     * 调整结果标签以及文本框的位置和宽度
     * @protected
     */
    _modifyTagPosition: function () {
        var opts = this.options;
        var minWidth = opts.minWidth4Edit;
        var tagClz = opts.tagBaseClass;
        var $container = $('.' + tagClz + '-container', this.triggerTextComp);
        var editWidth = $.support.boxModel ? this.triggerTextComp.width() : this.triggerTextComp.width() - 2;
        var tagsWidth = this.tagWrap.width();
        if (editWidth - tagsWidth < minWidth) {
            this.editComp.outerWidth(minWidth - this.widthFix);
            $container.width(editWidth - minWidth);
        } else {
            this.editComp.outerWidth(editWidth - tagsWidth - this.widthFix);
            $container.width(tagsWidth);
        }
    },

    /**
     * 选中指定的Tag
     * @param {jQuery} tagObj tag对象
     * @private
     */
    _setTagSelect: function (tagObj) {
        var tagClz = this.options.tagBaseClass;
        var selectedId = tagClz + '-tag-select';
        $('#' + selectedId, this.tagWrap).removeAttr('id');
        if (tagObj) {
            //tag上绑定键盘操作,包括左右方向键选择和DELETE,BACKSPACE
            var self = this;
            var tagOpts = function (e) {
                if(self.isTagEditing){
                    return;
                }
                if (e.keyCode == FR.keyCode.DELETE || e.keyCode == FR.keyCode.BACKSPACE) {
                    FR.Keys.unreg(tagOpts);
                    self._removeTag(tagObj);
                } else if (e.keyCode == FR.keyCode.LEFT) {
                    if (tagObj.prev().length > 0) {
                        self._setTagSelect(tagObj.prev());
                    }
                } else if (e.keyCode == FR.keyCode.RIGHT) {
                    self._setTagSelect(tagObj.next());
                    if (tagObj.next().length === 0) {
                        self.editComp.focus();
                    }
                }
            };
            FR.Keys.reg(tagOpts);
            $('body').bind('mousedown.tagselect', function(e) {
                if (!$(e.target).isChildAndSelfOf(self.tagWrap)) {
                    FR.Keys.unreg(tagOpts);
                    $('#' + selectedId, self.tagWrap).removeAttr('id');
                }
            });
            tagObj.attr('id', tagClz + '-tag-select');
            this._moveViewToShow(tagObj);
        } else {
            this._moveViewToShow();
        }
    },

    _editCompFocus: function () {
        var val = this.editComp.val();
        if(val != ""){
            this._setCompText(this.text);
            if(!this.isFiltering()){
                this.editComp.val("");
            }
        }else{
            this._setTagSelect();
        }
    },
    /**
     * 将所有Tag平移使指定对象出现在可视范围
     * @param {Number|jQuery} tagObj 需要显示的元素;若为空,则表示移动到最后一个tag可显示的地方
     * @protected
     */
    _moveViewToShow: function (tagObj) {
        var o = this.options, self = this;
        var conWidth = this.tagContainer.width(), tagWidth = this.tagWrap.width();
        if (tagObj && tagObj.length > 0) {
            if (this.editComp.outerWidth() > this.options.minWidth4Edit) {
                return;
            }
            var wrapLeft = this.tagWrap.offset().left;//tagWrap层左距
            var conLeft = this.tagContainer.offset().left;//tagContainer层左距
            var conDis = wrapLeft - conLeft;
            var objWidth = tagObj.width();
            var target = conLeft + conWidth/2 - objWidth/2;
            while (this.startTagIdx >= 0 && tagObj.offset().left < target) {
                this._createTagFromText(this.text[this.startTagIdx]).prependTo(this.tagWrap);
                this.startTagIdx --;
            }
            var pos = tagObj.offset().left - target;
            tagWidth = this.tagWrap.width();
            if(pos < 0){
                pos = "-="+Math.max(pos, conDis);
            }else{
                pos = "-="+Math.min(pos, tagWidth - conWidth + conDis);
            }
        } else {
            pos = Math.min(conWidth - tagWidth, 0);
        }
        this.tagWrap.animate({
            left: pos
        }, o.animateSpeed);
    },

    /**
     * EditComp的按键事件扩展,ENTER,LEFT,BACKSPACE
     * @private
     */
    _onKeyDown: function (e) {
        var k = e.keyCode, self = e.data;
        if (k == FR.keyCode.ENTER) {
            if (this.value == "") {
                self.collapse();
            } else {
                self._appendTagFromInput(this.value);
                self.editComp.val("");
                self._editCompBlur();
            }
            e.stopEvent();
        } else if (k == FR.keyCode.LEFT) {
            if (this.value == "" && self.tagWrap.children().length > 0) {
                var tagClz = self.options.tagBaseClass;
                self._setTagSelect($('.' + tagClz + '-tag:last', self.tagWrap));
                self.editComp.blur();
                e.stopEvent();
            }
        } else if (k == FR.keyCode.BACKSPACE) {
            if (this.value == "" && self.tagWrap.children().length > 0) {
                var tagClz = self.options.tagBaseClass;
                var $lastTag = $('.' + tagClz + '-tag:last', self.tagWrap);
                self._removeTag($lastTag, true);
                e.stopEvent();
            }
        }
        FR.CheckBoxEditor.superclass._onKeyDown.apply(this, arguments);
    },

    __makeSureInputValueInResList: function() {
        if (this.searchText == undefined) {
            return;
        }
        var t = this.searchText;
        var arr = t.split(/[,;,;]/);
        var endSymbol = t.endWith(',') || t.endWith(';') || t.endWith(',') || t.endWith(';');
        if (!endSymbol) {
            return;
        }
        for (var i=0; i<arr.length; i++) {
            if (arr[i] != "") {
                this._checkAndAddTag(arr[i]);
                this.fireEvent(FR.Events.AFTEREDIT);
                break;
            }
        }
    },

    _checkAndAddTag: function(text) {
        if (FR.isEmpty(text) || text == "") {
            return;
        }
        this.searchText = text;
        FR.CheckBoxEditor.superclass.__makeSureInputValueInResList.apply(this, arguments);
        if (this.inList || this.options.customData) {
            if (this.text == undefined) {
                this.text = [];
            }
            if ($.inArray(text, this.text) === -1) {
                this._pushTagData(text);
                this._addResultTag(text);
                this.searchText = null;
                this.editComp.val("");
                var checkArr = $.grep(this.ck_el_array, function (ck_el) {
                    return ck_el.getText() == text;
                })
                if (checkArr && checkArr[0]) {
                    checkArr[0].changeBoxState(true);
                }
                this.collapse();
                this.options.need2BuildList = true;
                this.editComp.focus();
            }
        } else {
            FR.Msg.toast('No custom value allowed');
            this.editComp.val(text);
        }
    },

    _addResultTag: function(txt) {
        this.tagWrap.append(this._createTagFromText(txt));
        this._modifyTagPosition();
    },

    /**
     * 移除不符合规则的提示样式
     */
    validateCss: function () {
        this.editComp.removeClass('fr-trigger-invalid');
        this.editComp.removeClass('fr-trigger-text-invalid');
        this.editComp.removeAttr('title');
    },

    /**
     * 显示不符合规则的提示样式
     */
    invalidateCss: function () {
        this.editComp.addClass('fr-trigger-invalid');
        this.editComp.addClass('fr-trigger-text-invalid');
        this.editComp.attr('title', this.getErrorMsg());
    },

    startEditing: function () {
        FR.TagCheckBoxEditor.superclass.startEditing.apply(this, arguments);
        this._modifyTagPosition();
    },


    reset: function () {
        FR.TagCheckBoxEditor.superclass.reset.apply(this, arguments);
        this.inAllSelectModel = false;
        this.tagContainer && this.tagContainer.remove();
        delete this.tagContainer;
        this._initTagContainer();
        if(this.options.watermark){
            this.removeWaterMark();
            this.setWaterMark();
        }
    }
});
$.shortcut("tagcombocheckbox", FR.TagCheckBoxEditor);