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

/**
 * Created by heweijun on 2016/6/20.
 */

export class CustomQueue extends Widget {

    private static TemplateCotainer: string = `<div class="row"></div>`;
    private static TemplateQueue: string = `
            <div class="col s6 m4 l3 custom_queue_container">
                <div class="custom_queue_container_second">
                    <p class="custom_queue_id"><!--A001--></p>

                    <div class="custom_queue_roundness" lookOver>
                        <p class="custom_queue_roundness_header_p">已等待时间</p>

                        <p class="custom_queue_roundness_header_p custom_queue_wait_time"><!--x分钟--></p>

                        <div class="custom_queue_roundness_middle_div">
                        </div>

                        <p class="custom_queue_roundness_footer_p">取号时间</p>

                        <p class="custom_queue_roundness_footer_p custom_queue_get_no_time"><!--12:09:11--></p>
                    </div>

                    <div class="custom_queue_body" lookOver>
                        <p class="custom_queue_name"><!--马志<img src="images/custom_queue/man.png"
                                                style="margin-top:-5px;"/>--></p>
                    </div>
                    <p class="custom_queue_custom_level">客户等级：普通客户<img
                        src="images/custom_queue/custom_level/putong.png"/></p>

                    <div class="custom_queue_business_flag">
                    </div>

                    <p class="custom_queue_footer"><img src="images/custom_queue/tiaozheng.png"/>调整</p>
                </div>
            </div>`;
    private static TemplateImage = `<img/>`;

    constructor(parentId: string, id: string, style: number) {
        super(parentId, id, style);
        this.$thisNode = $(CustomQueue.TemplateCotainer).attr({ id: this.id });
    }

    /**
     * @item{queue_num:"",waitting:"",en_queue_time:"",name:"",sex:"",customLevel:"",businessFlag:""}
     */
    public addItems(args: { items: { queue_num: string, waitting: string, en_queue_time: string, name: string, sex: string, customLevel: string, businessFlag: string }[] }) {
        let items = args.items;
        if (!items || items.length === 0) {
            return;
        }
        for (let i = 0; i < items.length; i++) {
            if (items[i].queue_num) {
                if (this.$thisNode.find("#" + items[i].queue_num).length !== 0) {
                    this.setItem(items[i]);
                } else {
                    this.addItem(items[i]);
                }
            }
        }
        //重置移动监听器
        this.setListeners();
    }

    public setItems(args: { items: { queue_num: string, waitting: string, en_queue_time: string, name: string, sex: string, customLevel: string, businessFlag: string }[] }) {
        let items = args.items;
        this.clear(); //先刪除所有
        this.addItems({ items: items });
        //重置移动监听器
        this.setListeners();
    }

    private setItem(item: { queue_num: string, waitting: string, en_queue_time: string, name: string, sex: string, customLevel: string, businessFlag: string }) {
        let itemNode = this.$thisNode.find("#" + item.queue_num);
        this.setCustomAttr(itemNode, item);
    }

    private addItem(item: { queue_num: string, waitting: string, en_queue_time: string, name: string, sex: string, customLevel: string, businessFlag: string }) {
        let itemNode = $(CustomQueue.TemplateQueue).attr({ id: item.queue_num });
        itemNode.appendTo(this.$thisNode);
        this.setCustomAttr(itemNode, item);
        let own = this;
        // 添加调整事件(底层用click)
        itemNode.find("p.custom_queue_footer").on("click", function (e) {
            let index = own.indexOf(itemNode[0]);
            let queueNO = itemNode.attr("id");
            EventHub.dispatchEvent(MessageType.WIDGET, {
                id: own.id,
                evtType: Event.CLICK,
                index: index,
                queue_num: queueNO
            });
        });
        //添加查看客户事件
        itemNode.find("div[lookOver]").on("click", function (e) {
            let index = own.indexOf(itemNode[0]);
            let queueNO = itemNode.attr("id");
            EventHub.dispatchEvent(MessageType.WIDGET, {
                id: own.id,
                evtType: Event.LOOK_OVER,
                index: index,
                queue_num: queueNO
            });
        });
    }

    private indexOf(item: HTMLElement): number {
        let items = this.$thisNode.find("div.custom_queue_container");
        for (let i = 0; i < items.length; i++) {
            if (item === items[i]) {
                return i;
            }
        }
        return -1;
    }

    private setCustomAttr(itemNode: JQuery, item: { queue_num: string, waitting: string, en_queue_time: string, name: string, sex: string, customLevel: string, businessFlag: string }) {
        //设置id、等待时间、取号时间
        itemNode.find(".custom_queue_id").text(item.queue_num);
        itemNode.find(".custom_queue_wait_time").text(item.waitting + "分钟");
        if (item.en_queue_time) {
            itemNode.find(".custom_queue_get_no_time").text(item.en_queue_time);
        }
        //设置姓名性别
        let customNameNode = itemNode.find(".custom_queue_name");
        if (item.name) {
            customNameNode.text(item.name);
        }
        if (item.sex) {
            let customSex = $(CustomQueue.TemplateImage).appendTo(customNameNode);
            customSex.css({ marginTop: "-5px" });
            if (item.sex === "男" || item.sex === "man" || item.sex === "1") {
                customSex.attr("src", "images/custom_queue/man.png");
            } else {
                customSex.attr("src", "images/custom_queue/woman.png");
            }
        }
        // 设置客户等级
        if (item.customLevel) {
            let customLevelNode = itemNode.find(".custom_queue_custom_level");
            customLevelNode.text("客户等级：" + item.customLevel);
            let customLevelImg = $(CustomQueue.TemplateImage).appendTo(customLevelNode);
            if (item.customLevel === "黄金客户") {
                customLevelImg.attr("src", "images/custom_queue/custom_level/huangjin.png");
            } else if (item.customLevel === "白金客户") {
                customLevelImg.attr("src", "images/custom_queue/custom_level/baijin.png");
            } else if (item.customLevel === "钻石客户") {
                customLevelImg.attr("src", "images/custom_queue/custom_level/zuanshi.png");
            } else {
                customLevelImg.attr("src", "images/custom_queue/custom_level/putong.png");
            }
        }
        //设置业务标记
        if (item.businessFlag) {
            let imgArr = item.businessFlag.split(",");
            if (imgArr.length > 0) {
                let businessFlagNode = itemNode.find(".custom_queue_business_flag");
                businessFlagNode.find("img").remove();
                for (let i = 0; i < imgArr.length; i++) {
                    $(CustomQueue.TemplateImage).attr("src", "images/custom_queue/business_flag/" + imgArr[i] + ".png").appendTo(businessFlagNode);
                }
            }
        }
    }

    public removeItem(args: { itemIds: string[] }) {
        let ids = args.itemIds;
        if (ids && ids.length > 0) {
            for (let i = 0; i < ids.length; i++) {
                this.$thisNode.find("#" + ids[i]).remove();
            }
        }
        //重置移动监听器
        this.setListeners();
    }

    public clear() {
        this.$thisNode.find(".custom_queue_container").remove();
        //重置移动监听器
        this.setListeners();
    }

    //-- 下面是拖拽功能实现的逻辑 --//
    //Created by tangqianchong on 2016.8.22

    //是否已有元素被选中
    private isSelected: boolean = false;
    //被选中的元素的下标
    private selectedIndex: number;
    //被选中的元素的element
    private selectedUnit: HTMLDivElement;
    //保存之前元素的宽
    private selectedUnitWidth: number;
    //移动之后的元素下标
    private targetIndex: number;
    //保存所有的触发关键点位置的列表
    private movingControlPositions: Array<Position> = new Array<Position>();
    //验证距离
    private checkDistance: number = 60;
    //选中的待移动的坐标
    private animationUnit: JQuery;
    //保存窗口改变事件以进行清理
    private resizeFunction: any;

    //重写layout方法,在layout之后才进行setListeners()方法

    postLayout() {
        this.setListeners();
    }

    //去掉窗口大小变动的监听
    dispose() {
        $(window).off("resize", this.resizeFunction);
        super.dispose();
    }

    // 在每一次进行队列单元的改动时,调用此方法对所有对应对象添加监听器
    setListeners() {

        let own = this;
        //初始化控制数据

        own.isSelected = false;
        own.selectedIndex = null;
        own.selectedUnitWidth = null;
        own.selectedUnit = null;
        own.targetIndex = null;
        own.movingControlPositions = new Array();
        own.animationUnit = null;

        own.resizeFunction = function () {
            own.setListeners();
        };
        $(window).on("resize", own.resizeFunction);

        if (this.$thisNode.find(".custom_queue_container").length === 0) {
            return;
        }

        //直接在document内部进行元素获取
        let $units: JQuery = this.$thisNode.find("div.custom_queue_container");
        let $unitsContainer: JQuery = this.$thisNode;

        //获取关键位置信息组成列表
        $units.each(function (index: number, elem: HTMLDivElement) {
            let $elemNode: JQuery = $(elem);
            let position: Position = own.getUnitCenterPosition(elem);
            if ($elemNode.next().length < 0) {
                position.x = position.x + elem.clientWidth;
            }
            own.movingControlPositions.push(position);
        });

        //控制unit跟着鼠标走的方法
        let moveControl = function (e: MouseEvent) {
            if (own.isSelected) {
                if (own.selectedUnit.style.position !== "absolute") {
                    $(own.selectedUnit).addClass("selected");
                }
                own.selectedUnit.style.width = own.selectedUnitWidth + "px";
                own.selectedUnit.style.left = e.clientX - $unitsContainer.get(0).clientLeft
                    - own.selectedUnit.clientWidth / 2 + "px";
                own.selectedUnit.style.top = e.clientY - $unitsContainer.get(0).clientTop
                    - own.selectedUnit.clientHeight / 2 + "px";
            }
        };

        //对每个unit处理鼠标按下的逻辑
        $units.each(function (index: number, elem: HTMLDivElement) {
            elem.onmousedown = function (e: MouseEvent) {
                if (!own.isSelected) {
                    own.isSelected = true;
                    own.selectedIndex = index;
                    own.selectedUnit = elem;
                    own.selectedUnitWidth = elem.clientWidth;

                    moveControl(e);
                    //在移动下一个元素之前计算出所有的触发位置,当焦点接近该位置达到一定值时,触发打开动作
                    own.animationUnit = $(elem).next();
                    if (own.animationUnit.length > 0) {
                        own.animationUnit.removeClass("moveToLeft").addClass("moveToRight");
                    }

                    //被选中时才绑定放开事件
                    elem.onmouseup = function () {

                        //根据targetIndex进行对应的操作

                        //-1时,表示当前选中的位置在关键位置外,复原
                        if (own.targetIndex === -1) {
                            $units.removeClass("moveToLeft").removeClass("moveToRight").
                                removeClass("selected").removeClass("inPosition");
                        }
                        else if (own.targetIndex > -1) {
                            $units.removeClass("moveToLeft").removeClass("moveToRight").
                                removeClass("selected").removeClass("inPosition");
                            let $tempNode: JQuery = $(own.selectedUnit);
                            if (own.targetIndex > 0) {
                                $units.eq(own.targetIndex - 1).after($tempNode);
                            } else if (own.targetIndex === 0) {
                                $units.eq(0).before($tempNode);
                            }
                            EventHub.dispatchEvent(MessageType.WIDGET, {
                                id: own.id,
                                evtType: Event.ON_CHANGE,
                                originIndex: own.selectedIndex,
                                finalIndex: own.targetIndex
                            });
                        }
                        //结束后再删除element
                        //去掉长宽...
                        $units.css({
                            "width": "",
                            "left": "",
                            "top": ""
                        });
                        own.setListeners();
                        e.preventDefault();
                    };
                    e.preventDefault();
                }
            };
        });

        $unitsContainer.get(0).onmousemove = function (e: MouseEvent) {
            moveControl(e);

            //对焦点接近关键位置时的处理
            if (own.isSelected) {
                let targetIndex: number = own.getTargetIndex(e, own.checkDistance);
                if (targetIndex >= own.selectedIndex) {
                    targetIndex++;
                }
                //第一次的处理,赋值给own.targetIndex作为一个之前数据的保存和当前index作比较判断状态
                if (own.targetIndex === undefined) {
                    own.targetIndex = targetIndex;
                }
                //刚进入指定范围的情况
                if (own.targetIndex === -1 && targetIndex > -1) {
                    own.animationUnit = $units.eq(targetIndex);
                    $(own.selectedUnit).addClass("inPosition");
                    own.animationUnit.removeClass("moveToLeft").addClass("moveToRight");
                }
                //刚刚跳出指定方位的情况
                else if (own.targetIndex > -1 && targetIndex === -1) {
                    $(own.selectedUnit).removeClass("inPosition");
                    own.animationUnit.removeClass("moveToRight").addClass("moveToLeft");
                }

                own.targetIndex = targetIndex;
            }
            e.preventDefault();
        };
    }


    //根据传入的校验距离数据计算出鼠标焦点最接近的插入点的坐标,当值为-1时为没有符合条件的插入点
    private getTargetIndex(event: MouseEvent, checkDistance: number): number {
        let own = this;
        let minDistance: number = checkDistance;
        let index: number = 0;
        let rIndex: number = -1;
        for (let position of this.movingControlPositions) {
            let dX: number = event.clientX - position.x;
            let dY: number = event.clientY - position.y;
            let dDistance: number = Math.sqrt(Math.pow(dX, 2) + Math.pow(dY, 2));
            if (dDistance < checkDistance) {
                if (dDistance < minDistance) {
                    minDistance = dDistance;
                    rIndex = index;
                }
            }
            index++;
        }
        return rIndex;
    }

    //获取元素的 !中心! 坐标
    private getUnitCenterPosition(elem: HTMLDivElement): Position {
        let startX: number = elem.offsetLeft;
        let startY: number = elem.offsetTop;
        let width: number = elem.clientWidth;
        let height: number = elem.clientHeight;

        let centerPosition: Position = { x: startX + width / 2, y: startY + height / 2 };
        return centerPosition;
    }

    //移动某个队列单元,没学会动态操作css先放这吧(╯-_-)╯︵┻━┻,以后想玩再加
    // private moveUnit(targetUnit: HTMLDivElement, direction: Position) {

    // }
}

interface Position {
    x: number;
    y: number;
}