$(function () {
    $(".dropdown-menu.dropdown-select-menu").each((index, value) => {
        setDropdownItem(value)
    })

})

/** 
 * fn 定義 | 手動初始化 Bootstrap dropdown select 
 */
$.fn.droSetItem = function () {
    setDropdownItem(this);
    return this;
}
/** 
 * fn 定義 | 輸出含原元素 html
 */
$.fn.outerHtml = function () {
    return $(this).prop("outerHTML");
}

/**
 * fn 定義 | Loading 操作
 * @param {any} type - close / start / exceed , exceed => 繼續執行並可切換文字
 * @param {any} text - 右下角 Alert 文字
 */
$.fn.Loading = function (type = "close",text) {
    let ele = this;
    let aleObj = $(this)[0]._aleObj;

    function closeLoading() {
        $("body").css("overflow", "auto");
        $(aleObj.ele).YTAlert().hide();
        $(ele).animate({ opacity: 0 }, 300, () => {
            $(ele).hide();
        })
    }
    function showLoading() {
        $("body").css("overflow", "hidden");
        let aleObj = YT.Alert.Tip(text || "讀取中,請稍後", "show");
        $(ele)[0]._aleObj = aleObj;
        $(ele).show();
        $(ele).animate({ opacity: 1 }, 300); 
        
        $(aleObj.ele).YTAlert().text(text);
    }
    if (type == "close") {
        closeLoading();
    } else if (type == "exceed") {
        $(aleObj.ele).YTAlert().text(text);
    } else if (type == "start") {
        showLoading();
    }
    
    return $(this);
}

$.fn.YTAlert = function () {
    let th = { element: this };
    th.hide = function (delay = 0) {
        let obj = this;
        setTimeout(function () {
            $(obj.element).fadeOut(300);
            alertIdArray.splice($.inArray($(obj.element).prop("id"), alertIdArray), 1);
            setTimeout(function () {
                $(obj.element).remove();
            }, 1000);
        }, delay);
    }

    th.text = function (text) {
        let obj = this;
        let id = $(obj.element).prop("id").split("tip-alert-")[1];
        $(`#alert-text-${id}`).text(text);
    }
    return th;
}

/**
 * 設置 bootstrap dropdown 為下拉選單 
 * @param {any} menuEle - .dropdown-menu element
 */
function setDropdownItem(menuEle) {
    if ($(menuEle).find(".dropdown-item.active").length == 0) {
        $(menuEle).find(".dropdown-item").first().addClass("active");
    }

    let actText = $(menuEle).find(".dropdown-item.active").first().text();
    let actEleId = $(menuEle).prop("id");
    $(`.dropdown-toggle[data-target=${actEleId}]`).text(actText);

    /*actChaCallback($(menuEle).find(".dropdown-item.active"))*/
    $(menuEle).trigger("active:change", $(menuEle).find(".dropdown-item.active"));

    //點選選項 add active class
    onEvent("click", ".dropdown-menu.dropdown-select-menu .dropdown-item", function () {
        $(this).parent(".dropdown-menu.dropdown-select-menu").find(".dropdown-item").removeClass("active");
        $(this).addClass("active");
        setDropdownItem($(this).parent(".dropdown-menu.dropdown-select-menu"));
    })
}

/**
 * 預設設備圖像
 * @param {any} obj
 */
function defDev(obj) {
    let defSrc = 'img/defdev.png';
    obj.src = defSrc;
}

/**
 * jquery datatable - ajax send data reset
 * @param {any} table
 * @param {any} sendData
 */
function dtAjaxResetSendData(table,sendData) {
    table.context[0].ajax.data = function (d) {
        d = sendData;
        return JSON.stringify(d)
    }
}


/**
 * element 建造 
 * @param {any} text
 * @param {any} id
 * @param {any} name
 * @param {any} cls
 * @param {any} data
 * @param {any} attr
 */
function eleBuild(text = null, id = null, name = null, cls = [], data = {}, attr = {}) {
    cls = cls ?? [], data = data ?? {}, attr = attr ?? {};
    id = id ? `id="${id}"` : "";
    name = name ? `name="${name}"` : "";
    cls = cls.length != 0 ? `class="${cls.join(' ')}"` : "";
    data = data.length != 0 ? `${Object.keys(data).map(x => `data-${x}="${data[x]}"`).join(" ")}` : "";
    attr = attr ? `${Object.keys(attr).map(x => `${x}="${attr[x]}"`).join(" ")}` : "";
    let attrArr = [], attrText = "";
    attrArr = [id, name, cls, data, attr];
    attrText = attrArr.filter(x => x != "").join(" ");
    text = text === null ? "" : text;
    return { attrText: attrText, text: text };
}

function creEle(ele, text = null, id = null, name = null, cls = [], data = {}, attr = {}) {
    let comp = eleBuild(text, id, name, cls, data, attr);
    return $(`<${ele} ${comp.attrText}>${comp.text}</${ele}>`);
}

function creDiv(cls = [], attr = {}, id = null, name = null, data = {}, text = null) {
    return creEle("div", text, id, name, cls, data, attr);
}

function creBtn(text = null, id = null, name = null, cls = [], data = {}, attr = {}) {
    return creEle("button", text, id, name, cls, data, attr);
}

function creBtnHtml(text = null, id = null, name = null, cls = [], data = {}, attr = {}) {
    return creEle("button", text, id, name, cls, data, attr).prop("outerHTML");
}

function creSelect(id = null, cls = [], name = null, data = {}, attr = {}, text = null) {
    return creEle("select", text, id, name, cls, data, attr);
}

function creOption(text = null, value = null, data = {}, attr = {}, cls = [], name = null, id = null) {
    attr = value != null ? attr.value = value : attr;
    return creEle("option", text, id, name, cls, data, attr);
}

/**
 * 根據該棟建築底下的'所有'電梯執行緒物件
 * */
class ElevatorHandler {
    constructor(ele, option = {}) {
        this.ele = ele;
        this.eleId = "";
        this.eleWra = $("<div></div>");
        this.speed = 0.3;
        this.movStatus = {};  // {id:elevator01,value:0} 0=no 1=up 2=down
        this.floorHeight = typeof option.fHeight == "undefined" ? 60 : option.fHeight;
        this.floorWidth = typeof option.fWidth == "undefined" ? 45 : option.fWidth;
        this.floors = typeof option.floors == "undefined" ? [{}] : option.floors;
        this.elevators = typeof option.elevators == "undefined" ? [{}] : option.elevators;  // {id:elevator01}
        this.curElevFloor = typeof option.curElevFloor == "undefined" ? {} : option.curElevFloor;
        this.setTimeout = null;
        this.init();
    }

    // 所有電梯初始化
    init = function () {
        this.setTabWra();
        this.setTabFloor();
        // 若已有每個設備的所在樓層,則預設到該樓層位置
        if (Object.keys(this.curElevFloor).length != 0) { 
            $.each(Object.keys(this.curElevFloor), (idx, elevKey) => {
                this.setElevFloor(elevKey,this.curElevFloor[elevKey]);
            })
        }
    }

    // 設置 wrapper
    setTabWra = function () {
        let id = $(this.ele).prop("id");
        this.eleId = id;
        if ($(this.ele).parent(".elevator-table-wrapper").length != 0) {
            $(this.ele).unwrap(".elevator-table-wrapper");
        }
        let wrapper = creDiv(["elevator-table-wrapper"], null, `${id}_wrapper`);
        $(this.ele).wrap(wrapper);
        this.eleWra = wrapper;
    }

    // 設置 table 樓層
    setTabFloor = function () {
        let _w = this.floorWidth, _h = this.floorHeight;
        let thead = creEle("thead"), tbody = creEle("tbody");
        let _floors = this.floors, _ele = this.ele, _elevators = this.elevators;
        //樓層從小到大
        _floors = _floors.oSort("sort").reverse().map(x => x.name);

        let theadTr = creEle("tr");
     
        for (let e = 1; e <= _elevators.length + 2; e++) {
            let th = creEle("th");
            th.css({ "width": `${_w}px`, "height": `${_h}px` ,"position":"relative"});
            if (e != 1 && e != _elevators.length + 2) {
                let elevId = _elevators[e - 2]?.id;
                // 電梯方框
                let span = creEle("span", null, "elevator-item-" + (elevId), null, ["elevator-item"]);
                let spanUp = creEle("span", null, null, null, ["elevator-item-toup"]);
                let spanDown = creEle("span", null, null, null, ["elevator-item-todown"]);
                span.css({ "width": `${_w - 3}px`, "height": `${_h - 3}px`, "top": `1.5px`,"left":"1.5px", "transition":`transform ${1 / this.speed}s cubic-bezier(0.43, 0.05, 0.62, 1) 0s`})
                spanUp.css({ "width": `${_w - 3}px`, "height": `${(_h - 3) / 2}px`, "top": `1.5px`, "left": "1.5px", "transition":`transform ${1 / this.speed}s cubic-bezier(0.43, 0.05, 0.62, 1) 0s`})
                spanDown.css({ "width": `${_w - 3}px`, "height": `${(_h - 3) / 2}px`, "top": `1.5px`, "left": "1.5px", "transition":`transform ${1 / this.speed}s cubic-bezier(0.43, 0.05, 0.62, 1) 0s`,"top":`${1.5 + (_h-3) / 2}px`})
                th.append(spanUp);
                th.append(span);
                th.append(spanDown);
            }
            theadTr.append(th);
        }
        thead.css("position", "absolute");
        thead.append(theadTr);

        //樓層表格建置 tbody
        for (let f = 1; f <= _floors.length; f++) {
            let tr = creEle("tr");
            
            for (let e = 1; e <= _elevators.length + 2; e++) {
                let td = creEle("td");
                td.css({ "width": `${_w}px`, "height": `${_h}px` });
                if (e == 1) {
                    td.addClass("t-black")
                    td.text(_floors[f - 1]);
                } else if (e == _elevators.length + 2) {
                }
                else {
                    let div = creDiv(["d-flex", "justify-content-center", "align-items-end", "h-100"]);
                    div.append(`<i class="fal fa-door-open fs-1-2"></i>`)
                    td.append(div)
                }
                tr.append(td);
            }
            tbody.append(tr);
        }

        $(_ele).append(thead);
        $(_ele).append(tbody);

        //表格外圍無框線
        $(_ele).find("tbody tr").each((index, tr) => {

            $(tr).find("td:eq(0)").css("border-left", "0");
            $(tr).find("td:eq(-1)").css("border-right", "0");

            if (index == 0) {
                $(tr).find("td").each((index, td) => {
                    $(td).css("border-top", "0");
                })
            } else if (index == $("#floorTable tbody tr").length - 1) {
                $(tr).find("td").each((index, td) => {
                    $(td).css("border-bottom", "0");
                })
            }
        })

    }

    // 設置某個電梯到某個樓層
    setElevFloor = function (elevId, floId) {
        let curFloId = this.curElevFloor[elevId];
        let curSort = this.floors.filter(x => x.id == curFloId).map(x => x.sort)[0];
        let tarSort = this.floors.filter(x => x.id == floId).map(x => x.sort)[0];
        let gapFloor = tarSort - curSort;
        let cssEle = [$(`#elevator-item-${elevId}`)[0], $(`#elevator-item-${elevId}`).prev("span.elevator-item-toup")[0], $(`#elevator-item-${elevId}`).next("span.elevator-item-todown")[0]]
        if (this.movStatus[elevId] != 0) { 
            $(cssEle).css("transition", `transform ${1 / this.speed * Math.abs(gapFloor)}s cubic-bezier(0, 0, 0.62, 1) 0s`);
        }
        clearTimeout(this.setTimeout);
        this.setTimeout = setTimeout(() => {
            $(cssEle).css("transition", `transform ${1 / this.speed * Math.abs(gapFloor)}s cubic-bezier(0.43, 0.05, 0.62, 1) 0s`);
            this.setEleUpDownStyle(elevId);
        }, (1 / this.speed * Math.abs(gapFloor)) * 1000)
        this.setEleUpDownStyle(elevId);
        this.curElevFloor[elevId] = floId;
        $(cssEle).css("transition", `transform ${1 / this.speed * Math.abs(gapFloor)}s cubic-bezier(0.43, 0.05, 0.62, 1) 0s`)
        $(cssEle).css("transform", `translateY(${this.floorHeight * (this.floors.length - tarSort)}px)`);
    }

    // 設定現在電梯狀態 (往上/往下/停止)
    setEleMovStatus = function (elevId,status) {
        this.movStatus[elevId] = status;
    }

    // 電梯方框 往上或往下閃爍
    setEleUpDownStyle = function (elevId) {
        if (this.movStatus[elevId] == 1) {
            $(`#elevator-item-${elevId}`).next("span.elevator-item-todown").removeClass("light-flash-c-bd")
            $(`#elevator-item-${elevId}`).prev("span.elevator-item-toup").addClass("light-flash-c-bd")
                .css("--flash-color-1", "#44ea8e").css("--flash-color-2", "rgba(255,255,255,0)");
        } else if (this.movStatus[elevId] == 2) {
            $(`#elevator-item-${elevId}`).prev("span.elevator-item-toup").removeClass("light-flash-c-bd")
            $(`#elevator-item-${elevId}`).next("span.elevator-item-todown").addClass("light-flash-c-bd")
                .css("--flash-color-1", "#44ea8e").css("--flash-color-2", "rgba(255,255,255,0)");
        } else {
            $(`#elevator-item-${elevId}`).prev("span.elevator-item-toup").removeClass("light-flash-c-bd");
            $(`#elevator-item-${elevId}`).next("span.elevator-item-todown").removeClass("light-flash-c-bd");
        }
    }

    // 設定現在某個電梯所在樓層
    setCurElevFloor = function (elevId,floId) {
        this.curElevFloor[elevId] = floId;
    }

    // 重新繪製
    redraw = function () {
        $(this.ele).empty();
        this.setTabFloor();
        if (Object.keys(this.curElevFloor).length != 0) {
            $.each(Object.keys(this.curElevFloor), (idx, elevKey) => {
                this.setElevFloor(elevKey, this.curElevFloor[elevKey]);
            })
        }
    }
    
}