/*
 * 特别声明：本技术材料受《中华人民共和国著作权法》、《计算机软件保护条例》等法律、法规、行政
 * 规章以及有关国际条约的保护，赞同科技享有知识产权、保留一切权利并视其为技术秘密。未经本公司书
 * 面许可，任何人不得擅自（包括但不限于：以非法的方式复制、传播、展示、镜像、上载、下载）使用，
 * 不得向第三方泄露、透露、披露。否则，本公司将依法追究侵权者的法律责任。特此声明！
 *
 * 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 huangdeyun on 2015/4/8.
 */
define(["adoreapp/widget/BaseWidget"
    , "adoreapp/widget/EventHub"
    , "adoreapp/hotkey/Keys"], function (BaseWidget, EventHub, Keys) {

    var currentIndex = -1;

    return BaseWidget.extend(function (base) {
        return {
            _initWidget: function (attrs) {
                var template = attrs.template;
                this.templates = template.split("<!-- split -->");
                this.datas = [];
                this.maxShowItems = 5;//最大显示条数，默认5
                this.expandableTextId = this.id;
                this.jqueryNode = $(this.templates[0]).attr("id", 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);

                var own = this;
                //add listener
                this.textCode.on("input", function (e) {
                    own.handleInput(e, $(this).val());
                });
                this.textCode.on("keydown", function (e) {
                    own.handleKeyDown(e);
                });
                this.textCode.on("blur", function (e) {
                    own.handleBlur(e);
                });
                this.textCode.on("focus",function(e){
                    own.sendFocusGain();
                });
            },

            _setText: function (attrs) {
                this.textCode.val(attrs.text);
            },

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

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

            _layout: function () {
                base._layout.call(this);
            },

            _dispose: function () {
                base._dispose.call(this);
                $("#" + this.expandableTextId + "_dropDown").remove();
            },

            handleFocus: function (e, value) {
                this.showDropDown(e, value, true);
            },

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

            handleBlur: function (e) {
                var mouseOn = $("#" + this.expandableTextId + "_dropDown").attr("mouseOn");
                if (mouseOn === "false") {
                    $("#" + this.expandableTextId + "_dropDown").css("display", "none");
                }
            },

            handleKeyDown: function (e) {
                var dropDown = $("#" + this.expandableTextId + "_dropDown");
                var dis = dropDown.css("display");
                // 还未弹出dropDown，忽略
                if (!dis || dis === "none") {
                    if(e.keyCode === Keys.DOWN_ARROW){
                        this.showDropDown(e,"",true);
                    }
                    return;
                }
                var items = dropDown.find("li");
                if (items.length === 0) {
                    return;
                }
                //上
                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.textCode.val($(items[currentIndex]).find("a").text().split(" ")[0]);
                    }
                    this.refreshScroll(dropDown, currentIndex);
                    e.preventDefault();
                    return;
                }
                // 下
                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.textCode.val($(items[currentIndex]).find("a").text().split(" ")[0]);
                    }
                    this.refreshScroll(dropDown, currentIndex);
                    e.preventDefault();
                    return;
                }
                // enter
                else if (e.keyCode === Keys.ENTER || e.keyCode === Keys.NUMPAD_ENTER) {
                    dropDown.css("display", "none");
                    if (currentIndex >= 0 && currentIndex < items.length) {
                        var text = $(items[currentIndex]).find("a").text();
                        var val = text.split(" ")[0];
                        this.textCode.val(val);
                        // dispatch modify event
                        EventHub.dispatchEvent(EventHub.MSG_TYPE.WIDGET, {id: this.id, text: val, evtType: EventHub.MODIFY});
                        // dispatch click event
                        EventHub.dispatchEvent(EventHub.MSG_TYPE.WIDGET, {id: this.id, evtType: EventHub.CLICK});
                    }
                }
            },

            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];
                }
            },

            handleInput: function (e, value) {
                // dispatch modify event
                var tmpId = this.expandableTextId;
                EventHub.dispatchEvent(EventHub.MSG_TYPE.WIDGET, {id: tmpId, text: value, evtType: EventHub.MODIFY});
                this.showDropDown(e, value.toLocaleLowerCase(), false);
            },

            getPosition: function (obj) {
                var pos = [0, 0];
                if (obj && obj.offsetParent) {
                    while (obj && obj.offsetParent) {
                        pos[0] += obj.offsetTop;
                        pos[1] += obj.offsetLeft;
                        obj = obj.offsetParent;
                    }
                }
                return pos;
            },

            _setPlaceholder: function (attrs) {
                this.jqueryNode.find("input").attr("placeholder", attrs.placeholder);
            },

            showDropDown: function (e, value, showAll) {
                var textCode = $("#" + this.expandableTextId + "_input");
                var width = textCode.width();// textCode width
                var height = textCode.height();
                this.scrollIndexs = [0, this.maxShowItems - 1];//重置滚动区域的可视下标[beginIndex,endIndex]
                //height = Number(height.replace("px", ""));
                var pos = this.getPosition(textCode[0]);
                var tmpHeight = height + pos[0] + 14;
                // 把原来dropDown remove掉
                $("#" + this.expandableTextId + "_dropDown").remove();
                // 添加 dropDown
                var dropDown = $(this.templates[1]).attr("id", this.expandableTextId + "_dropDown");
                dropDown.attr({mouseOn: "false"});
                dropDown.appendTo(document.body);

                //设置宽度
                dropDown.css("width", width);
                dropDown.css("top", tmpHeight);
                dropDown.css("left", pos[1]);
                currentIndex = -1;
                //添加列表
                var liNode;
                if (this.datas) {
                    if (showAll === true && value === "") {
                        for (var i = 0; i < this.datas.length; i++) {
                            liNode = $(this.templates[2]);
                            liNode.find("a").text(this.datas[i]);
                            liNode.appendTo(dropDown);
                        }
                    }
                    else if (value != "") {
                        for (var i = 0; i < this.datas.length; i++) {
                            if (this.datas[i].toLocaleLowerCase().indexOf(value) >= 0) {
                                liNode = $(this.templates[2]);
                                liNode.find("a").text(this.datas[i]);
                                liNode.appendTo(dropDown);
                            }
                        }
                    }
                }
                var len = dropDown.find("li").length;
                var inputNode = this.textCode;
                if (len > 0) {
                    // 为每个列表添加click事件
                    var tmpId = this.expandableTextId;
                    dropDown.find("li").find("a").on("click", function (e) {
                        var value = $(this).text();
                        var newValue = value.split(" ")[0];
                        $("#" + tmpId + "_input").val(newValue);
                        $("#" + tmpId + "_dropDown").css("display", "none");
                        // dispatch modify event
                        EventHub.dispatchEvent(EventHub.MSG_TYPE.WIDGET, {id: tmpId, text: newValue, evtType: EventHub.MODIFY});
                        // dispatch click event
                        EventHub.dispatchEvent(EventHub.MSG_TYPE.WIDGET, {id: tmpId, evtType: EventHub.CLICK});
                    });
                    /**
                     * 添加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");
                    // 若超出最大显示条数，设置最大高度
                    if (len > this.maxShowItems) {
                        var h = $(dropDown.find("li")[0]).height();
                        var maxHeight = h * this.maxShowItems;
                        dropDown.css("height", maxHeight);
                    }
                    var own = this;
                    var tmpId = this.expandableTextId;
                    $(document).bind('click.' + this.expandableTextId + "_dropDown", function (e) {
                        if ((!dropDown.is(e.target) && !inputNode.is(e.target)) || dropDown.css("display") === "none") {
                            dropDown.css("display", "none");
                            $(document).unbind('click.' + tmpId + "_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;
                }
                if (e.keyCode === Keys.TAB || e.keyCode === Keys.ENTER || e.keyCode === Keys.NUMPAD_ENTER) {
                    return true
                }
                return false;
            }
        }
    })
})