/*
 * 特别声明：本技术材料受《中华人民共和国著作权法》、《计算机软件保护条例》等法律、法规、行政
 * 规章以及有关国际条约的保护，赞同科技享有知识产权、保留一切权利并视其为技术秘密。未经本公司书
 * 面许可，任何人不得擅自（包括但不限于：以非法的方式复制、传播、展示、镜像、上载、下载）使用，
 * 不得向第三方泄露、透露、披露。否则，本公司将依法追究侵权者的法律责任。特此声明！
 *
 * Special Declaration: These technical material reserved as the technical secrets by AGREE 
 * TECHNOLOGY have been protected by the "Copyright Law" "ordinances on Protection of Computer 
 * Software" and other relevant administrative regulations and international treaties. Without 
 * the written permission of the Company, no person may use (including but not limited to the 
 * illegal copy, distribute, display, image, upload, and download) and disclose the above 
 * technical documents to any third party. Otherwise, any infringer shall afford the legal 
 * liability to the company.
 */
/**
 * Created by liushuai on 2015/1/16.
 */
define(["adoreapp/widget/BaseWidget", "adoreapp/widget/EventHub", "adoreapp/hotkey/Keys"], function (BaseWidget, EventHub, Keys) {
    return BaseWidget.extend(function (base) {
        return {
            _initWidget: function (attr) {
                var template = attr.template;
                this.templates = template.split("<!-- split -->");
                this.jqueryNode = $(this.templates[0]).attr("id", this.id);

                this.iconNode = this.jqueryNode.find("i:first").attr("id", this.id + "_icon");

                this.dropDownArrow = this.jqueryNode.find("i.mdi-navigation-arrow-drop-down").attr("id", this.id + "_arrow");

                this.isLayout = false;
                this.hadIcon = false;
                this.datas = [];
                this.maxShowItems = 6;//最大显示条数，默认6
                this.expandableTextId = this.id;

                this.attachNode = this.jqueryNode;
                this.textCode = this.jqueryNode.find("input").attr("id", this.id + "_input");
                this.jqueryNode.find("label").attr("for", this.id + "_input");

                var own = this;

                var widgetId = this.id;
                //add listener
                this.dropDownArrow.on("click", function (e) {
                    own.showDropDown(e, widgetId);
                });

                this.textCode.on("keydown", function (e) {
                    own.handleKeyDown(e, widgetId);
                });
                this.textCode.on("blur", function (e) {
                    own.handleOnBlur();
                });
               /* this.textCode.on("focus", function (e) {
                    //own.showDropDown(e, own.id);//移动端不需要在focus事件中弹出dropDown
                });*/
                this.textCode.on("input", function (e) {
                    own.handleInput(e);
                    own.checkRequisite();
                });

                $(document).bind("click." + widgetId, function (e) {
                    if (own.textCode.is(e.target)) {
                        own.showDropDown(e, widgetId);
                    }
                });
            },


            _setItems: function (attrs) {
                var items = attrs.items;
                this.datas = items;
            },

            handleInput: function (e) {
                var value = this.textCode.val();
                if (value === "") {
                    return;
                }
                for (var i = 0; i < this.datas.length; i++) {
                    if (this.datas[i].indexOf(value) != -1) {
                        this._setText({text: this.datas[i]});
                        return;
                    }
                }
                this.textCode.val("");
                this.checkRequisite();
            },

            handleOnBlur: function () {
                var value = this.textCode.val();
                this._setText({text: value});
                this.checkRequisite();
                var mouseOn = $("#" + this.id + "_dropDown").attr("mouseOn");
                if (mouseOn === "false") {
                    $("#" + this.id + "_dropDown").css("display", "none");
                }
            },

            _setName: function (attrs) {
                var name = attrs.name;
                this.jqueryNode.find("label").text(name);
            },

            _setEnabled: function (attrs) {
                var enabled = attrs.enabled;
                var input = this.jqueryNode.find("input");
                if (enabled) {
                    input.removeAttr("disabled");
                    this.jqueryNode.find("i").removeClass("icon_disabled");
                    if (this.requisite) {
                        if (input.val() == null || input.val() === "") {
                            this.addRequisite();
                        }
                    }
                } else {
                    this.jqueryNode.find("input").attr("disabled", "disabled");
                    if (this.requisite) {
                        this.removeRequisite();
                    }
                    this.jqueryNode.find("i").addClass("icon_disabled");
                }
            },

            _layout: function () {
                base._layout.call(this);
                this.isLayout = true;
                if (this.requisite) {
                    this._setRequisite({requisite: true});
                }
            },

            _setText: function (attrs) {
                var inputNode = this.jqueryNode.find("input");
                inputNode.val(attrs.text);
                if (attrs.text.length > 0) {
                    inputNode.siblings('label').addClass('active');
                    this.iconNode.addClass("active");
                } else {
                    inputNode.siblings('label').removeClass('active');
                    this.iconNode.removeClass("active");
                }
                if ((attrs.text == null || attrs.text === "") && this.requisite) {
                    this.addRequisite();
                } else {
                    this.removeRequisite();
                }
            },

            checkRequisite: function () {
                if (this.requisite) {
                    var inputSelector = this.jqueryNode.find('input');
                    var value = inputSelector.val();
                    if (value) {
                        this.removeRequisite();
                    } else {
                        this.addRequisite();
                        this.showSpan('请输入数据!');
                    }
                }
            },


            showSpan: function (msg) {
                this.jqueryNode.find('span').html(msg).css('display', 'block');
                $("#" + this.id + "_dropDown").css("margin-top", "-21px");
            },

            _setRequisite: function (attrs) {
                this.requisite = attrs.requisite;
                if (!this.isLayout) {
                    return;
                }
                if (this.requisite) {
                    if (this.jqueryNode.find('input').val()) {
                        this.removeRequisite();
                    } else {
                        this.addRequisite();
                    }
                }
            },

            removeRequisite: function () {
                this.jqueryNode.find('input').removeClass('adore_InputRequisite');
                this.jqueryNode.find("label").removeClass('adore_requisiteColor');
                this.iconNode.removeClass('adore_requisiteColor');
                this.hideSpan();
            },

            hideSpan: function () {
                this.jqueryNode.find('span').css('display', 'none');
//                $("#" + this.id + "_dropDown").css("margin-top", "-12px");
            },

            addRequisite: function () {
                this.jqueryNode.find('input').addClass('adore_InputRequisite');
                this.jqueryNode.find("label").addClass('adore_requisiteColor');
                this.iconNode.addClass('adore_requisiteColor');
            },

            _setFocus: function () {
                var dropDownNode = $("#" + this.id + "_dropDown");
                if (this.jqueryNode.find("input")[0] !== document.activeElement && dropDownNode.css("display") !== "block") {
                    this.jqueryNode.find("input").focus();
                }
            },

            _setIcon: function (attrs) {
                this.iconNode.addClass(attrs.icon);
                if (attrs.icon) {
                    this.hadIcon = true;
                    // this.dropDownArrow.css("right", "-30px");
                } else {
                    // this.dropDownArrow.css("right", "0");
                    this.hadIcon = false;
                }
                if (this.jqueryNode.find("input").val().length > 0) {
                    this.jqueryNode.find("input").siblings('label').addClass('active');
                    this.iconNode.addClass("active");
                }
                this.jqueryNode.find('span').addClass('span_prefix');
            },

            _dispose: function () {
                $(document).unbind("click." + this.id);
                base._dispose.call(this);
                $("#" + this.id + "_dropDown").remove();
            },

            handleKeyDown: function (e, widgetId) {
                var dropDown = $("#" + widgetId + "_dropDown");
                var dis = dropDown.css("display");

                if (e.keyCode === Keys.BACKSPACE) {
                    this.textCode.val("");
                    this.checkRequisite();
                    return;
                }

                if (!dis || dis === "none") {
                    if (e.keyCode === Keys.DOWN_ARROW) {
                        // 还未弹出dropDown时按了down键
                        this.showDropDown(e, widgetId);
                        e.preventDefault();
                    }
                    return;
                }
                var items = dropDown.find("li");
                if (items.length === 0) {
                    return;
                }
                var currentIndex = parseInt(dropDown.attr("currentIndex"));
                //上
                if (e.keyCode === Keys.UP_ARROW) {
                    if (currentIndex === -1) {
                        currentIndex = items.length - 1;
                    } else {
                        currentIndex--;
                    }
                    items.css("background-color", "#FFFFFF");
                    if (currentIndex < 0) {
                        currentIndex = -1;
                    } else {
                        $(items[currentIndex]).css("background-color", "#BEBEBE");
                        // $(this).val($(items[currentIndex]).text().split(" ")[0]);
                    }
                    this.refreshScroll(dropDown, currentIndex);
                    e.preventDefault();
                }
                // 下
                else if (e.keyCode === Keys.DOWN_ARROW) {
                    currentIndex++;
                    items.css("background-color", "#FFFFFF");
                    if (currentIndex >= items.length) {
                        currentIndex = -1;
                    } else {
                        $(items[currentIndex]).css("background-color", "#BEBEBE");
                        // $(this).val($(items[currentIndex]).text().split(" ")[0]);
                    }
                    this.refreshScroll(dropDown, currentIndex);
                    e.preventDefault();
                }
                // enter
                else if (e.keyCode === Keys.ENTER) {
                    dropDown.css("display", "none");
                    $("#" + widgetId + "_a").css("display", "none");
                    if (currentIndex >= 0 && currentIndex < items.length) {
                        //console.log("Enter click,text["+$(items[currentIndex]).text()+"]");
                        this._setText({text: $(items[currentIndex]).text().trim()});
                        this.checkRequisite();
                        //this.sendFocusGain();
                        EventHub.dispatchEvent(EventHub.MSG_TYPE.WIDGET, {
                            id: widgetId,
                            selectedIndex: $(items[currentIndex]).attr("index"),
                            evtType: EventHub.ON_CHANGE
                        });//
                        EventHub.dispatchEvent(EventHub.MSG_TYPE.WIDGET, {
                            id: widgetId,
                            selectedIndex: $(items[currentIndex]).attr("index"),
                            evtType: EventHub.SELECTION
                        });//
                    }
                    e.preventDefault();
                }
                dropDown.attr("currentIndex", currentIndex + "");
            },

            refreshScroll: function (dropDown, currentIndex) {
                if (currentIndex === -1) {
                    return;
                }
                var count = dropDown.find("li").length - 1;
                var needRefresh = false;
                /**判断当前下标对应的li是否已经不在可视滚动区域内,若不在，需要刷新滚动条的位置**/
                if (currentIndex < this.scrollIndexs[0]) {
                    // 6 10 currentIndex:5
                    var endIndex = currentIndex + this.maxShowItems - 1;
                    endIndex = endIndex > count ? count : endIndex;
                    this.scrollIndexs = [currentIndex, endIndex];
                    needRefresh = true;
                } else if (currentIndex > this.scrollIndexs[1]) {
                    var beginIndex = currentIndex - this.maxShowItems + 1;
                    beginIndex = beginIndex < 0 ? 0 : beginIndex;
                    this.scrollIndexs = [beginIndex, currentIndex];
                    needRefresh = true;
                }
                if (needRefresh) {
                    var h = dropDown.find("li").height();
                    dropDown[0].scrollTop = h * this.scrollIndexs[0];
                }
            },

            showDropDown: function (e, widgetId) {
                if (this.jqueryNode.find("input").attr("disabled")) {
                    return;
                }
                this.sendFocusGain();
                this.scrollIndexs = [0, this.maxShowItems - 1];//重置滚动区域的可视下标[beginIndex,endIndex]
                var textCode = $("#" + widgetId + "_input");
                var width = textCode.width();
                var height = textCode.height();
                // 把原来dropDown remove掉
                $("#" + widgetId + "_dropDown").remove();
                // 添加 dropDown
                var dropDown = $(this.templates[1]).attr("id", widgetId + "_dropDown");
                dropDown.attr({mouseOn: "false"});
                dropDown.appendTo(this.jqueryNode);


                //dropDown.css("top", tmpHeight);
                //dropDown.css("left", pos[1]);
                dropDown.attr("currentIndex", "-1");
                if (this.hadIcon) {
                    dropDown.css("margin-left", " 3rem");
                }
                //添加列表
                var liNode;
                if (this.datas) {
                    for (var i = 0; i < this.datas.length; i++) {
                        liNode = $(this.templates[2]).attr("index", i + "");
                        liNode.find("a").text(this.datas[i]);
                        liNode.appendTo(dropDown);
                    }
                }

                var len = dropDown.find("li").length;
                if (len > 0) {
                    // 为每个列表添加click事件
                    var tmpId = widgetId;
                    var own = this;
                    dropDown.find("li").find("a").on("click", function (e) {
                        var value = $(this).text().trim();
                        $("#" + tmpId + "_dropDown").css("display", "none");
                        own._setText({text: value});
                        own.checkRequisite();
                        // dispatch onChange event
                        EventHub.dispatchEvent(EventHub.MSG_TYPE.WIDGET, {
                            id: tmpId,
                            selectedIndex: $(this.parentNode).attr("index"),
                            evtType: EventHub.ON_CHANGE
                        });//
                        EventHub.dispatchEvent(EventHub.MSG_TYPE.WIDGET, {
                            id: tmpId,
                            selectedIndex: $(this.parentNode).attr("index"),
                            evtType: EventHub.SELECTION
                        });//
                    });
                    /**
                     * 添加mouseover和mouseout事件，解决为input添加blur事件后不能选中选项的问题
                     * */
                    dropDown.on("mouseover", function (e) {
                        dropDown.attr("mouseOn", "true");
                    });
                    dropDown.on("mouseout", function (e) {
                        dropDown.attr("mouseOn", "false");
                    });
                    //弹出dropDown
                    dropDown.css("display", "block");


                    //设置宽度
                    dropDown.css("width","135px");
                    if(dropDown.width() < width) {
                        dropDown.css("width", width);
                    }
                    //this.textCode.focusin();
                    //dropDown.focus();
                    if (this.jqueryNode.find('span').css("display") === "block") {
                        dropDown.css("margin-top", "-21px");
                    }
                    // 若超出最大显示条数，设置最大高度
                    if (len > this.maxShowItems) {
                        var h = $(dropDown.find("li")[0]).height();
                        var maxHeight = h * this.maxShowItems;
                        dropDown.css("height", maxHeight);
                    }
                    var dropdown_offsetTop = 0;
                    var container_offsetTop = 0;
                    var container_height = 0;
                    var limit_height = 0;
                    var $node = this.jqueryNode;

                    dropdown_offsetTop = dropDown.offset().top + 15;
                    dropDown.addClass("adore_dropDown_show");


                    while (1) {
                        var tagname = $node.get(0).tagName;
                        if(tagname.match("BODY") !== null) {
                            container_height = $node.height();
                            break;
                        }
                        var id_str = $node.attr("id");
                        if(typeof(id_str) !== "undefined") {
                            if(id_str.match("AdoreShell") !== null) {
                                container_offsetTop = $node.offset().top;
                                container_height = $node.height();
                                break;
                            }
                        }
                        $node = $node.parent();
                    }

                    limit_height = container_height + container_offsetTop - dropdown_offsetTop;
                    if(dropDown.height() > limit_height) {
                        var top_length = dropDown.height() - limit_height + 25;
                        var str_length = "-" + top_length + "px";
                        dropDown.css("margin-top", str_length);
                    }








                    $(document).bind('click.' + widgetId + "_dropDown", function (e) {
                        var arrow = $("#" + widgetId + "_arrow");
                        if (!dropDown.is(e.target) && !arrow.is(e.target)) {
                            own.handleOnBlur();
                            $(document).unbind('click.' + widgetId + "_dropDown");
                        }
                    });
                } else {
                    dropDown.css("display", "none");
                }
            },

            _handleKeyDownEvent: function (e, hasFilter) {
                if (this.handleKeyEvent(e)) {
                    base._handleKeyDownEvent.call(this, e, hasFilter);
                }
            },

            _handleKeyUpEvent: function (e) {
                if (this.handleKeyEvent(e)) {
                    base._handleKeyUpEvent.call(this, e);
                }
            },

            handleKeyEvent: function (e) {
                if ($("#" + this.id + "_dropDown").css("display") === "block") {
                    return false;
                }
                //任何情况下都不处理down_arrow，因为该键是触发DropDown的弹出
                if (e.keyCode === Keys.DOWN_ARROW) {
                    return false;
                }
                return true;
            }
        };
    });
})