/*
     $Revision$
     $Id$

     File:          mobile.js
     Description:   clientside functions for pda
*/

window.fcltmobile = 1;

if (window && window.localStorage && window.localStorage.getItem("interface") == "touch") {
    toTouch();
}

$(function() {
    // Alle niet :target's worden default onderdrukt, als er geen :target is; toon dan de eerste pagina
    window.addEventListener("hashchange", function() {
        var hash = location.hash.split("#")[1];
        if (hash) {
            $(".page.show").removeClass("show");
            var $targetPage = $(".page#" + hash);
            if ($targetPage.length) {
                $targetPage.addClass("show");
            } else {
                // Als er geen pagina is, dan terug naar de eerste pagina
                $(".page:first").addClass("show");
            }
        } else {
            // Als er geen hash is, dan terug naar de eerste pagina
            $(".page.show").removeClass("show");
            $(".page:first").addClass("show");
        }
    });

    if (!location.href.split("#")[1]) {
        $(".page:first").addClass("show");
    }

    // Set initial theme
    toggleTheme();

    /* theme change eventHandler */
    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", toggleTheme);

    /* Footer eventHandlers */
    $(".pda-button-more").off("click").on("click", function() {
        $(this).toggleClass("open");
    });

    $(document)
        .off("touchstart touchend touchcancel")
        .on("touchstart", function(e) {
            var $target = $(e.target).closest(".tappable");
            if (!$target.hasClass("tappable")) {
                return;
            }
            if ($target.find(".tappable-target").length) {
                $target = $target.find(".tappable-target");
            }
            $target.addClass("fclt-active");
            $(document).one("scrollstart", () => {
                $(".tappable.fclt-active .tappable-target.fclt-active").removeClass("fclt-active");
            });
        }).on("touchend touchcancel", function(e) {
            var $target = $(e.target).closest(".tappable");
            if (!$target.hasClass("tappable")) {
                return;
            }
            if ($target.find(".tappable-target").length) {
                $target = $target.find(".tappable-target");
            }
            $target.removeClass("fclt-active");
            $(document).off("scrollstart");
        });

    var path = window.location.pathname;
    var page = path.split("/").pop();
    $("a[href='" + page + "']").addClass("active-page");
    /* \Footer eventHandlers */

    // Card more button
    $(".tappable.fclt-more").on("click", toggleRows);

    // Swipe
    let touchstart = { "x": 0, "y": 0 };
    const SWIPE_THRESHOLD = {
        "x": window.innerWidth / 2.5,
        "y": window.innerHeight / 2.5
    }
    let touchmoveHandler = e => {
        let translateX = (e.touches[0].screenX - touchstart.x);
        let translateY = (e.touches[0].screenY - touchstart.y);
        let isHoriSwiping = Math.abs(translateX) > Math.abs(translateY); /* else => vertical scrolling */
        if (isHoriSwiping &&
             (translateX > 0 && typeof swipeRightAction === "function" ||
              translateX < 0 && typeof swipeLeftAction === "function")) {
            e.currentTarget.style.transform = "translateX(" + translateX + "px)";
            e.currentTarget.style.opacity = 1 - Math.abs(translateX) / window.innerWidth;
        // } else if ( translateY < 0 && typeof swipeUpAction === "function" ||
        //             translateY > 0 && typeof swipeDownAction === "function") {
        //     e.currentTarget.style.transform = "translateY(" + translateX + "px)";
        //     e.currentTarget.style.opacity = 1 - translateY / window.innerHeight;
        } else {
            e.currentTarget.style.transform = null;
            e.currentTarget.style.opacity = null;
            if (!isHoriSwiping) { /* Cancel swipe */
                e.currentTarget.removeEventListener("touchmove", touchmoveHandler);
                e.currentTarget.dataset.swipeActive = 0;
            }
        }
    }
    let swipeables = document.getElementsByClassName("swipeable");
    [...swipeables].forEach(element => {
        element.addEventListener("touchstart", e => {
            touchstart.x = e.touches[0].screenX;
            touchstart.y = e.touches[0].screenY;
            e.currentTarget.addEventListener("touchmove", touchmoveHandler);
            e.currentTarget.dataset.swipeActive = 1;
        });
        element.addEventListener("touchend", e => {
            if (touchstart.x === 0 && touchstart.y === 0 ||
                e.currentTarget.dataset.swipeActive != 1) {
                return;
            }
            let touchend = {
                "x": e.changedTouches[0].screenX,
                "y": e.changedTouches[0].screenY
            };
            let swipeFunc;
            // if (touchstart.y - touchend.y > SWIPE_THRESHOLD.y) { // UP
            //     swipeFunc = window["swipeUpAction"];
            // } else if (touchend.y - touchstart.y > SWIPE_THRESHOLD.y) { // DOWN
            //     swipeFunc = window["swipeDownAction"];
            // }
            if (touchstart.x - touchend.x > SWIPE_THRESHOLD.x) { // LEFT
                swipeFunc = window["swipeLeftAction"];
            } else if (touchend.x - touchstart.x > SWIPE_THRESHOLD.x) { // RIGHT
                swipeFunc = window["swipeRightAction"];
            }
            if (typeof swipeFunc === "function") {
                e.currentTarget.removeEventListener("touchmove", touchmoveHandler);
                e.currentTarget.dataset.swipeActive = 0;
                swipeFunc(e.currentTarget);
            }
            touchstart = { "x": 0, "y": 0 };
            if (e.currentTarget) {
                e.currentTarget.style.transform = null;
                e.currentTarget.style.opacity = null;
                e.currentTarget.removeEventListener("touchmove", touchmoveHandler);
                e.currentTarget.dataset.swipeActive = 0;
            }
        });
    });

    // Multiactions
    const $bulkables = $(".bulkable");
    $bulkables.add(".tappable").on("contextmenu", e => e.preventDefault());
    if ($bulkables.length) {
        $(".cancel.multiaction").on("click", e => toggleBulkAction("off"));
        const $counter = $(".multiaction-count");
        const bulkEventHandler = e => {
            e.preventDefault();
            let $this = $(e.currentTarget);
            let isActive = $this.hasClass("bulk-selected");
            $this.toggleClass("bulk-selected", !isActive);
            $counter.attr("data-count", +$counter.attr("data-count") + (isActive ? -1 : 1));
            if ($(".bulkable.bulk-selected").length === 0) {
                toggleBulkAction("off");
            }
        }

        window.toggleBulkAction = function _toggleBulkAction(newState) {
            let isActive = $(".fclt-content").hasClass("bulk-active");
            if (newState === "on" && !isActive) {
                $(".fclt-content").addClass("bulk-active");
                $(".bulkable > .card-link, .bulkable.list-group-item-action").each((i, el) => {
                    $(el)
                        .data("href", $(el).attr("href"))
                        .data("onclick", $(el).attr("onclick"))
                        .attr({
                            "href": null,
                            "onclick": null,
                            "aria-disabled": true
                        });
                });
                $(".bulkable").on("click", bulkEventHandler);
            } else if (newState === "off" && isActive) {
                $(".fclt-content").removeClass("bulk-active");
                $counter.attr("data-count", 0);
                $(".bulkable").off("click", bulkEventHandler)
                              .removeClass("bulk-selected");
                $(".bulkable > .card-link, .bulkable.list-group-item-action").each((i, el) => {
                    $(el)
                        .attr({
                            "href": $(el).data("href"),
                            "onclick": $(el).data("onclick"),
                            "aria-disabled": false
                        }).removeData("href onclick");
                });
            }
        }

        $bulkables.each((i, elem) => {
            $(elem).on("fclt-longpress", e => {
                e.preventDefault();
                toggleBulkAction("on");
                bulkEventHandler(e);
            });
        });
    }

    function addLongPressEventHandler($elem) {
        $elem
            .on("touchstart.longpress", e => {
                let $this = $(e.currentTarget);
                var longpressTimer = window.setTimeout($().trigger.bind($this, "fclt-longpress"), 750);
                $this.data("longpressTimer", longpressTimer);
            }).on("touchend.longpress touchcancel.longpress", e => {
                let $this = $(e.currentTarget);
                var longpressTimer = $this.data("longpressTimer");
                if (longpressTimer) {
                    window.clearTimeout(longpressTimer);
                    $this.removeData("longpressTimer");
                }
            });
    }

    var $longpressables = $bulkables; // Kan worden uitgebreid

    addLongPressEventHandler($longpressables);

    // Filter
    $(".list-group-filter").on("input", function () {
        if (window.filterTimeout) {
            clearTimeout(window.filterTimeout);
        }
        window.filterTimeout = setTimeout(searchList.bind(this), 500);
    });

    $("textarea").autogrow();
});

function toggleRows() {
    var $card = $(this).closest(".card");
    $card.find(".fa-chevron-down, .fa-chevron-up").toggleClass("fa-chevron-down fa-chevron-up");
    $card.find(".row.open, .row.closed").toggleClass("open closed");
}

function getActiveTheme() {
    let activeTheme = window.localStorage.getItem("color-scheme");
    if (activeTheme !== "light" && activeTheme !== "dark") {
        activeTheme = "auto";
    }
    return activeTheme;
}

function getThemeIcon(theme) {
    theme = theme || getActiveTheme();
    if (theme === "light") {
        return "fa-sun-bright";
    } else if (theme === "dark") {
        return "fa-moon fas";
    } else {
        return "fa-circle-half-stroke far";
    }
}

function toggleTheme(newTheme) {
    if (newTheme === "light" || newTheme === "dark") {
        window.localStorage.setItem("color-scheme", newTheme);
    } else if (newTheme === "auto") {
        window.localStorage.removeItem("color-scheme");
    }
    let activeTheme = getActiveTheme();
    if (activeTheme !== "light" && activeTheme !== "dark") { // Dus auto
        activeTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
    }
    $("html").attr("data-bs-theme", activeTheme);
    $("[data-theme-toggle]").children("i").replaceWith(I(getThemeIcon(newTheme)));
}

function removeCardAnimated(elem) {
    const elemStyle = window.getComputedStyle(elem);
    let padding = parseInt(elemStyle.paddingTop) + parseInt(elemStyle.paddingBottom);
    elem.style.flexBasis = elem.clientHeight - padding + "px";
    elem.style.visibility = "hidden";
    while (elem.lastChild) { // Vanilla .empty();
        elem.removeChild(elem.lastChild);
    }
    elem.offsetHeight; // Flushes the CSS changes
    elem.classList.add("card-removing"); // Sets transition duration
    elem.addEventListener("transitionend", () => {
        elem.remove();
    }, { once: true });
    elem.classList.add("card-remove"); // Animate object vertically disappearing
}

function searchList() {
    var s = this.value.toLowerCase();
    var $section = $(this).next("section");
    // Remove expliciete 'first' en 'last' classes voor de styling
    $(".list-group-item-first, .list-group-item-last").removeClass("list-group-item-first list-group-item-last");
    if ($section.length) {
        if (s === "") {
            $section.find(".list-group-item").show();
        } else {
            // De regels
            $section.find(".list-group-item").each((i, elem) => {
                $(elem).toggle($(elem).text().toLowerCase().indexOf(s) != -1);
            });
            // De dividers (eventueel)
            $section.find(".list-group-header").each((i, elem) => {
                $(elem).toggle($(elem).nextUntil(".list-group-header").filter(":visible").length > 0);
            });
        }
    }
    // Add expliciete 'first' en 'last' classes voor de styling
    $section.find(".list-group-item").filter(":visible").first().addClass("list-group-item-first");
    $section.find(".list-group-item").filter(":visible").last().addClass("list-group-item-last");
}

function McltCallbackAndThen(afterAction) {
    return function(json, textStatus) {
        if (json.message) alert(json.message); // Normaal door FcltMgr.closeDetail
        if (json.warning) alert(json.warning);
        if (json.toaster) jqToast(json.toaster);
        json.message = null;
        json.warning = null;
        json.toaster = null;
        if (json.success) {
            if (afterAction) afterAction(json);
        }
    }
};

function McltCallbackAndThenAlways(afterAction) {
    return function(json, textStatus) {
        if (json.message) alert(json.message);
        if (json.warning) alert(json.warning);
        if (json.toaster) jqToast(json.toaster);
        json.message = null;
        json.warning = null;
        json.toaster = null;
        if (afterAction) afterAction(json);
    }
};

function jqToast(msg) {
    var $toaster = $(`
    <div class="toast align-items-center" role="alert" aria-live="assertive" aria-atomic="true">
        <div class="d-flex">
            <div class="toast-body">
            ${msg}
            </div>
            <button type="button" class="btn-close me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
        </div>
    </div>
    `).appendTo("body");
    $toaster.on("hidden.bs.toast", function () { $(this).remove(); });
    var toaster = new bootstrap.Toast($toaster);
    toaster.show();
}

var McltCallbackSaved = McltCallbackAndThen(function(json) {
    if (json.success)
        jqToast(L("lcl_mobile_data_saved"));
});

var McltCallbackRefresh = McltCallbackAndThen(function(json) {
    window.location.href = window.location.href;
});

var McltCallbackClose = McltCallbackAndThen(function(json) {
    window.history.back(1);
});

var McltCallbackHome = McltCallbackAndThen(function(json) {
    // window.history.back(1); doet geen refresh als je bijvoorbeeld net een reservering hebt verwijderd
    window.location.href = rooturl + "/appl/pda/facilitor.asp";
});

var mobile = {
    button: {
        click: async function(evt, btn) {
            FcltMgr.stopPropagation(evt);

            if (btn.getAttribute("singlepress") && $(btn).hasClass("btn_disabled")) { // FcltMgr.alert("Heb geduld");
                return;
            }
            if (btn.getAttribute("singlepress")) {
                mobile.button.disable(btn);
            }
            var elem = btn.getAttribute("mobClick");

            // window.fcltevent = evt;
            var result = eval(elem);
            if (typeof result === "object" && result instanceof Promise) {
                result = await result;
            }
            // Dit lijkt erg onzinning (we zitten binnen mobile) maar soms als
            // een scherm/dialoog net gesloten is door de action van de button
            // blijkt de code toch nog hier te komen terwijl mobile weg is
            if (typeof mobile == "undefined")
                return;

            if (result === false) {
                mobile.button.enable(btn);
            }

        },
        disable: function(btn) {
            if (!btn || btn.tagName != 'A')
                return; // not a mobile button

            $(btn).toggleClass("btn_disabled", true)
                .removeClass("btn_enabled");
        },
        enable: function(btn) {
            if (!btn || btn.tagName != 'A')
                return; // not a mobile button

            $(btn).toggleClass("btn_enabled", true)
                .removeClass("btn_disabled");
        }
    },
    changePage: function _changePage(id) {
        if (id) {
            $(".page.show").removeClass("show");
            location.hash = "#" + id;
        } else { // Back
            if (location.hash) {
                $(".page:first").addClass("show");
                location.hash = "";
            } else {
                history.back(1);
            }
        }
    }
}

var $signatureButton;
var save_url;
function onBijlagenMobile(formurl /* protected */, saveUrl /* protected */, multi, objButton) {
    save_url = saveUrl; /* Global voor uploadDone() */
    $signatureButton = $(objButton); /* Global voor uploadDone() */
    $.get(formurl, {}, function (data) { // Levert een HTML segment op; een <script> en een <div>
        $("#form-signature").html(data).trigger("create");  // Zet dat in de bestaande hash-pagina
        mobile.changePage("page-signature"); // En ga naar die pagina
    });
}

// make filename safe for show
function safeFilename(s) {
    return s.replace(/[\x00-\x1F|\/|\\|\*|\%\<\>\"\:\;\?\|\+]+/g, "_");
}
// remove element of deleted file
function removeElement(element) {
    return function(json) {
        let $bijlageButton = element.closest(".attachments_form").find(".add_attachment > [role=button][nBijlagen]");
        if ($bijlageButton.length) {
            $bijlageButton.attr("nBijlagen", parseInt($bijlageButton.attr("nBijlagen") || 0, 10) - 1);
        }
        element.remove();
        if (json.toaster) {
            jqToast(json.toaster);
        }
    }
};
// delete flex-attachment
function DeleteFile(fname, safeDeleteurl, element) {
    FcltMgr.confirm(L("lcl_delete") + " " + safeFilename(fname) + "?", function() {
        var data = {};
        protectRequest.dataToken(data);
        $.post("../shared/" + safeDeleteurl,
            data,
            McltCallbackAndThen(removeElement(element))
        );
    });
}

function disable(btn) {
    $(btn).attr("onclick", "return false;")
        .toggleClass("btn-disabled", true)
        .removeClass("btn-enabled");
}

function toTouch() {
    window.localStorage.setItem("interface", "touch");
    parent.location.href = "../../default.asp?interface=touch";
}

function toDesktop() {
    window.localStorage.setItem("interface", "desktop");
    parent.location.href = "../../default.asp?interface=desktop";
}