<% /*
    $Revision$
    $Id$

    File:               mld_bord.inc
    Description:        Definieert de serverside functie mld_bord() die een kolom-gesorteerde weergave van meldingen toont
                        die voldoen aan de gegeven parameters/criteria.
                        Zoals altijd wordt hierbij wel autorisatie betrokken,
                        maar verder geen contextafhankelijke zaken; dat behoort de aanroeper te doen.
    Parameters:
    Context:            vanuit mld_search_list.asp
    Note:
*/ %>

<!-- #include file="../Shared/iface.inc" -->
<!-- #include file="../mld/mld.inc" -->

<%
FCLTHeader.Requires({
    plugins: ["jQuery"],
    js:      ["jquery-ui.js"]
});

var showAll = getFParamInt("showAll", 0) == 1;

function dataToHtmlStr(data) {
    var result = "";
    if (data) {
        for (var i in data) {
            if (data.hasOwnProperty(i)) {
                result += ' data-' + i + '="' + safe.htmlattr(data[i]) + '"';
            }
        }
    }
    return result;
}

// Om planbord kaarten in een kaartenbak te groeperen.
function CARDBOX_START_HTML(params) {
    params = params || {};
    return '<div class="fclt-cardbox' + (params.isEmpty ? " empty" : "") + '"'
         + dataToHtmlStr(params.data)
         + '>';
}

function CARDBOX_END_HTML() {
    return '</div>';
}

// Om velden in een planbord kaart te groeperen.
function CARD_START_HTML(params) {
    params = params || {};
    params.cls = params.cls || "";
    return '<div class="fclt-card ' + (params.cls ? params.cls + " " : "") +  (params.open ? "open" : "closed") + '"'
         + dataToHtmlStr(params.data)
         + ' draggable="true" tabindex="' + (params.open ? "0" : "-1") + '">';
}

function CARD_END_HTML() {
    return '</div>';
}

function getCardBoxTitle(oRs, mldbordColumn) {
    var result = null;
    if (oRs && oRs("mldbordColumnValue").Value) { // De tekstuele waarde
        result = oRs("mldbordColumnValue").Value;
    }
    if (result === null) {
        if (mldbordColumn === -2) {
            result = L("lcl_suggestemptytxtBEH");
        } else if (mldbordColumn === -3) {
            result = L("lcl_suggestemptytxtBHT");
        } else if (mldbordColumn === -4) {
            result = L("lcl_suggestemptytxtTBH");
        } else if (mldbordColumn > 0) {
            result = L("lcl_suggestemptytxt");
        }
    }
    return result;
}

function getFlagHtml(oRs) {

  var mldkey = oRs("mld_melding_key").Value;
  var flagkey = oRs("mld_melding_flag").Value || 0;
  var ttl = L("lcl_mld_flag" + flagkey);

  var flagIcon = "<span class='mldflag"+flagkey+" mlds'>" + I("fa-fclt-flag" + (flagkey == 0 ? "0" : "")) + "</span>"

  // Met hidden flagkey voor sortering
  return "<div class='clickParent flagparent pointer' onclick='toggleMldFlag(event, "+ mldkey +");'"
       + " title='"+safe.htmlattr(ttl)+"'>"
       + "<span id='mldflagimg"+mldkey+"' flagkey='"+flagkey+"'>"+flagIcon+"</span>"
       + "<span class='hidden'>"+(flagkey||999)+"</span></div>";
}

// Merk op dat er een max-height staat op de .fclt-card
// Als er content toegevoegd wordt moet die CSS (die voor de inklapt-animatie bestaat) mogelijk ook aangepast worden
function fnCardContent(oRs, mld_bord_params) {
    var result = '';
    var subject = oRs("mld_melding_onderwerp").Value || oRs("mld_stdmelding_omschrijving").Value;
    result += '<div class="bord-card-body-line limit-lines-1" title="' + safe.htmlattr(subject) + '">'
            + safe.html(subject)
            + '</div>';

    var einddatum = oRs("mld_melding_einddatum").Value;
    if (einddatum !== null) {
        result += '<div class="bord-card-body-line limit-lines-1" title="' + L("lcl_end_date_plan") + '">'
                + I("fa-calendar")
                + '<span>' + toDateTimeString(einddatum) + '</span>'
                + '</div>';
    }

    if (
        mldlist.anybeh &&           // Doen we iets met behandelteams?
        mld_bord_params.mld_ins_discipline_key_arr && mld_bord_params.mld_ins_discipline_key_arr.length !== 1 &&  // Hebben we niet gefilterd op één specifiek team?
        mld_bord_params.mldbordColumn !== -3 // Hebben we 'behandelteam' niet als kaartindeling gekozen?
    ) {                             // Dan willen we het behandelteam wel zien
        var behandelteam = oRs("behandelteam").Value;
        if (behandelteam) {
            result += '<div class="bord-card-body-line limit-lines-1" title="' + L("mld_processing_group") + '">'
                    + I("fa-users")
                    + '<span>' + safe.html(behandelteam) + '</span>'
                    + '</div>';
        }
    }

    return result;
}

function mld_bord(pautfunction, params)
{
    var authparams = user.checkAutorisation(pautfunction);
%>
<html>
    <head>
<%  FCLTHeader.Generate(); %>
        <script>
            let $draggedCard = null;
            let dragStartKey = null;
            const SHOW_CARDS = <%=S("mld_show_cards")%>;

            var fnReloadByPost = parent.window.doSubmit.bind(null, 0, <%=showAll ? 1 : 0%>, 'bord');

            function getDragAfterElement($container, y) {
                const $cards = $container.find(".fclt-card.open").not(".fclt-dragging");
                let closest = null;
                let closestOffset = Number.NEGATIVE_INFINITY;

                $cards.each(function () {
                    const box = this.getBoundingClientRect();
                    const offset = y - box.top - box.height / 2;

                    if (offset < 0 && offset > closestOffset) {
                        closestOffset = offset;
                        closest = this;
                    }
                });

                return closest || $container.find(".fclt-card.closed").get(0) || $container.find(".fclt-card-more").get(0);
            }

            function updateMelding(mld_key, from_key, to_key) {
                if (from_key == to_key) {
                    return {
                        success: true
                    };
                }

                var data = {
                    mld_key: mld_key,
                    type: <%=params.mldbordColumn%>
                };
<%              if (params.mldbordColumn > 0) { %>
                data.type_descr = "<%=safe.jsstring(params.mldbordColumnDescr)%>";
<%              } %>
                if (from_key) {
                    data.from_key = from_key;
                }
                if (to_key) {
                    data.to_key = to_key;
                }
                protectRequest.dataToken(data);

                return $.post(
                    "mld_edit_bord_save.asp",
                    data,
                    FcltCallback,
                    "json"
                );
            }

            /**
            * Update één enkele cardbox: toon/verberg de 'meer'-knop
            * en hide/show kaarten volgens S("mld_show_cards")
            */
            function updateCardBox($box) {
                const $cards = $box.find(".fclt-card");
                const totalCards = $cards.length;
                const $moreBtn = $box.find(".fclt-card-more");
                const isExpanded = $moreBtn.attr("aria-expanded") === "true";
                const hasMoreBtn = $moreBtn.hasClass("open");
                const $counter = $box.find(".fclt-cardbox-counter");

                // Update de card-count
                $counter.text(totalCards);

                // 1) Bij of onder de drempel: knop weg, alle kaarten open
                if (totalCards <= SHOW_CARDS) {
                    if (hasMoreBtn) {
                        $moreBtn.toggleClass("open closed");
                    }
                    // Open alle gesloten kaarten
                    toggleCards($cards.filter(".closed"));
                    return;
                }

                // 2) Boven de drempel: knop tonen (collapsed state)
                if (!hasMoreBtn) {
                    $moreBtn.toggleClass("open closed");
                }

                if (isExpanded) { // a) Géén drempel meer: open alle gesloten kaarten
                    toggleCards($cards.filter(".closed"));
                } else { // b) Collapsed: zorg dat alleen de eerste SHOW_CARDS open zijn
                    const $openCards = $cards.filter(".open");
                    const openCount  = $openCards.length;
                    if (openCount > SHOW_CARDS) { // b1) Te veel open: sluit de rest
                        toggleCards($openCards.slice(SHOW_CARDS));
                    } else if (openCount < SHOW_CARDS) { // b2) Te weinig open: open extra
                        const $closedCards = $cards.filter(".closed");
                        toggleCards($closedCards.slice(0, SHOW_CARDS - openCount));
                    }
                }
            }

            /**
            * afterDrop: alleen de 'from' en 'to' kolommen updaten.
            */
            function afterDrop(from_key, to_key) {
                if (from_key == to_key) {
                    return; // Niets te doen
                }
                $draggedCard.addClass("updated");

                const $fromBox = $(`.fclt-cardbox[data-key="${from_key}"]`);
                updateCardBox($fromBox);

                const $toBox = $(`.fclt-cardbox[data-key="${to_key}"]`);
                updateCardBox($toBox);
            }

            function toggleCardBoxes() {
                // Update de classes van de kolommen
                $(".fclt-cardbox").each((i, elem) => {
                    let isEmpty = $(elem).find(".fclt-card").length === 0;
                    if (isEmpty) {
                        $(elem).addClass("empty");
                    } else {
                        $(elem).removeClass("empty");
                    }
                });

                if ($(".fclt-cardbox.empty").length > 0) {
                    var continuousResizeTimer = setInterval(resizeScrollingClone, 1);
                    $(".fclt-cardbox.empty").eq(0).one("transitionend", clearInterval.bind(null, continuousResizeTimer));
                }

                // Toggle de compact-modus
                $(".mldbord-content").toggleClass("compact");

                // Toggle de button (icoon & tekst)
                const compact = $(".mldbord-content").hasClass("compact");
                $("#compact").find(".fa-eye, .fa-eye-slash").toggleClass("fa-eye fa-eye-slash")
                            .next().text(compact ? L("lcl_mldbord_compact_off") : L("lcl_mldbord_compact_on"));
            }

            function toggleCards($cards) {
                $cards.eq(0)
                    .one("transitionend", FcltMgr.resized.bind(null, window, {}) ); // Als je niet 'bind' wordt het event het eerste argument
                $cards.toggleClass("open closed");
                $cards.attr("tabindex", (_, attr) => (attr == -1 ? 0 : -1));
            }

            function toggleMore(e) {
                var $cardbox = $(this).closest(".fclt-cardbox");

                $(this).find(".fa-chevron-down, .fa-chevron-up").toggleClass("fa-chevron-down fa-chevron-up");
                $(this).attr("aria-expanded", ($(this).attr("aria-expanded") === "true" ? "false" : "true"));

                toggleCards($cardbox.find(".fclt-card.open, .fclt-card.closed").slice(SHOW_CARDS));
            }

            /**
            * Drag to scroll
            */
            let scrollModeX = 0;
            let scrollModeY = 0;
            let scrollInterval = {};
            const EDGE_THRESHOLD = 50; // px
            const SCROLL_SPEED = 20; // px per frame

            function mldbordScroll(mode, dir) {
                if (dir == "x") {
                    if (mode === scrollModeX) {
                        return; // No change
                    }
                    scrollModeX = mode || 0;
                } else if (dir == "y") {
                    if (mode === scrollModeY) {
                        return; // No change
                    }
                    scrollModeY = mode || 0;
                } else {
                    scrollModeX = 0;
                    scrollModeY = 0;
                }
                if (mode) {
                    if (dir == "x") {
                        if (dir in scrollInterval) {
                            clearInterval(scrollInterval[dir])
                        }
                        scrollInterval[dir] = setInterval(_ => {
                            mldbord.scrollBy(mode * SCROLL_SPEED, 0);
                        }, 1);
                    } else {
                        if (dir in scrollInterval) {
                            clearInterval(scrollInterval[dir])
                        }
                        scrollInterval[dir] = setInterval(_ => {
                            parent.scrollBy(0, mode * SCROLL_SPEED);
                        }, 1);
                    }
                } else {
                    if (dir == "x" || dir == "y") {
                        clearInterval(scrollInterval[dir]);
                    } else {
                        for (var i in scrollInterval) {
                            if (scrollInterval.hasOwnProperty(i)) {
                                clearInterval(scrollInterval[i]);
                            }
                        }
                    }
                }
            }

            function doScroll(e) {
                const $content = $(this).find(".mldbord-content");
                if (!$content.hasClass("dragging-content")) {
                    return;
                }
                const rect = $content.get(0).getBoundingClientRect();
                const x    = e.clientX;
                const y    = e.clientY;

                // Horizontaal
                if (x < EDGE_THRESHOLD) {
                    mldbordScroll(-1, 'x');
                } else if (x > window.innerWidth - EDGE_THRESHOLD) {
                    mldbordScroll(1, 'x');
                } else if (scrollModeX != 0) {
                    mldbordScroll(0, 'x');
                }

                // Verticaal
                if (
                    y - this.offsetTop < EDGE_THRESHOLD ||                              // Ik zit in de bovenste 50px van .mldbord,
                    y < EDGE_THRESHOLD + parent.scrollY - window.frameElement.offsetTop // of ik zit in de bovenste 50px van de parent.window
                ) { // Up
                    mldbordScroll(-1, 'y');
                } else if ((y + window.frameElement.offsetTop - parent.scrollY) > (parent.innerHeight - EDGE_THRESHOLD)) { // Down
                    mldbordScroll(1, 'y');
                } else if (scrollModeY != 0) {
                    mldbordScroll(0, 'y');
                }
            }

            /**
            * Sticky scrollbar
            */
            var $fakeScrollbar, fakeScrollbar,
                $mldbord, mldbord,
                noTransitionTimer;
            function resizeScrollingClone() {
                $fakeScrollbar.find(".content-width-clone").get(0).style.width = mldbord.scrollWidth + "px";
            }

            $(() => {

                $(".fclt-card-more").on("click", toggleMore);

                $(".fclt-card").on("click", function() {
                    if (!$(this).hasClass("closed")) {
                        FcltMgr.openDetail("./APPL/MLD/mld_melding.asp?mld_key=" + this.dataset.key);
                    }
                }).on("keydown", function(e) {
                    if (e.key == "Enter" || e.key == " ") {
                        this.click();
                    }
                }).on("mousedown", function(e) {
                    if ($(e.target).closest(".flagparent").length === 0) { // Niet activeren als je op de flag klikt
                        $(this).addClass("pressed");
                    }
                }).on("mouseup mouseleave", function(e) {
                    $(this).removeClass("pressed");
                });

                $(".fclt-card").on("dragstart", function (e) {
                    if ($draggedCard !== null) {
                        return; // Niet zo snel
                    }
                    $draggedCard = $(this);
                    $draggedCard.addClass("fclt-dragging");
                    $draggedCard.before("<placeholder class='hidden'></placeholder>"); // Placeholder to remember location
                    dragStartKey = $(this).closest(".fclt-cardbox").data("key");
                    $(this).closest(".fclt-cardbox").addClass("fclt-drag-over");
                    $(".mldbord-content").addClass("dragging-content");
                });

                $(".fclt-card").on("dragend", async function (e) {
                    if ($draggedCard === null) {
                        return;
                    }
                    $("[draggable]").attr("draggable", false);
                    $(".fclt-drag-over").removeClass("fclt-drag-over");
                    $(".mldbord-content").removeClass("dragging-content");
                    mldbordScroll(); // Zonder parameters = stop
                    if (e.originalEvent.dataTransfer.dropEffect != "none") { // is 'none' bij cancel (Escape) of drop buiten een dropzone
                        var dragDropKey = $draggedCard.closest(".fclt-cardbox").data("key");
                        var result = await updateMelding($(this).data("key"), dragStartKey, dragDropKey);
                        if (result.success) {
                            $("placeholder").remove();
                            afterDrop(dragStartKey, dragDropKey);
                        } else {
                            $("placeholder").replaceWith($draggedCard); // Restore original position
                        }
                    } else {
                        $("placeholder").replaceWith($draggedCard); // Restore original position
                    }
                    $draggedCard.removeClass("fclt-dragging");
                    $draggedCard = null;
                    $("[draggable]").attr("draggable", true);
                });

                $(".fclt-cardbox").on("dragover", function (e) {
                    e.preventDefault();
                    if ($draggedCard === null) {
                        return;
                    }
                    const $cardbox = $(this);
                    const afterElement = getDragAfterElement($cardbox, e.originalEvent.clientY);
                    if (!afterElement) {
                        $cardbox.append($draggedCard);
                    } else {
                        $draggedCard.insertBefore(afterElement);
                    }
                });

                $(".fclt-cardbox").on("dragenter", function () {
                    $(".fclt-drag-over").removeClass("fclt-drag-over");
                    $(this).addClass("fclt-drag-over");
                });

                $(".mldbord").on("dragover", doScroll);

                $fakeScrollbar = $(frameElement.parentElement).next(".fclt-scrollbar");
                if ($fakeScrollbar.length === 0) { // Bestaat al na een refresh
                    $fakeScrollbar =
                        $(` <div class="fclt-scrollbar">
                                <div class="content-width-clone"></div>
                            </div>`);
                    $fakeScrollbar.insertAfter(frameElement.parentElement); // = div#result
                }
                fakeScrollbar = $fakeScrollbar.get(0);

                $mldbord = $(".mldbord");
                mldbord = $mldbord.get(0);

                // Hou de scrollpositie van de clone gelijk aan die van de content
                $mldbord.on("scroll", _ => {
                    fakeScrollbar.scrollLeft = mldbord.scrollLeft;
                });

                // Hou de scrollpositie van de content gelijk aan die van de clone
                $fakeScrollbar.on("scroll", _ => {
                    mldbord.scrollLeft = fakeScrollbar.scrollLeft;
                });

                resizeScrollingClone();
                $(window).on("resize", function () {
                    resizeScrollingClone(); // Gewoon elke 'tick'
                    $(".mldbord-content").addClass("no-transition"); // Snel te intensief
                    if (noTransitionTimer) {
                        clearTimeout(noTransitionTimer);
                    }
                    noTransitionTimer = setTimeout(function () {
                        $(".mldbord-content").removeClass("no-transition");
                    }, 25);
                });

                $(window).on("unload", function () { // Cleanup
                    $fakeScrollbar.off().remove();
                })
            });
        </script>
    </head>

    <body id="mldbordbody">
<%
    params.mldbord = true;
    var sql = mld_list(pautfunction, params);
    var oRs = Oracle.Execute(sql);

    var bord_html = {}; // Verzamelt de gegenereerde HTML per 'kolomwaarde'
    var col_keys = {};  // Verzamelt de kolom-keys met een key per 'kolomwaarde'
    var bord_cols = []; // Verzamelt de 'kolomwaardes'

    // params.mldbordColumn indiceert het type kaartindeling, waarbij;
    // -2 = Primaire behandelaar
    // -3 = Behandelteam
    // -4 = Actieve behandelaar
    // >0 = (srt_)Kenmerk(_key) (hier wordt ook een mldbordColumnDescr meegestuurd die het label van het gekozen kenmerk bevat)

    // Voor kenmerken maken we eerst de kolommen aan, op volgorde van fac_usrdata_volgnr, alfabetisch
    // Andere velden voegen we vooraan 1 lege kolom toe, daarna maken we kolommen aan terwijl we door de records lopen,
    // en tot slot (achteraan dus) vullen we de kolommen aan met lege kolommen voor alle overige mogelijkheden
    var emptyOption = getCardBoxTitle(null, params.mldbordColumn);
    if (params.mldbordColumn > 0) { // Haal eerst alle kolommen op, plak de records in de juiste kolom, en print daarna alles pas
        var srtkenmerk_key = params.mldbordColumn;
        var kenmerk_omschrijving = params.mldbordColumnDescr;
        var sql_k = "   SELECT MAX (mld_kenmerk_verplicht)     mld_kenmerk_verplicht,"
                  + "          kd.fac_kenmerkdomein_objectnaam,"
                  + "          kd.fac_kenmerkdomein_kolomnaam,"
                  + "          kd.fac_kenmerkdomein_kolomtxt,"
                  + "          kd.fac_usrtab_key,"
                  + "          kd.fac_kenmerkdomein_verval"
                  + "     FROM mld_kenmerk k, mld_srtkenmerk sk, fac_kenmerkdomein kd"
                  + "    WHERE     k.mld_srtkenmerk_key = sk.mld_srtkenmerk_key"
                  + "          AND sk.fac_kenmerkdomein_key = kd.fac_kenmerkdomein_key"
                  + "          AND k.mld_kenmerk_verwijder IS NULL"
                  + "          AND sk.mld_srtkenmerk_verwijder IS NULL"
                  + "          AND kd.fac_kenmerkdomein_verwijder IS NULL"
                  + "          AND sk.mld_srtkenmerk_key = " + srtkenmerk_key
                  + "          AND COALESCE (k.mld_kenmerk_omschrijving, sk.mld_srtkenmerk_omschrijving) = " + safe.quoted_sql(kenmerk_omschrijving)
                  + " GROUP BY sk.mld_srtkenmerk_key,"
                  + "          kd.fac_kenmerkdomein_objectnaam,"
                  + "          kd.fac_kenmerkdomein_kolomnaam,"
                  + "          kd.fac_kenmerkdomein_kolomtxt,"
                  + "          kd.fac_usrtab_key,"
                  + "          kd.fac_kenmerkdomein_verval";
        var oRs_k = Oracle.Execute(sql_k);

        if (oRs_k("fac_kenmerkdomein_objectnaam").Value == "FAC_USRDATA") {
            var r_sql = "SELECT fac_usrdata_key rkey"
                      + "     , " + lcl.xsql('fac_usrdata_omschr', 'fac_usrdata_key') + " roms"
                      + "  FROM fac_usrdata "
                      + " WHERE fac_usrtab_key = " + oRs_k("fac_usrtab_key").Value
                      + "   AND (fac_usrdata_vervaldatum IS NULL OR fac_usrdata_vervaldatum > SYSDATE)"
                      + "   AND fac_usrdata_verwijder IS NULL"
                      + " ORDER BY fac_usrdata_volgnr NULLS LAST, roms";
        } else {
            var vervalkolom = oRs_k("fac_kenmerkdomein_verval").Value;
            var r_sql = "SELECT " + oRs_k("fac_kenmerkdomein_kolomnaam").Value + " rkey"
                      + "     , " + oRs_k("fac_kenmerkdomein_kolomtxt").Value + " roms"
                      + "  FROM " + oRs_k("fac_kenmerkdomein_objectnaam").Value
                      + (vervalkolom
                        ? " WHERE (" + vervalkolom + " IS NULL OR " + vervalkolom + " > SYSDATE)"
                        : "")
                      + " ORDER BY roms";
        }

        if (oRs_k("mld_kenmerk_verplicht").Value != 1) { // Begin met een <Niet gevuld>-kolom (indien niet verplicht)
            bord_html[emptyOption] = [];
            col_keys[emptyOption] = null;
            bord_cols.push(emptyOption);
        }
        oRs_k.Close();

        var r_oRs = Oracle.Execute(r_sql);
        while (!r_oRs.EOF) { // Insert kolommen in de juiste volgorde
            bord_html[r_oRs("roms").Value] = [];
            col_keys[r_oRs("roms").Value] = r_oRs("rkey").Value;
            bord_cols.push(r_oRs("roms").Value);
            r_oRs.MoveNext();
        }
        r_oRs.Close();
    } else { // Voeg lege optie toe
        bord_html[emptyOption] = [];
        col_keys[emptyOption] = null;
        bord_cols.push(emptyOption);
    }

    for (
        var cnt = 0; (cnt < S("qp_maxrows") || showAll) &&
                      cnt < S("qp_maxrows2") &&
                      !oRs.EOF; cnt++
    ) {
        var col_key = oRs("mldbordColumnKey").Value; // key vd waarde, bijv. mld_kenmerkmelding_waarde
        var col_val = getCardBoxTitle(oRs, params.mldbordColumn);

        if (!(col_val in bord_html)) { // Zou bij kenmerken niet voor moeten komen, die zijn hiervoor al toegevoegd
            bord_html[col_val] = [];
            col_keys[col_val] = col_key;
            bord_cols.push(col_val);
        }

        var mld_key = oRs("mld_melding_key").Value;
        var mld_nr = (oRs("ins_srtdiscipline_prefix").Value || "") + oRs("mld_melding_key").Value;
        if (S("mld_num_prefix_mode") > 0 && oRs("mld_prefix").Value) {
            mld_nr = oRs("mld_prefix").Value + "#" + mld_nr;
        }
        var flag = oRs("mld_melding_flag").Value;
        var prio = oRs("mld_melding_spoed").Value;
        var prioIcon = mld.getpriocon(prio);
        var prioTitle = mld.getpriotext(prio);

        var headerHtml = '<span class="mldnr semibold">' + safe.html(mld_nr) + '</span>'
                       + '<span class="icons">';
        if (S("mld_melding_flags") > 0) {
            headerHtml += getFlagHtml(oRs);
        }
        if (prioIcon !== "") {
            headerHtml += "<span title='" + safe.htmlattr(prioTitle) + "'>" + I(prioIcon) + "</span>";
        }
        headerHtml += '</span>';

        var card_params = {
            cls: mldlist.fnrowClass(oRs),
            open: bord_html[col_val].length < S("mld_show_cards"),
            data: {
                "key": mld_key
            }
        }
        bord_html[col_val].push(
              CARD_START_HTML(card_params)
            + '<div class="bord-card-header">' + headerHtml + '</div>'
            + '<div class="bord-card-body">'
            + fnCardContent(oRs, params)
            + '</div>'
            + CARD_END_HTML()
        );

        oRs.MoveNext();
    }
    var EOF = oRs.EOF;
    oRs.Close();

    if (params.mldbordColumn > 0) {
        // Kenmerken zijn vooraan al gesorteert
    } else {
        // Sorteer alfabetisch
        bord_cols.sort(function (a, b) { // Lege optie altijd vooraan
            if (a === emptyOption) {
                return -1;
            } else if (b === emptyOption) {
                return 1;
            }
            return a - b;
        });

        // Vul nu aan met alle overige, nog niet voorgekomen opties (lege kolommen);
        var col_sql;
        if (params.mldbordColumn === -2 || params.mldbordColumn === -4) { // Primaire || actieve behandelaar (deze delen veel)
            col_sql = "SELECT p.prs_perslid_key         AS key"
                    + "     , pf.prs_perslid_naam_full  AS descr"
                    + "  FROM prs_v_aanwezigperslid p"
                    + "       JOIN prs_v_perslid_fullnames_all pf"
                    + "           ON p.prs_perslid_key = pf.prs_perslid_key"
                    + (params.caller_key > 0
                      ? "       JOIN prs_v_afdeling d"
                        + "           ON p.prs_afdeling_key = d.prs_afdeling_key"
                      : "")
                    + " WHERE EXISTS"
                    + "           (SELECT 1" // Haakje open
                    + "              FROM fac_v_webgebruiker g"
                    + "             WHERE     g.prs_perslid_key = p.prs_perslid_key"
                    + "                   AND g.fac_functie_key IN (" + F("WEB_MLDFOF") + ", " + F("WEB_MLDBOF") + ")" // mld_edit_bord_save.asp bewaakt de juiste wel
            if (params.mldbordColumn === -2 && params.disc_key_arr && params.disc_key_arr.length > 0) {
                col_sql += "              AND g.ins_discipline_key IN (" + params.disc_key_arr.join(",") + ")";
            } else if (params.mldbordColumn === -4 && params.mld_ins_discipline_key_arr && params.mld_ins_discipline_key_arr.length > 0) {
                col_sql += "              AND g.ins_discipline_key IN (" + params.mld_ins_discipline_key_arr.join(",") + ")";
            }
            if (params.caller_key && params.caller_key > 0) { // Melder bekend, dus afdeling-scope in acht nemen;
                var afd_key = new Perslid(params.caller_key).prs_afdeling_key(); // afdeling van de melder
                col_sql += "              AND (   g.fac_gebruiker_prs_level_write = -1"
                         + "                   OR (    g.fac_gebruiker_prs_level_write = 0"
                         + "                       AND d.prs_bedrijf_key ="
                         + "                           (SELECT aa.prs_bedrijf_key"
                         + "                              FROM prs_v_afdeling aa"
                         + "                             WHERE aa.prs_afdeling_key = " + afd_key + "))"
                         + "                   OR (    g.fac_gebruiker_prs_level_write > 0"
                         + "                       AND EXISTS"
                         + "                               (SELECT 1"
                         + "                                  FROM prs_v_afdeling_familie a"
                         + "                                 WHERE     a.prs_afdeling_key = p.prs_afdeling_key"
                         + "                                       AND a.prs_afdeling_elder_key IN"
                         + "                                           (SELECT aa.prs_afdeling_elder_key"
                         + "                                              FROM prs_v_afdeling_familie aa"
                         + "                                             WHERE     aa.prs_afdeling_key = " + afd_key
                         + "                                                   AND aa.niveau ="
                         + "                                                       g.fac_gebruiker_prs_level_write)"
                         + "                                            )"
                         + "                        ))";
            }
            if (params.loc_key_arr && params.loc_key_arr.length > 0) {
                col_sql += "              AND (   g.fac_gebruiker_alg_level_write = -1"
                         + "                   OR (    g.fac_gebruiker_alg_level_write < 9"
                         + "                       AND EXISTS"
                         + "                           (SELECT 1"
                         + "                              FROM fac_v_my_locations ml"
                         + "                             WHERE ml.prs_perslid_key = p.prs_perslid_key"
                         + "                               AND ml.niveau = g.fac_gebruiker_alg_level_write"
                         + "                               AND ml.alg_locatie_key IN (" + params.loc_key_arr.join(",") + ")"
                         + "                           )"
                         + "                      )"
                         + "                  )";
            }
            col_sql += "          )" // Haakje sluiten
                     + "  AND BITAND(p.prs_perslid_flags, 2) = 0"
                     + "  AND (p.prs_perslid_oslogin IS NULL OR p.prs_perslid_oslogin NOT LIKE '\\_%' ESCAPE '\\')"
                     + "  ORDER BY pf.prs_perslid_naam_full";
        } else if (params.mldbordColumn === -3) { // Behandelteam
            var col_sql = "SELECT ins_discipline_key            AS key"
                        + "     , ins_discipline_omschrijving   AS descr"
                        + "  FROM ins_tab_discipline  td"
                        + "       JOIN mld_disc_params mdp"
                        + "           ON td.ins_discipline_key = mdp.mld_ins_discipline_key"
                        + " WHERE     td.ins_discipline_module = 'MLD'"
                        + "       AND td.ins_discipline_verwijder IS NULL"
                        + "       AND BITAND (mdp.mld_disc_params_srtgroep, 2) = 2";
            if (params.disc_key_arr && params.disc_key_arr.length === 1) { // We nemen alleen behandelteam-scoping in acht bij één enkele vakgroep
                var disc_sql = "  SELECT mld_discipline_key2"
                             + "    FROM mld_discipline_discipline"
                             + "   WHERE mld_discipline_key1 = " + params.disc_key_arr[0];
                var disc_oRs = Oracle.Execute(disc_sql);
                if (!disc_oRs.EOF) {
                    var behandelteam_key_arr = [];
                    while (!disc_oRs.EOF) {
                        behandelteam_key_arr.push(disc_oRs("mld_discipline_key2").Value);
                        disc_oRs.MoveNext();
                    }
                    col_sql += "   AND td.ins_discipline_key IN (" + behandelteam_key_arr.join(",") + ")";
                }
                disc_oRs.Close();
            }
        }
        var cols_oRs = Oracle.Execute(col_sql);
        while (!cols_oRs.EOF) {
            var col_key = cols_oRs("key").Value;
            var col_val = cols_oRs("descr").Value;
            if (!(col_val in bord_html)) { // Alle gebruikten bestaan al, we voegen hier dus alleen lege kolommen toe
                bord_html[col_val] = [];
                col_keys[col_val] = col_key;
                bord_cols.push(col_val);
            }
            cols_oRs.MoveNext();
        }
        cols_oRs.Close();
    }

    // Tot zover het verzamelen van de data/html, hieronder gaan we bezig met het printen van het resultaat

    var hasEmptyColumns = false;
    var hasFilledColumns = false;
    for (var index in bord_cols) {
        var x = bord_cols[index]; // x = Kolomwaarde (en tevens de keys voor de objecten col_keys & bord_html)
        if (bord_html[x].length === 0 && x !== emptyOption) {
            hasEmptyColumns = true;
        } else if (bord_html[x].length > 0) {
            hasFilledColumns = true;
        }
    }

    var compact =
            hasFilledColumns &&                                         // Geen compacte weergave als er dan geen kolommen weer te geven zijn
            S("mld_bord_compact_threshold_columns") >= 0 &&             // Als deze setting == -1, dan default geen compacte modus
            bord_cols.length > S("mld_bord_compact_threshold_columns"); // Alleen default compacte modus initieren als er meer dan {SETTING} kolommen zijn

    var buttons = [];
    if (hasEmptyColumns) {
        buttons.push({
            icon: compact ? "fa-eye" : "fa-eye-slash",
            title: compact ? L("lcl_mldbord_compact_off") : L("lcl_mldbord_compact_on"),
            action: "toggleCardBoxes()",
            id: "compact"
        });
    }
    buttons.push({ icon: "fa-fclt-refresh", title: L("lcl_refresh"), action: "FcltMgr.reload()" });
    buttons.push({ icon: "fa-list-ul",  title: L("lcl_mld_legenda"), action: "openLegenda()" });

    IFRAMER_HEADER(L("lcl_complains"), buttons);
%>
        <div id="collapseblock">
            <div class="mldbord">
                <div class="mldbord-content<%=compact ? " compact" : ""%>">
<%

        if (!EOF) { %>
                    <div id='rsMaxHistoryB'>
                        <span id='rsMaxHistoryInfoB'>
<%          if (showAll) { %>
                            <%=L("lcl_qp_maxrows2").format(S("qp_maxrows2"))%>
<%          } else { %>
                            <a href="#" onclick="parent.window.doSubmit(0, 1, 'bord'); return false;">
                                <%=L("lcl_qp_maxrows1").format(S("qp_maxrows"))%>
                            </a>
<%          } %>
                        </span>
                    </div>
<%      }

        // Hier printen we de echte kolommen in de DOM;
        for (var index in bord_cols) {
            var x = bord_cols[index]; // x = Kolomwaarde (en tevens de keys voor de objecten col_keys & bord_html)
            var cardbox_params = {
                isEmpty: bord_html[x].length === 0,
                data: {
                    "key": col_keys[x]
                }
            }
            Response.Write(CARDBOX_START_HTML(cardbox_params));

%>          <div class="fclt-cardbox-header-wrapper">
                <h5 class="fclt-cardbox-header truncate" title="<%=safe.htmlattr(x)%>">
                    <%=safe.html(x)%>
                </h5>
                <div class="fclt-cardbox-counter badge rounded-pill"><%=bord_html[x].length%></div>
            </div>
<%
            for (var y = 0; y < bord_html[x].length; y++) {
                Response.Write(bord_html[x][y]);
            }

%>          <div class="fclt-card-more pointer <%=(bord_html[x].length > S("mld_show_cards")) ? "open" : "closed"%>" aria-expanded="false">
                <%=I("fa-chevron-down")%>
            </div><%
            Response.Write(CARDBOX_END_HTML());
        }
%>
                </div>
            </div>
        </div>

        <!-- LEGENDA  -->
        <script type="text/javascript">
            function openLegenda()
            {
                var myPosition = "right top+30";
                if (elems.$originalHeaderRow && elems.$originalHeaderRow.length) {
                    myPosition = "right-15 top+"+(parseInt(elems.$fcltFrameHeader.css("top"))+30);
                }
                params = {
                    width: 220,
                    resizable: false,
                    position: { my: "right top", at: myPosition },
                    title: "<%=L("lcl_res_legenda")%>",
                    create: FcltMgr.fnCreateCloseButton("div#legenda")
                };
                $('div#legenda').dialog(params).dialog('open');
                FcltMgr.resized();
            }
        </script>
        <%=mldlist.legendaHtml({ anyorders: mldlist.anyorders })%>
    </body>
</html>
<%
}
%>
