<% /*
    $Revision$
    $Id$

    File:        pda/iface.inc
    Description: Vergeljk ../shared/iface.inc maar dan voor Mobile
    Parameters:
    Context:
    Note:

*/ %>
<!-- #include file="../FontAwesome/icons.inc" -->
<%
FCLTHeader.Requires({ plugins: ["jQuery", "bootstrap", "modernizr"], js: ["iface.js"]})

// The mobile version of FCLTHeader
FCLTMHeader =
{
    Generate: function (params)
    {
        if (!params) params = {};
        params.mobile = true;
        FCLTHeader.testTemplateCssRefresh(true); // generate default customer css
        FCLTHeader.Requires({ plugins: ["jQuery"],
                              js: [rooturl + "/appl/pda/mobile.js",
                                   rooturl + "/appl/pda/attachments.js"]
                            });
        if (typeof generateFlexKenmerkBlock === "function" || typeof generateFlexKenmerkCode === "function") { // Heb ik een 'xxx_flexkenmerk.inc'-bestand aan boord?
            FCLTHeader.Requires({
                js: [rooturl+"/appl/Localscripts/signature/signature_pad.min.js"],
                css: [rooturl+"/appl/Localscripts/signature/signature-pad.css"]
            });
        }
        FCLTHeader.Generate(params);
        return;
   }
}

var MOBILE_UI_CLASSES = {
    "input":            " form-control",
    "input_plain":      " form-control-plaintext",
    "textarea":         " form-control",
    "textarea_plain":   " form-control-plaintext",
    "select":           " form-select",
    "checkbox_wrapper": " form-check",
    "checkbox":         " form-check-input",
    "checkbox_label":   " form-check-label",
    "label":            " form-label",
    "button_primary":   " btn btn-primary",
    "button":           " btn btn-outline-primary"
}
var firstButton = false;

function HEADER(params)
{
    params = params || {};

    if (params.title && params.title != "&nbsp;") var safe_title = safe.html(params.title);
    var use_title = (safe_title || params.title || L("lcl_mobile_title")).format(bannerGeoTitle);

    var otap_html = "";
    if (L("lcl_facilitor_header_prefix") != "") {
        otap_html = "<span class='otap-title'>" + L("lcl_facilitor_header_prefix") + "</span>";
    }

    if (getQParamInt("modal", 0) == 1 || params.modal) // Dan params.title in de modal-dialog titel stoppen en geen buttons
    {
        if (params.title)
        {
            %><title><%=use_title%></title>
            <script>
                if (parent && parent.$)
                {
                    parent.$('span.ui-dialog-title').html("<%=safe.jsstring(use_title)%>");
                }
              </script><%
        }
        if (bannerUrl) { %>
            <header class="page-banner fixed-top">
                <img src="<%=safe.htmlattr(bannerUrl)%>">
                <div class="header-title limit-lines-2<%=params.bigtitle ? ' bigtitle' : '' %>"><%=use_title%></div>
                <%=otap_html%>
            </header>
<%      }
        return;
    }

    if (bannerUrl) { %>
        <header class="page-banner fixed-top">
            <img src="<%=safe.htmlattr(bannerUrl)%>">
            <div class="header-title limit-lines-2<%=params.bigtitle ? ' bigtitle' : '' %>"><%=use_title%></div>
            <%=otap_html%>
        </header>
        <div class="spacer"></div>
<%  } %>
<div class="header fixed-top">
    <div class="header-left">
<%
      if (params.go) {
        %><a href="<%=params.go%>" class="<%=MOBILE_UI_CLASSES.button_primary%> icon-button"><%=I("fa-arrow-left fa-lg")%></a><%
      }
      if (params.back && !params.go) {
          %><a onclick="history.back()" class="<%=MOBILE_UI_CLASSES.button_primary%> icon-button"><%=I("fa-arrow-left fa-lg")%></a><% // L("lcl_back")
      }
      if (params.search) {
          %><a href="<%=rooturl + "/appl/pda/"%>productsearch.asp" class="<%=MOBILE_UI_CLASSES.button_primary%> icon-button"><%=I("fa-search fa-lg")%></a><% // L("lcl_search")
      }
      if (params.filterPanel) {
          %><a href="#filterPanel" class="<%=MOBILE_UI_CLASSES.button_primary%> icon-button" data-bs-toggle="offcanvas"><%=I("fa-filter-list fa-lg")%></a><% // L("lcl_filter")
      }
      if (params.useraction) {
          %><a class="<%=MOBILE_UI_CLASSES.button_primary%> icon-button" onclick="<%=params.useraction.action%>"><%=I(ICONS.placeholder(params.useraction.icon) +  " fa-lg")%></a><% // params.useraction.label
      }
%>
    </div><!-- ui-btn-left -->
<%  if (!bannerUrl) { %>
        <div class="header-title limit-lines-2<%=params.bigtitle ? ' bigtitle' : '' %>">
            <%=use_title%>
        </div>
        <%=otap_html%>
<%  } %>
    <div class="header-right">
<%
    if (false && params.profile) { /* Aparte */ // TODO
        var thisuser = prs.prs_perslid(user_key, { withPhoto: true });
        %><a href="<%=rooturl%>/appl/pda/user_info.asp">
            <img src="<%=safe.htmlattr(thisuser.photopaththumb)%>" class="icon-button">
        </a><%
    }

    if (params.theme) { /* Dit is een eigen dropdown */
        var theme_dropdown = [];
        theme_dropdown.push({ "name": "toggle-theme-auto",  "action": "toggleTheme('auto')",  "icon": "fa-circle-half-stroke far", "label": L("lcl_fac_theme_system") });
        theme_dropdown.push({ "name": "toggle-theme-light", "action": "toggleTheme('light')", "icon": "fa-sun-bright", "label": L("lcl_fac_theme_light") });
        theme_dropdown.push({ "name": "toggle-theme-dark",  "action": "toggleTheme('dark')",  "icon": "fa-moon fas", "label": L("lcl_fac_theme_dark") });
        Response.Write(DROPDOWN(theme_dropdown, { "top": true, "theme": true }));
    }

    var top_right_actions = [];
    if (params.refresh) {
        top_right_actions.push({ "name": "refresh", "action": "FcltMgr.reload()", "icon": "fa-fclt-refresh", "label": L("lcl_refresh") });
    }
    if (params.location) {
        top_right_actions.push({ "name": "location", "href": rooturl + "/appl/pda/setlocation.asp", "icon": "fa-map-marker-alt", "label": L("lcl_mobile_setlocation") });
    }
    if (params.addaction) {
        top_right_actions.push({ "name": "add", "href": params.addaction, "icon": "fa-plus", "label": L("lcl_add") });
    }
    if (params.delaction) {
        top_right_actions.push({ "name": "delete", "href": params.delaction, "icon": "fa-times", "label": L("lcl_delete") });
    }
    if (params.customActionRight) {
        top_right_actions.push({ "name": "custom", "action": params.customActionRight.action, "icon": params.customActionRight.icon, "label": params.customActionRight.label });
    }
    if (params.multiactions) {
        top_right_actions.push({ "name": "multiactions", "action": "toggleBulkAction('on')", "icon": "fa-list-check", "label": L("lcl_pda_bulkaction") });
    }
    Response.Write(DROPDOWN(top_right_actions, { "top": true }));
%>
    </div><!-- ui-btn-right -->
<%
      if (params.banner) {
          %><div id="hbanner">&nbsp;</div><%
      }
%>
  </div>
<%
    bannerUrl = null; /* Een banner moet voor elke mobile PAGE_START apart gedefinieerd worden */
}

var FOOTER_PRINTED = false; // Sommige zaken willen we niet dubbelop doen, terwijl 1 asp-pagina wel meerdere FOOTER's kan hebben
function FOOTER(params)
{
    if (!params) params = {};
    // no footer at all when used modal (as a popup somewhere)
    if (getQParamInt("modal", 0) == 1 || params.modal) {
        return;
    }

    if (user.isGroupedUser() || Session("login_by_fallback"))
    {
        return; // Die hebben ook niets met die knoppen te maken
    }

    var sql = "SELECT COUNT(*) berichten"
            + "  FROM web_user_messages"
            + " WHERE prs_perslid_key_receiver = " + user_key
            + "   AND web_user_mess_action_status = 1"
            + "   AND web_user_mess_action_datum > SYSDATE - " + 14;
    var oRs = Oracle.Execute(sql);
    var berichten = Math.min(99, oRs("berichten").Value) || "";
    oRs.Close();

    var hamburger_actions = [];
    hamburger_actions.push({ "name"  : "myprofile",
                             "label" : L("lcl_prs_myprofile"),
                             "icon"  : "fa-user",
                             "href"  : rooturl + "/appl/pda/user_info.asp" });

    if (Application("otap_environment") == "O" || params.mswitch && !device.isapp()) {
        hamburger_actions.push({ "name"  : "mobile2touch",
                                 "label" : L("lcl_mobile_classicmode"),
                                 "icon"  : "fa-tablet",
                                 "action": "toTouch()" });
        if (Application("otap_environment") == "O") {
            hamburger_actions.push({ "name"  : "mobile2desktop",
                                     "label" : L("lcl_desktop_classicmode"),
                                     "icon"  : "fa-desktop",
                                     "action": "toDesktop()" });
        }
    }

    if (Session("app_build") && user.has("WEB_FACQRC")) { /* App-only */
        hamburger_actions.push({ "name"  : "scanqr",
                                 "label" : L("lcl_mobile_scanqr"),
                                 "icon"  : "fa-camera",
                                 "href"  : "qr:" });
    }

    if (Application("otap_environment") == "O" || __Logging > 0) {
        hamburger_actions.push({ "name"  : "togglelogging",
                                 "label" : __Logging > 0 ? "Stop log" : "Start log",
                                 "icon"  : "fa-triangle-exclamation",
                                 "action": "toggleLogging()" });

        hamburger_actions.push({ "name"  : "mobilelogging",
                                 "label" : "Open logging",
                                 "icon"  : "fa-eye",
                                 "action": "openLogging()" });
        if (!FOOTER_PRINTED) {
%>
    <script>
        function toggleLogging(state) {
            var current_state = $(".pda-button-togglelogging").data("state") || 0;
            if (typeof state !== "undefined" && state === current_state) {
                return; // Nothing to do
            }
            $.post("../shared/wislog.asp?logging=" + (current_state ? 0 : 1));
            if (typeof state === "undefined") {
                jqToast("Logging is now " + (current_state ? "off" : "on"));
            }
            $(".pda-button-togglelogging .pda-button-label").text((current_state ? "Start" : "Stop") + " log");
            $(".pda-button-togglelogging").data("state", (current_state ? 0 : 1));
        }

        function openLogging() {
            FcltMgr.windowopen("../fac/fac_StreamFile.asp?logger=0");
        }
<%
        if (__Logging > 0) { %>
        $(function() {
            toggleLogging(1);
        });
<%      } %>
    </script>
<%      } // !FOOTER_PRINTED
    }

    if (Application("otap_environment") == "O") {
        hamburger_actions.push({ "name"  : "logoff",
                                 "label" : "Afmelden",
                                 "icon"  : "fa-power-off",
                                 "action": "logOff()" });
        if (!FOOTER_PRINTED) {
%>
    <script>
        function logOff()
        {
            var data = {};
            <% protectRequest.dataToken("data"); %>
            $.post(
                "<%=rooturl%>/appl/aut/LogOff.asp"
              , data
              , McltCallbackAndThen(logOffCallback)
              , "json"
            );
            return true; // disable button
        }
        function logOffCallback(json, textStatus)
        {
            if (json && json.message)
                logOffCancel();
            else
                parent.location.href = json.return_url;
        }
        function logoff_cancel()
        {
            window.history.back();
        }
    </script>
<%      } // !FOOTER_PRINTED
    } %>

    <footer class="fixed-bottom page-footer">
        <a href="<%=rooturl%>/appl/pda/Facilitor.asp" class="tappable"><%=I("fa-home fa-xl")%></a>
        <a href="<%=rooturl%>/appl/pda/fac_list.asp" class="tappable"><%=I("fa-ballot-check fa-xl")%></a>
        <a href="<%=rooturl%>/appl/pda/message_list.asp" class="tappable"<%=berichten ? ' data-badge="' + berichten + '"' : ''%>>
            <%=I("fa-bell fa-xl")%>
            <span class="fclt-noti-badge badge rounded-pill bg-danger"><%=berichten%></span>
        </a>
<%      if (user.has("WEB_MSGUSE")) { // Any new messages?
            sql = "SELECT fac_gui_counter_date"
                + "  FROM fac_gui_counter"
                + " WHERE fac_gui_counter_group = 'community'"
                + "   AND prs_perslid_key = " + user_key;
            oRs = Oracle.Execute(sql);
            var new_msg = true; // Geen page-visits gevonden? Dan is alles dus nieuw
            if (!oRs.EoF) {
                var last_msg_sql = "SELECT 'dummy'"
                                 + "  FROM fac_nieuws"
                                 + " WHERE BITAND (fac_nieuws_show, 4) = 4"
                                 + "   AND (fac_nieuws_van <= SYSDATE OR fac_nieuws_van IS NULL)"
                                 + "   AND (fac_nieuws_tot > SYSDATE OR fac_nieuws_tot IS NULL)"
                                 + "   AND fac_nieuws_parentkey IS NULL" /* Filter de ##LIKE##'s & reacties eruit */
                                 + "   AND COALESCE (fac_nieuws_van, fac_nieuws_aanmaak) > (" + sql + ")";
                var last_msg_oRs = Oracle.Execute(last_msg_sql);
                new_msg = !last_msg_oRs.EoF; // EoF indien geen nieuwe berichten gevonden sinds laatste bezoek
                last_msg_oRs.Close();
            }
            oRs.Close();
%>      <a href="<%=rooturl%>/appl/pda/berichten.asp" class="tappable"<%=new_msg ? ' data-badge="!"' : ''%>><%=I("fa-circle-y fa-xl")%></a>
<%      } %>
        <%=DROPDOWN(hamburger_actions)%>
    </footer>
<%
    FOOTER_PRINTED = true;
}

var bannerUrl = null;
var bannerGeoTitle = "";
function PAGE_START(params)
{
    params = params || {};
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    if (typeof params.headerImage === "string") { // Een url van een foto
        if (fso.FileExists(Server.MapPath(params.headerImage))) {
            bannerUrl = params.headerImage;
        }
    } else if (typeof params.headerImage !== "undefined" && params.headerImage) { // true of 1 => Foto van standplaats gebouw/locatie
        var geb_key = user.alg_gebouw_key({ "withcurrent": true, "currentIsOptional": true });
        if (geb_key > -1) {
            var sql = "SELECT alg_gebouw_image, alg_gebouw_naam FROM alg_gebouw WHERE alg_gebouw_key = " + geb_key;
            var oRs = Oracle.Execute(sql);
            if (!oRs.EoF) {
                bannerUrl = S("alg_image_path") + "gebouw/" + oRs("alg_gebouw_image").Value;
                if (fso.FileExists(Server.MapPath(bannerUrl))) {
                    bannerGeoTitle = oRs("alg_gebouw_naam").Value;
                } else {
                    bannerUrl = null;
                }
            }
            oRs.Close();
        }
        if (bannerUrl === null) { // Locatie-foto dan?
            var loc_key = user.alg_locatie_key({ "withcurrent": true, "currentIsOptional": true });
            if (loc_key > -1) {
                var sql = "SELECT alg_locatie_image, alg_locatie_omschrijving FROM alg_locatie WHERE alg_locatie_key = " + loc_key;
                var oRs = Oracle.Execute(sql);
                if (!oRs.EoF) {
                    bannerUrl = S("alg_image_path") + "locatie/" + oRs("alg_locatie_image").Value;
                    if (fso.FileExists(Server.MapPath(bannerUrl))) {
                        bannerGeoTitle = oRs("alg_locatie_omschrijving").Value;
                    } else {
                        bannerUrl = null;
                    }
                }
                oRs.Close();
            }
        }
    }
    %>
    <div id="<%=params.id ? params.id : "page"%>" class="page <%=(params.pclass || "") + (bannerUrl ? " image-banner" : "")%>"><%
}
function PAGE_END()
{
   %></div></div><%
}

/* Horizontale groepering van content (Bootstrap column) */
function CONTENT_START(params)
{
   params = params || {};
   %><div class="fclt-content<%=params.pclass ? " " + params.pclass : ""%>"><%
}
function CONTENT_END()
{
   %></div><%
}

/* Groep van buttons/checkboxes/radiobuttons */
function CONTROLGROUP_START(params)
{
    params = params || {};
    firstButton = true;
%>  <section <%=params.id ? ' id="' + params.id + '"' : ''%>><%
}
function CONTROLGROUP_END()
{
    firstButton = false;
%>  </section><%
}

function BLOCK_START_HTML(params)
{
    params = params || {};
    if (params.title && params.title != L("lcl_flexblok")) // Het algemene flexblok wil ik onderdrukken, totdat je een betekenisvolle naam geeft
    {
        if (params.safe !== false && params.title && params.title != "&nbsp;") {
            var safe_title = safe.html(params.title);
        }
        var guid = shared.random(32);
        resultstr = "<section" + (params.pId? " id='" + params.pId + "'" : "")
                  + " class='card card-body fclt-block'>"
                  + "<h5 class='card-title limit-lines-2'"
                  + (params.collapsed
                    ? " data-bs-toggle='collapse' data-bs-target='." + safe.htmlattr(guid) + "' aria-expanded='false'>"
                    : ">")
                  + (safe_title || params.title) + (params.count? '<span class="ui-li-count">' + params.count + '</span>' : '')
                  + "</h5>"
                  + "<span" + (params.collapsed ? " class='" + safe.htmlattr(guid) + " collapse'" : "") + ">";

        if (params.treatable && params.treatable.isTreatable)
        { // De selectboxen behandelteams en behandelaar aan de bloktitiel toevoegen.
            var params_disc  = params.treatable.disc;
            var params_prs   = params.treatable.prs;
            var params_compl = params.treatable.compl;
            var urlAdd_disc  = [{ urlParam: "disc", field: "disc", init: params_disc.disc }];
            var urlAdd_prs   = [{ urlParam: "prs_key",  field: "person",           init: params_prs.melder_key },
                                { urlParam: "disc_key", field: params_prs.disc_id, init: params_prs.disc_key }];
            if (params_prs.show_alg)
                urlAdd_prs.push({   urlParam: "loc_key",  field: "locatiekey",       init: params_disc.loc_key});
            resultstr += "    <span class='span_treatable nowrap'>"
                       + "      <div id='span_treatable1_" + params.treatable.kkey + "'>"
                       + FCLTdisciplineselector_HTML(params_disc.id,
                                                       "sg" + params_disc.id,
                                                       { disc_key: params_disc.disc_key,
                                                       module: "MLDB",
                                                       perslidKey: params_disc.perslidKey,
                                                       autfunctionKey: -1, // Alles is toegestaan! authparams.autfunctionkey,
                                                       srtdisc_key: (S("mld_processing_group_all") == 1)? null : params_disc.srtdisc_key,
                                                       onChange: "onChange" + params_disc.id,
                                                       readonly: params_disc.reado,
                                                       urlAdd: urlAdd_disc,
                                                       noJustOne: true,
                                                       required: false,
                                                       whenEmpty: L("lcl_select_mld_process_grp_blok")
                                                       })
                       + "      </div>"
                       + "      <div id='span_treatable2_" + params.treatable.kkey + "'>"
                       + FCLTpersoonselector_HTML(params_prs.id,
                                                   "sg" + params_prs.id,
                                                   { perslidKey: params_prs.prs_key,
                                                   autlevel: params_prs.prsautlevel,
                                                   urlAdd: urlAdd_prs,
                                                   readonly: params_prs.reado,
                                                   filtercode: "BH2B",
                                                   whenEmpty: L("lcl_select_mld_processor_blok")
                                                   })
                       + "      </div>"
                       + CHB_FIELD_HTML(params.treatable.flexid + "complete", L("lcl_close"), params_compl.value, {disabled: params_compl.reado})
                       + "      <hr>"
                       + "    </span>";

            resultstr += "<script type='text/javascript'>"
                       + "  function onChange" + params_disc.id + "(behandelteam_key)"
                       + "  {"
                       + "    if (typeof sg" + params_prs.id + " != 'undefined')"
                       + "    {"
                       + "      if (behandelteam_key == -1)" // Efficiënter
                       + "        sg" + params_prs.id + ".setValue(-1, '');"
                       + "      else"
                       + "        sg" + params_prs.id + ".setValue($('#" + params_prs.id + "').val(), $('#" + params_prs.id + "_show').val(), true, true);"
                       + "    }"
                       + "  }"
                       + "</script>";
        }
        return resultstr;
   }
   else {
        return "<section"
             + (params.pId ? " id='" + params.pId + "'" : "")
             + " class='fclt-block'"
             + ">";
   }
}
function BLOCK_END_HTML()
{
    return "<span></section>";
}
function BLOCK_START(params)
{
    Response.Write(BLOCK_START_HTML(params));
}
function BLOCK_END()
{
    Response.Write(BLOCK_END_HTML());
}

/* Een container met daarbinnen CARD's */
function CARDS_WRAPPER_START_HTML(params) {
    params = params || "";

    var horiz = params.layout && params.layout === "horizontal";
    var result = "<section>";
    if (params.title) {
        var elem = params.nested ? "h6" : "h2";
        result += "<" + elem + " class='section-title'>" + params.title + "</" + elem + ">";
    }
    if (params.moreLink) {
        result += "<a class='more-link' href='" + params.moreLink + "' data-ajax='false'>"
                + I("fa-arrows-maximize")
                + "</a>";
    }
    result += "<div class='" + (horiz ? "fclt-row-horizontal overflow-x-auto flex-nowrap" : "fclt-cards-wrapper") + (params.cls ? " " + params.cls : "") + "'>";
    return result;
}
function CARDS_WRAPPER_END_HTML(params) {
    params = params || "";
    var result = "</div>"
               + "</section>";
    return result;
}
function CARDS_WRAPPER_START(params) {
    Response.Write(CARDS_WRAPPER_START_HTML(params));
}
function CARDS_WRAPPER_END(params) {
    Response.Write(CARDS_WRAPPER_END_HTML(params));
}

function CARD_START_HTML(params) {
    params = params || {};
    var result = "<article class='" + (params.cls ? " " + params.cls : "") + "'";
    if ("action" in params) {
        result += " onclick='" + params.action + "'";
    }
    if ("data" in params) {
        for (var x in params.data) {
            result += " data-" + x + "='" + params.data[x] + "'";
        }
    }
    result += ">"
            + "<div class='card" + (params.card_class ? " " + params.card_class : "") + "'>";
    if (!params.noPadding) {
        result += "<div class='card-body'>";
    }
    if (params.title) {
        var elem = (params.cls || "") == "nested" ? "h3" : "h2";
        result += "<" + elem + " class='card-title'>" + params.title + "</" + elem + ">";
    }
    return result;
}
function CARD_END_HTML(params) {
    params = params || {};
    var result = "";
    if (params.more) {
        result += "<div class='tappable text-center rounded fclt-more'>" + I("fa-chevron-down") + "</div>";
    }
    if (!params.noPadding) {
        result += "</div>";
    }
    result += "</div></article>";
    return result;
}
function CARD_START(params) {
    Response.Write(CARD_START_HTML(params));
}
function CARD_END(params) {
    Response.Write(CARD_END_HTML(params));
}

function CONTAINER_START()
{
   %><div><%
}
function CONTAINER_END()
{
   %></div><%
}
function FILTER_PANEL_START() { %>
    <div class="offcanvas offcanvas-start" tabindex="-1" id="filterPanel" aria-labelledby="filterPanelLabel">
        <div class="offcanvas-header">
            <h5 class="offcanvas-title" id="filterPanelLabel"><%=L("lcl_mobile_panel_filter_title")%></h5>
            <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="<%=L("lcl_close_window")%>"></button>
        </div>
        <div class="offcanvas-body">
<%
}
function FILTER_PANEL_END() { %>
        </div>
    </div>
<%
}

function LISTVIEW_START()
{
    %><ul><%
}
function LISTVIEW_END()
{
    %></ul><%
}
function LISTVIEW_DIVIDER(params)
{
    %><li><%=params.title%></li><%
}
function LIST_KENMERK_COL(oRs, params)
{   // Toon in een lijst met bezoekers, meldingen, objecten, etc.  de kenmerken.
    var v_params = params || {};
    var v_flex = "";
    var v_kmcol = ("kmcol" in params ? params.kmcol : "flex");
    var flexdata = oRs(v_kmcol).Value;
    if (flexdata)
    {
        var v_prop = "";
        v_flex_arr = flexdata.split("\r");
        for (var i=0; i<v_flex_arr.length; i++)
        {
            v_prop += safe.html(v_flex_arr[i]) + "<br>";
        }
        v_flex = "" //"<br>"
               + "<div>"
               + "  <table>"
               + "    <tr>"
               + "      <td style='vertical-align:top;'>"
               + "        <span>" + I("fa-info-square fa-lg") + "</span>"
               + "      </td>"
               + "      <td>"
               + "        <span class='list-properties'>" + v_prop + "</span>"
               + "      </td>"
               + "    </tr>"
               + "  </table>"
               + "</div>";
    }
    return v_flex;
}

function GRID_START(columns, params)
{
   params = params||{};
   var vgridclass = '';
   switch (columns)
   { // maximaal 5 kolommen. 1 kolom bestaat niet.
     case 1: break;
     case 2: vgridclass = ' class="ui-grid-a"'; break;
     case 3: vgridclass = ' class="ui-grid-b"'; break;
     case 4: vgridclass = ' class="ui-grid-c"'; break;
     case 5: vgridclass = ' class="ui-grid-d"'; break;
   }
   %><div<%=vgridclass%>><%
}

function GRID_END()
{
   %></div><!-- GRID --><%
}

// Parameter items is een array van { href, img, desc }-objecten
function ICON_GRID_HTML(items)
{
    var ITEMS_PER_ROW = 4;
    // The icons / columns
    var menu_cols_html = "";
    for (var x in items) {
        var item = items[x];
        menu_cols_html += "<a class='col-" + (12 / ITEMS_PER_ROW) + " menu-item tappable' href='" + safe.htmlattr(item.href) + "'>"
                        + "  <div class='menu-icon tappable-target'>"
                        +      item.img
                        + "  </div>"
                        + "  <div class='menu-caption limit-lines-2'>" + safe.html(item.desc) + "</div>"
                        + "</a>";
    }

    // Layout
    var result = CARD_START_HTML()
               + "<div class='icon-grid container-fluid'>"
               + "  <div class='row'>"
               + menu_cols_html
               + "  </div>"
               + "</div>"
               + CARD_END_HTML();

    return result;
}

function ICON_GRID(items)
{
    Response.Write(items.length ? ICON_GRID_HTML(items) : L("lcl_empty_rstable"));
}

function COL_START(column, params)
{
   params = params||{};
   var vcolclass = '';
   var vcolwidth = (params.width ? ' style="width:'+params.width+'%"' : '');
   switch (column)
   { // maximaal 5 kolommen
     case 1: vcolclass = ' class="ui-block-a"' + vcolwidth; break;
     case 2: vcolclass = ' class="ui-block-b"' + vcolwidth; break;
     case 3: vcolclass = ' class="ui-block-c"' + vcolwidth; break;
     case 4: vcolclass = ' class="ui-block-d"' + vcolwidth; break;
     case 5: vcolclass = ' class="ui-block-e"' + vcolwidth; break;
   }
   %><div<%=vcolclass%>><%
}

function COL_END()
{
   %></div><%
}

function LISTCOUNTER(p)
{
  return "<span class='ui-li-count'>"+ p + "</span>"
}

function ROFIELD(pclass, plabel, pvalue, params) {
  Response.Write(ROFIELD_HTML(pclass, plabel, pvalue, params));
}

function ROFIELD_HTML(pclass, plabel, pvalue, params)
{
  params = params || {};
  var resultstr = "";
  if (!pvalue && (params && params.suppressEmpty))
    return; // snel klaar
  if (!params.moreinfo && params.type)
    switch(params.type)
    {
      case "mail":
      case "email":
      case "e-mail":
      case "mailto":
        params.moreinfo = "mailto:" + pvalue;
        break;
      case "tel":
      case "phone":
      case "callto":
      case "telefoon":
        params.moreinfo = S("pda_phone_protocol") + ":" + (params.phone_number || pvalue);
        break;
    }
  if (params.moreinfo)
    params.disabled = true;
  params.readonly = true;
  if (!plabel)
  { // Heel simpel
    resultstr += "<div class='" + pclass + "'>" + safe.fclthtml(pvalue) + (params.html || "") + "</div>";
    return resultstr;
  }

  if (pclass) params.pclass = pclass;
  resultstr += RWFIELD_HTML(null, plabel, pvalue, params);
  if (params.withhidden)
  {
    resultstr += "<input type='hidden' id='"+params.withhidden.id+"' name='"+params.withhidden.id+"' value='"+safe.htmlattr(params.withhidden.value)+"'>";
  }

  return resultstr;
}

function RWFIELD(pId, plabel, pvalue, params) {
  Response.Write(RWFIELD_HTML(pId, plabel, pvalue, params));
}

function RWFIELD_HTML(pId, plabel, pvalue, params)
{
  params = params || {};
  var resultstr = "";
  var vlabel = plabel? "<label" + (pId? " for='"+pId+"'" : "")
                                + ((!params.readonly&&!params.disabled)? " class='ed'" : "") + ">" + safe.html(plabel) + "</label>" : "";
  var hasPhoneIcon = params.type && inArray(params.type, ["tel", "phone", "callto", "telefoon"]);
  params.pclass = (params.pclass || "");
  if (hasPhoneIcon)
      params.pclass += " hasPhoneIcon";
  if (params.disabled || params.readonly) {
      params.pclass += " ui-disabled" + MOBILE_UI_CLASSES.input_plain;
  } else {
    params.pclass += MOBILE_UI_CLASSES.input;
  }
  var vinputattr = "";
  if (pId)
  {
    vinputattr += " name='" + (params.name ? params.name : pId) + "' id='" + pId + "'";
  }
  vinputattr += (params.disabled || params.readonly? " readonly" : "");
  vinputattr += (params.pclass? " class='" + params.pclass + "'" : "");
  vinputattr += (params.datatype? " type='" + params.datatype+"'" : " type='text'");
  vinputattr += (params.html? " "+params.html : "");
  vinputattr += (params.onkeyup? " onkeyup='" + params.onkeyup + "'" : " type='text'");


  if ((!params.multi || !params.disabled) && params.readonly)
      pvalue = shared.stripbbcodes(pvalue);

  vinput = (params.multi
             ? (params.disabled
                 ? safe.fclthtml(pvalue)
                 : "<textarea " + vinputattr + ">" + safe.textarea(pvalue) + "</textarea>"
               )
             : "<input " + vinputattr + " value='" + safe.htmlattr(pvalue) + "' />"
           );
  if (params.moreinfo && params.disabled)
  {
    if (params.multi && plabel)
      vlabel = "<a class='moreinfo' href='" + safe.htmlattr(params.moreinfo) + "'>" + vlabel + "</a>";
    else
      vinput = "<a class='moreinfo' href='" + safe.htmlattr(params.moreinfo) + "'>" + vinput + "</a>";

    if (hasPhoneIcon)
    {
      resultstr += "<script>"
                 + "  $(function()"
                 + "  {"
                 + "    var $phoneIcon = \"<div class='suggestklikker'><span class='suggestklikker'>" + I("fa-phone") + "</span></div>\";"
                 + "    $('input" + (params.pclass? "." + params.pclass.split(" ").join(".") : "") + (pId? "#" + pId + "[name=" + pId + "]" : "") + "[type=" + (params.datatype || "text") + "]').after($phoneIcon);"
                 + "  });"
                 + "</script>"
    }
  }
  resultstr += vlabel + "<div" + (hasPhoneIcon ? " class='input-icon-wrapper'" : "") + ">" + vinput + "</div>"

  return resultstr;
}

function HIFIELD(pId, pValue, params) {
    params = params || {};
    Response.Write(HIFIELD_HTML(pId, pValue, params));
}

function HIFIELD_HTML(pId, pValue, params)
{ // Hidden input field
    var params = params || {};
    var vinput = "<input type='hidden'"
               + ( typeof pId !== "undefined"
                 ? " id='" + pId + "' name='" + (params.name ? params.name : pId) + "'"
                 : ""
                 )
               + ( typeof pValue !== "undefined"
                 ? " value='" + safe.htmlattr(pValue) + "'"
                 : ""
                 )
               + " />\n";
    return vinput;
}

function BTN_BACK(plabel)
{
  BUTTON(L("lcl_back"), { click: "window.history.back(1)", icon: "fa-arrow-left" });
}

// TODO Bootstrap
function BUTTON_HTML(plabel, params) {
    params = params || {};
    var html = "<a";
    html += params.id         ? " id='" + params.id + "'" : "";
    if (!("primary" in params) && firstButton) {
        params.primary = true;
        firstButton = false;
    }
    html += " class='" + (params.cls || "")
          + (params.primary ? MOBILE_UI_CLASSES.button_primary : MOBILE_UI_CLASSES.button)
          + "'"
    html += " role='button'"
    html += params.click      ? " onclick='mobile.button.click(event, this)' mobClick='" + safe.htmlattr(params.click) + "'" : "";
    html += params.singlepress? " singlepress=1":"";
    if (params.linkid) {
        if (params.linkid.indexOf("#") === 0) {
            html += " onclick='mobile.changePage(\"" + safe.htmlattr(params.linkid.slice(1)) + "\")'";
        } else {
            html += " href='" + safe.htmlattr(params.linkid) + "'";
        }
    }
    if ("attributes" in params) {
        for (var x in params.attributes) {
            html += " " + x + "=\"" + params.attributes[x] + "\"";
        }
    }
    html += ">"
          + (params.icon ? I(params.icon) : "")
          + plabel
          + "</a>";
    html = "<div class='btn-wrapper'>" + html + "</div>";
    return html;
}

function BUTTON(plabel, params)
{
    params = params || {};
    var html = BUTTON_HTML(plabel, params);
    Response.Write(html);
}

// TODO Bootstrap
function BTN_SUBMIT(plabel, pform)
{
  var save_icon = "fa-fclt-save";
  %><a data-icon='<%=ICONS.placeholder(save_icon, true)%>' onclick="$('#<%=pform%>').submit()" ><%=plabel%></a><%
}

function CHB_FIELD_HTML(pId, plabel, pvalue, params)
{
    params = params || {};
    var vlabel = "";
    var vinput = "<input type='checkbox' class='" + MOBILE_UI_CLASSES.checkbox + " " + (params.pclass ? params.pclass : "") + "' ";
    if (pId)
    {
        vinput += "name='" + pId + "' id='" + pId + "' ";
        vlabel += "<label class='" + MOBILE_UI_CLASSES.checkbox_label + "' for='" + pId + "'>" + plabel + "</label>";
    }
    vinput += (pvalue && pvalue==1 ? "checked " : "");
    vinput += (params.disabled ? "disabled " : "")
            + (params.html ? params.html + " " : "");
    vinput += (params.onclick ? "onclick='" + params.onclick + "' " : "");
    vinput += "/>";
    // Net als in /Shared/iface.inc voegen we hier een hidden field has_xxxx toe
    if (pId)
        vinput += "<input type='hidden' id='has_" + pId + "' name='has_" + pId + "' value='1' " + (params.disabled ? ' disabled' : '') + ">";
    if ("inline" in params && !params.inline) {
        return vlabel + '<div class="' + MOBILE_UI_CLASSES.checkbox_wrapper + (params.big ? " big_radio" : "") + '">' + vinput + '</div>';
    } else {
        return '<div class="' + MOBILE_UI_CLASSES.checkbox_wrapper + (params.big ? " big_radio" : "") + '">' + vinput + vlabel + '</div>';
    }
}

function CHB_FIELD(pId, plabel, pvalue, params)
{
    params = params || {};
    Response.Write(CHB_FIELD_HTML(pId, plabel, pvalue, params));
}

function RADIO_GROUP_HTML(pName, pButtons, params)
{
    params = params || {};
    var result = "";
    for (var r = 0; r < pButtons.length; r++)
    {
        var radio = pButtons[r];
        var this_radio = "<input type='radio' name='" + pName + "'"
                       + " id='" + radio.id + "'"
                       + " class='" + MOBILE_UI_CLASSES.checkbox + "'"
                       + " value='" + radio.value + "' "
                       + (radio.checked ? " checked='checked'" : "")
                       + (radio.disabled ? " disabled='disabled'" : "")
        for (var x in radio.data) {
            this_radio += " data-" + x + "='" + safe.htmlattr(radio.data[x]) + "'";
        }
        this_radio += ">";
        this_radio += "<label class='" + MOBILE_UI_CLASSES.checkbox_label + "' for='" + radio.id + "'>" + safe.html(radio.label) + "</label>";
        result += "<div class='" + MOBILE_UI_CLASSES.checkbox_wrapper + (params.big ? " big_radio" : "") + "'>" + this_radio + "</div>";
    }
    return result;
}

function RADIO_GROUP(pName, pButtons, params)
{
    if (!pButtons || !pButtons.length) {
        return ""; // Geen buttons, dus niets te doen
    }
    params = params || {};
    Response.Write(RADIO_GROUP_HTML(pName, pButtons, params));
}

function FORM_START(pId, params)
{
    var params = params || {}
    var vform = "<form" + ( pId ? " id='" + pId + "'" + (params.name ? "" : " name='" + pId + "'") : "")
                        + ( params.name ? " name='" + params.name + "'" : "")
                        + ( params.action ? " action='" + safe.htmlattr(params.action) + "'" : "")
                        + ( params.method && (inArray(params.method.toUpperCase(), ["GET", "POST"])) ? " method='" + params.method.toUpperCase() + "'" : "")
              + ">\n";
    Response.Write(vform);
}

function FORM_RVT()
{
    protectRequest.inputToken();
}

function FORM_END()
{
    Response.Write("</form>\n");
}

// Kopie uit ../shared/iface.inc
IFACE =
{
    FORM_END: function()
    {
        protectRequest.inputToken();
    }
}

function DROPDOWN(actions, params) {
    params = params || {};
    if (!actions.length) {
        return "";
    }

    var wrappingCls = (params.top
                        ? MOBILE_UI_CLASSES.button_primary + " icon-button"
                        : "");
    if (actions.length === 1) {
        var action = actions[0];
        if (params.top) {
            action.icon += " fa-lg";
        } else {
            wrappingCls += " tappable col";
            action.icon += " fa-xl";
        }
        var elem = ("action" in action) ? "div" : "a"; // Javascript vs <a>nchor
        var res = "<" + elem + " class='pda-button-" + safe.htmlattr(action.name) + wrappingCls + "'";
        if ("action" in action) {
            res += " onclick='" + safe.htmlattr(action.action) + "'>";
        } else if ("href" in action) {
            res += " href='" + safe.htmlattr(action.href) + "'>";
        }
        res += I(action.icon)
             + "</" + elem + ">";
        return res;
    }

    // Nu verder voor de eigenlijke dropdown (= meer dan 1 actie)
    function _makeAction(action) {
        var elem = ("action" in action) ? "div" : "a"; // Javascript vs <a>nchor
        var res = "<" + elem + " class='pda-button-" + safe.htmlattr(action.name) + " tappable'";
        if ("action" in action) {
            res += " onclick='" + safe.htmlattr(action.action) + "'>";
        } else if ("href" in action) {
            res += " href='" + safe.htmlattr(action.href) + "'>";
        }
        res += I(action.icon)
             + "<span class='pda-button-label'>" + safe.html(action.label) + "</span>";
        res += "</" + elem + ">";
        return res;
    }

    var dd_Menu = "<div class='pda-action-menu"
                + (params.top ? " top" : "")
                + "'>";
    for (x in actions) {
        dd_Menu += _makeAction(actions[x]);
    }
    dd_Menu += "</div>";
    if (params.top) {
        return "<span class='pda-button-more" + wrappingCls + "'" + (params.theme ? " data-theme-toggle" : "") + ">" + I("fa-bars") + dd_Menu + "</span>";
    } else {
        return "<span class='pda-button-more" + wrappingCls + "'>" + I("fa-bars fa-xl") + dd_Menu + "</span>";
    }
}

function shorttxt(txt, len)
{
    len = len || S("max_tracking_length");
    txt = txt || "";
    txt = txt.replace(/\n\s*\n/ig, "\n"); // Geheel lege regels of met alleen whitespace

    if  (txt.length < len)
        return txt;

    // Oke, op scherm afkappen na len karakters.
    // Probeer op de eerste spatie maar die moet wel binnen 20% karakters komen
    var spatie = String(txt).substr(len).indexOf(" ");
    if (spatie < 0 || spatie > len/5)
        spatie = 0;
    return txt.substr(0, len+spatie+1) + "...";
}

function SYMBOL(name, params) {
    params = params || {};
    var symbol = name || params.defVal;
    if (symbol && symbol.match(/^fa-/) !== null) {
        return I(symbol, params);
    } else {
        return IMG(symbol, params);
    }
}

function IMG(fileName, params) {
    if ("module" in params) {
        var fso = Server.CreateObject("Scripting.FileSystemObject");
        var flexParams = {};
        if ("key" in params) {
            flexParams.getFiles = true;
        } else if (fileName) {
            flexParams.getFile = fileName;
        }
        flexParams.cacheablehmac = true;
        var fileProps = flexProps(params.module, params.key || null, null, null, flexParams);
        if (fileProps.files.length && fso.FileExists(fileProps.AttachPath + fileProps.files[0].name)) {
            return "<img loading='lazy' src='" + safe.htmlattr(fileProps.files[0].deepurl) + "' alt='" + safe.htmlattr(params.alt || L("lcl_photos")) + "'>";
        } else if (fileName) {
            return "<span title='{0}'>".format(safe.htmlattr(fileName || "")) + I("fa-question") + "</span>";
        }
    }
    return "";
}

// Returns an icon to be displayed. icon can be an image (e.g. "notfound.png") or a fontawesome icon-name (e.g. "fa-user")
// trailing fa-qualifiers (e.g. "fa-2x fa-rotate-180" are preserved
// The optional params provides some options
//    params.fastyle: overrule global fastyle
function I(icon, params)
{
    if (!icon)
        return "";
    var params = params || {};

    if (icon.match(/^fa-/))
    {
        var lstyle = params.fastyle == null ? S("fontawesomestyle") : params.fastyle;
        var fa_fw = !("fa_fw" in params) || params.fa_fw ? " fa-fw" : ""; /* Default met fa-fw maar je kunt het er afhalen met { fa-fw: false } */
        var icon_arr = icon.split(/\s/);
        for (var i = 0; i < icon_arr.length; i++)
            icon_arr[i] = ICONS.placeholder(icon_arr[i]); /* Vervang door placeholder icon indien aanwezig */
        icon = icon_arr.join(" ");

        /* Geef ik een style mee in de icoon naam, bijv: I("fa-image fas"), dan is die leidend, nuttig voor placeholder-overrules */
        var styles = ["fal", "far", "fas"];
        for (style in styles)
            if (inArray(styles[style], icon.split(/\s/)))
            {
                lstyle = styles[style];
                icon = icon.replace(new RegExp("\\s?" + lstyle), "");
            }
        return "<i class='{0}{1} {2}'></i>".format(lstyle, fa_fw, safe.htmlattr(icon));
    }
    return "";
}

function PDA_PAGE_START() {

}

function PDA_PAGE_END() {
    if (typeof generateFlexKenmerkBlock === "function" || typeof generateFlexKenmerkCode === "function") {
        PAGE_START({ id: "page-signature" })
            // De title alleen op de mobile hash-pagina gebruiken, niet in de desktop modal-dialog titel
            HEADER({ title: (getQParamInt("modal", 0) == 1 ? "" : L("lcl_sign_here")), back: false });
            CONTENT_START();
%>
        <form id="form-signature" name="form-signature">
<%          IFACE.FORM_END(); %>
        </form>
<%          CONTENT_END();
        PAGE_END();
    }
}
%>