/*
 * 特别声明：本技术材料受《中华人民共和国著作权法》、《计算机软件保护条例》等法律、法规、行政
 * 规章以及有关国际条约的保护，赞同科技享有知识产权、保留一切权利并视其为技术秘密。未经本公司书
 * 面许可，任何人不得擅自（包括但不限于：以非法的方式复制、传播、展示、镜像、上载、下载）使用，
 * 不得向第三方泄露、透露、披露。否则，本公司将依法追究侵权者的法律责任。特此声明！
 *
 * 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.
 */
import {Widget} from "widget/Widget";
import {Event as AdoreEvent} from "event/Event";
import {MessageType} from "event/MessageType";
import {EventHub} from "event/EventHub";
import {Keys} from "hotkey/Keys";
/// <reference path="../typings/jquery.d.ts" />
/**
 * Created by tangqianchong on 2016/6/2.
 */

export class Select extends Widget {

    private static Template = `
    <div class="input-field">
        <i class="icon_normal"></i>
        <i class="mdi-navigation-arrow-drop-down adore_select_arrow"></i>
        <input type="text">
        <label></label>
        <span class="span_base"></span>
    </div>`;

    private static TemplateDropdown = `<ul class= "adore_dropDown dropdown-content"></ul>`;
    private static TemplateLi = `
        <li>
            <a href='#!' class="waves-effect"></a>
        </li>`;

    private $iconNode: JQuery;
    private $dropDownArrow: JQuery;
    private isLayout: boolean = false;
    private hadIcon: boolean = false;
    private datas: Array<string>;
    private selectDatas: Array<string>;
    private maxShowItems: number = 6; //最大显示条数，默认6
    private $textCode: JQuery;
    private scrollIndexs: Array<number>;
    private requisite: boolean;
    private focusLostFromText_DropDownShow_ArrowFocus = false;
    private focusLostFromText_DropDownShow = false;
    constructor(parentId: string, id: string, style: number) {
        super(parentId, id, style);
        this.$thisNode = $(Select.Template).attr("id", this.id);

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

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

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

        // 这份数据是由java传送过来的
        this.datas = [];
        // 这份数据是由于模糊查询造成的
        this.selectDatas = new Array();
        this.maxShowItems = 6;//最大显示条数，默认6
        this.scrollIndexs = [0, this.maxShowItems - 1];//重置滚动区域的可视下标[beginIndex,endIndex]


        let own = this;
        let widgetId = this.id;
        //add listener
        this.$dropDownArrow.on("click", function (e: any) {
            var show = !own.isDropDownShow();
            if (show) {
                // 焦点至到文本框中
                own.$textCode.focus();
            }
            // 需要展示下拉框
            own.showDropDown(widgetId, show,!show);
        });

        this.$textCode.on("keydown", function (e: any) {
            own.handleKeyDown(e as KeyboardEvent, own.id);
        });
        this.$textCode.on("blur", function (e) {
            // 如果焦点是从文本框切换过来的，那就不需要触发onBlur事件
            if(!own.focusLostFromText_DropDownShow){
                own.handleOnBlur();
            }
        });
        this.$textCode.on("focus", function (e) {
            // 获取焦点应该选中文本
            own.$textCode.select();
            // 当前下拉框获取到焦点
            own.sendFocusGain();
        });
        this.$textCode.on("input", function (e) {
            own.handleInput(e);
        });
    }


    public setItems(args: { items: Array<string> }) {
        this.datas = args.items;
        // 清除掉数据
        this.selectDatas.splice(0, this.selectDatas.length);
        for (let i = 0; i < this.datas.length; i++) {
            this.selectDatas.push(this.datas[i]);
        }
    }

    public handleMouseDownEvent(e: MouseEvent) {
        /**
         * 鼠标单击下去的时候，如果当前的焦点正在文本框中，并且接下来焦点会落到下拉框的按钮中，那么不需要触发onBlur事件
         */
        this.focusLostFromText_DropDownShow = null;
        if (document.activeElement === this.$textCode.get(0) && this.isDropDownShow()) {
            this.focusLostFromText_DropDownShow = true;
        } else {
            this.focusLostFromText_DropDownShow = false;
        }
        super.handleMouseDownEvent(e);
    }

    public handleMouseUpEvent(e: MouseEvent) {
        // 能够从mouseDown和mouseUp中看出焦点的转移
        this.focusLostFromText_DropDownShow = false;
        super.handleMouseUpEvent(e);
    }


    private handleInput(e: BaseJQueryEventObject) {
        // 获取值
        var value = this.$textCode.val();
        // 过滤下拉选项
        this.filterItems(value);
        // 重新显示下拉列表
        this.showDropDown(this.id, true,false);
    }

    private handleOnBlur() {
        let value = this.$textCode.val();
        this.setText({ text: value });
        this.checkRequisite();
        let mouseOn = $("#" + this.id + "_dropDown").attr("mouseOn");
        if (mouseOn === "false") {
            this.showDropDown(this.id, false,false);
        }
    }

    public setName(args: { name: string }) {
        let name = args.name;
        this.$thisNode.find("label").text(name);
    }

    public setEnabled(args: { enabled: boolean }) {
        super.setEnabled(args);
        let input = this.$thisNode.find("input");
        if (this.enabled) {
            input.removeAttr("disabled");
            this.$thisNode.find("i").removeClass("icon_disabled");
            if (this.requisite) {
                if (input.val() == null || input.val() === "") {
                    this.addRequisite();
                }
            }
        } else {
            this.$thisNode.find("input").attr("disabled", "disabled");
            if (this.requisite) {
                this.removeRequisite();
            }
            this.$thisNode.find("i").addClass("icon_disabled");
        }
    }

    public postLayout() {
        this.isLayout = true;
        if (this.requisite) {
            this.setRequisite({ requisite: true });
        }
    }

    public setText(args: { text: string }) {
        let inputNode = this.$thisNode.find("input");
        inputNode.val(args.text);
        if (args.text.length > 0) {
            inputNode.siblings('label').addClass('active');
            this.$iconNode.addClass("active");
        } else {
            inputNode.siblings('label').removeClass('active');
            this.$iconNode.removeClass("active");
        }
        if ((args.text == null || args.text === "") && this.requisite) {
            this.addRequisite();
        } else {
            this.removeRequisite();
        }
    }

    private checkRequisite() {
        if (this.requisite) {
            let inputSelector = this.$thisNode.find('input');
            let value = inputSelector.val();
            if (value) {
                this.removeRequisite();
            } else {
                this.addRequisite();
                this.showSpan('请输入数据!');
            }
        }
    }


    private showSpan(msg: string) {
        if(this.$thisNode.find('span').css("display")==="none" ){
            this.$thisNode.find('span').html(msg).show().delay(2000).fadeOut(300);
        }
        $("#" + this.id + "_dropDown").css("margin-top", "-21px");
    }

    public setRequisite(args: { requisite: boolean }) {
        this.requisite = args.requisite;
        if (!this.isLayout) {
            return;
        }
        if (this.requisite) {
            if (this.$thisNode.find('input').val()) {
                this.removeRequisite();
            } else {
                this.addRequisite();
            }
        }
    }

    private removeRequisite() {
        this.$thisNode.find('input').removeClass('adore_InputRequisite');
        this.$thisNode.find("label").removeClass('adore_requisiteColor');
        this.$iconNode.removeClass('adore_requisiteColor');
        this.hideSpan();
    }

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

    private addRequisite() {
        this.$thisNode.find('input').addClass('adore_InputRequisite');
        this.$thisNode.find("label").addClass('adore_requisiteColor');
        this.$iconNode.addClass('adore_requisiteColor');
    }

    public setFocus() {
        let dropDownNode = $("#" + this.id + "_dropDown");
        if (this.$thisNode.find("input")[0] !== document.activeElement && dropDownNode.css("display") !== "block") {
            this.$thisNode.find("input").focus();
        }
    }

    public setIcon(args: { icon: string }) {
        this.$iconNode.addClass(args.icon);
        if (args.icon) {
            this.hadIcon = true;
            // this.dropDownArrow.css("right", "-30px");
        } else {
            // this.dropDownArrow.css("right", "0");
            this.hadIcon = false;
        }
        if (this.$thisNode.find("input").val().length > 0) {
            this.$thisNode.find("input").siblings('label').addClass('active');
            this.$iconNode.addClass("active");
        }
        this.$thisNode.find('span').addClass('span_prefix');
    }

    public dispose() {
        $(document).unbind("click." + this.id);
        super.dispose();
        $("#" + this.id + "_dropDown").remove();
    }

    private handleKeyDown(e: KeyboardEvent, widgetId: string) {
        let dropDown = $("#" + widgetId + "_dropDown");
        let dis = dropDown.css("display");
        if (e.keyCode === Keys.BACKSPACE) {
            return;
        }

        if ((!dis || dis === "none") && e.keyCode !== Keys.ENTER ) {
            if (e.keyCode === Keys.DOWN_ARROW || e.keyCode === Keys.SPACE) {
                // 还未弹出dropDown时按了down键
                this.showDropDown(widgetId, true,false);
                e.preventDefault();
                e.stopPropagation();
            }
            return;
        }
        let items = dropDown.find("li");
        let 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.setText({ text: this.selectDatas[currentIndex] });
                // $(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.setText({ text: this.selectDatas[currentIndex] });
                // $(this).val($(items[currentIndex]).text().split(" ")[0]);
            }
            this.refreshScroll(dropDown, currentIndex);
            e.preventDefault();
        }
        // enter
        else if (e.keyCode === Keys.ENTER) {
            if (currentIndex >= 0 && currentIndex < items.length) {
                this.setText({ text: $(items[currentIndex]).text().trim() });
                this.checkRequisite();
            }
            this.showDropDown(this.id, false,true);
            e.preventDefault();
            e.stopPropagation();
        }
        dropDown.attr("currentIndex", currentIndex + "");
    }

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

    private showDropDown(widgetId: string, show: boolean,changedFocus : boolean) {
        if (this.$thisNode.find("input").attr("disabled")) {
            return;
        }
        let isDropDownShow = this.isDropDownShow();
        if (!show) {
            // if (isDropDownShow) {
            $("#" + widgetId + "_dropDown").css("display", "none");
            // }
            this.handleModify(changedFocus);
            return;
        }
        // this.sendFocusGain();
        let textCode = $("#" + widgetId + "_input");
        let width = textCode.width();
        let height = textCode.height();
        // 把原来dropDown remove掉
        $("#" + widgetId + "_dropDown").remove();
        // 添加 dropDown
        let dropDown = $(Select.TemplateDropdown).attr("id", widgetId + "_dropDown");
        dropDown.attr({ mouseOn: "false" });
        dropDown.appendTo(this.$thisNode);

        dropDown.attr("currentIndex", "-1");
        dropDown.attr("currentIndex", "-1");
        if (this.hadIcon) {
            dropDown.css("margin-left", " 3rem");
        }
        //添加列表
        let liNode: JQuery;
        if (this.selectDatas) {
            for (let i = 0; i < this.selectDatas.length; i++) {
                liNode = $(Select.TemplateLi).attr("index", i + "");
                liNode.find("a").text(this.selectDatas[i]);
                liNode.appendTo(dropDown);
            }
        }

        let len = dropDown.find("li").length;
        if (len > 0) {
            // 为每个列表添加click事件
            let tmpId = widgetId;
            let own = this;
            dropDown.find("li").find("a").on("click", function (e) {
                let value = $(this).text().trim();
                own.setText({ text: value });
                own.checkRequisite();
                own.showDropDown(tmpId, false,true);
            });
            /**
             * 添加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.$thisNode.find('span').css("display") === "block") {
                dropDown.css("margin-top", "-21px");
            }
            // 若超出最大显示条数，设置最大高度
            if (len > this.maxShowItems) {
                let h = $(dropDown.find("li")[0]).height();
                let maxHeight = h * this.maxShowItems;
                dropDown.css("height", maxHeight);
            }
            let dropdown_offsetTop = 0;
            let container_offsetTop = 0;
            let container_height = 0;
            let limit_height = 0;
            let $node = this.$thisNode;

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


            while (1) {
                let tagname = $node.get(0).tagName;
                if (tagname.match("BODY") !== null) {
                    container_height = $node.height();
                    break;
                }
                let 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) {
                let top_length = dropDown.height() - limit_height + 25;
                let str_length = "-" + top_length + "px";
                dropDown.css("margin-top", str_length);
            }

        } else {
            dropDown.css("display", "none");
        }
    }

    public handleKeyDownEvent(e: KeyboardEvent, hasFilter: boolean) {
        if (this.handleKeyEvent(e)) {
            super.handleKeyDownEvent(e, hasFilter);
        }
    }

    public handleKeyUpEvent(e: KeyboardEvent) {
        if (this.handleKeyEvent(e)) {
            super.handleKeyUpEvent(e);
        }
    }

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

    private getSelectedIndex(selectedText: string) {
        if (!selectedText || selectedText === "") {
            return -1;
        } else {
            for (let i = 0; i < this.datas.length; i++) {
                if (this.datas[i].indexOf(selectedText) != -1) {
                    return i;
                }
            }
            return -1;
        }
    }

    private handleModify(changedFocus : boolean) {
        let selectedText = this.$textCode.val();
        let selectedIndex = this.getSelectedIndex(selectedText);
        if (selectedIndex >= 0) {
            this.setText({ text: this.datas[selectedIndex] })
        } else {
            this.setText({ text: "" });
        }
        EventHub.dispatchEvent(MessageType.WIDGET, {
            id: this.id,
            selectedIndex: selectedIndex + "",
            changedFocus : changedFocus + "" ,
            evtType: AdoreEvent.ON_CHANGE
        });//
        // reset
        this.reset();
    }

    // 下拉列表是否展开
    private isDropDownShow() {
        let $dropDownNode = $("#" + this.id + "_dropDown");
        if ($dropDownNode) {
            var dis = $dropDownNode.css("display");
            if (dis) {
                if (dis === "block") return true;
            }
        }
        return false;
    }

    private refreshDropDownItemBGC(selectedIndex: number) {
        let $dropDown = $("#" + this.id + "_dropDown");
        let $items = $dropDown.find("li");
        $items.css("background-color", "#FFFFFF");
        if (selectedIndex < 0) {
        } else {
            $($items[selectedIndex]).css("background-color", "#BEBEBE");
        }
    }

    private filterItems(filterText: string) {
        // 过滤下拉选项
        this.selectDatas.splice(0, this.selectDatas.length);
        for (let i = 0; i < this.datas.length; i++) {
            if (this.datas[i].indexOf(filterText) != -1) {
                this.selectDatas.push(this.datas[i]);
            }
        }
    }

    private reset() {
        // 重置selectDatas
        this.selectDatas.splice(0, this.selectDatas.length);
        for (let i = 0; i < this.datas.length; i++) {
            this.selectDatas.push(this.datas[i]);
        }
    }

}