<% /*
     $Revision$
     $Id$

    File:           scaffolding_list.asp

    Description:    Toont een lijst
    Parameters:
    Context:        Vanuit scaffolding.inc
    Note:           model variabele is globaal beschikbaar
    */
%>
<%
function scaffolding_list(model, scf_params)
{
    scf_params.list = scf_params.list || {};
    scf_params.list.columns = scf_params.list.columns || [];
    scf_params.list.groupby = scf_params.list.groupby || [];
    scf_params.list.orderby = scf_params.list.orderby || [];

    var transit = scf_transit2url(scf_params);

    var cols = getQParamArray("columns", []);
    if (cols.length && cols[0])
        scf_params.list.columns = cols;

    var grps = getQParamArray("groupby", []);
    if (grps.length)
        scf_params.list.groupby = grps;

    if (!scf_params.list.columns.length && "list" in model)
    {
        scf_params.list.columns = model.list.columns;
        scf_params.list.groupby = model.list.groupby;
    }

    var modal = model.edit.modal || scf_params.edit && scf_params.edit.modal; // dan doen we een detailrecord altijd modal
    var addmodal = modal || scf_params.edit && scf_params.edit.addmodal;

    FCLTHeader.Requires({js: ["jquery-ui.js"]});
    if ("requires" in scf_params.list)
        FCLTHeader.Requires(scf_params.list.requires);

    if (model.autfunction)
        var authparams = user.checkAutorisation(model.autfunction);
    else
        var authparams = { PRSreadlevel: -1, ALGreadlevel: -1, PRSwritelevel: -1, ALGwritelevel: -1 };

    var showAll = getQParamInt("showall", 0) == 1;
    var outputmode = getQParamInt("outputmode", 0)
    var nobuttons = getQParamInt("nobuttons", 0) == 1;

    var filter = shared.qs2json(model);
    if (scf_params.incsetting && scf_params.incsetting.joinfield in filter) // Zijn we eigenlijk een include?
    {
        transit += "&" + scf_params.incsetting.joinfield + "=" + filter[scf_params.incsetting.joinfield]; // parentkey doorgeven
    }

    var default_url = model.list.default_url;
    if (!default_url && ("show" in model ||"show" in scf_params || model["REST_PUT"] || model["REST_DELETE"]))
    {
        if (modal)
            default_url = scf_params.this_fullpath + "?mode=edit" + transit + "&id=";
        else
            default_url = scf_params.this_path + "?mode=wrap" + transit + "&id=";
    }
    if (default_url && default_url.indexOf("{0}") == -1)
        default_url += "{0}";
    %>
    <html>
      <head>
    <%  FCLTHeader.Generate({ outputmode: outputmode }); %>
<% if (outputmode == 0) { %>
        <script>
          function scf_reload (json)
          {
              FcltMgr.reload({ appendurl: "scf_highlight=" + json.key});
          }
          function scf_show(row)
          {
            var key = row.getAttribute("ROWKEY");
            var url = "<%= default_url %>".format(key);
            <% if (modal) { %>
                $("#<%=model.table%> tbody tr").removeClass("editing updated")
                $(row).addClass('editing');
                FcltMgr.openModalDetail(url, "<%=safe.jsstring(model.record_title)%>", { callback: scf_reload });
            <% } else { %>
                $(row).addClass('dirty');
                FcltMgr.openDetail(url, "<%=safe.jsstring(model.record_title)%>");
            <% } %>
          }
          function scf_add()
          {
            <%
                if (addmodal) {
             %>
                FcltMgr.openModalDetail("<%= scf_params.this_fullpath + "?mode=edit" + transit %>", "<%=L("lcl_add") + " " + safe.jsstring(model.record_title)%>", { callback: scf_reload });
            <% } else { %>
                FcltMgr.openDetail("<%= scf_params.this_path + "?mode=wrap" + transit %>", "<%=L("lcl_add") + " " + safe.jsstring(model.record_title)%>");
            <% } %>
          }

          // Sorteren door drag-and-drop experiment (niet actief)
          // Return a helper with preserved width of cells
          var fixHelper = function(e, ui) {
          	ui.children().each(function() {
          		$(this).width($(this).width());
          	});
          	ui.css('left', "-2px");
          	return ui;
          };

          if (window.$ && 0) // TODO: nog even uit, misschien if ("sequence" in fields)
          $(function () {
            $("#<%=model.table%> tbody").sortable({
            	axis: "y",
            	helper: fixHelper,
            	stop: function( event, ui ) {
                        //ui.item.children('td').css('color', 'red');
            	        var rows = [];
            	        $("#<%=model.table%> tbody tr").each(function()
            	            {
             	                rows.push(this.getAttribute("ROWKEY"));
            	            }
            	        );
            	        FcltMgr.alert(rows);
                }
            }).disableSelection() });;
            <%= scf_params.list.script %>
        </script>
<% } %>
      </head>
      <body id="listbody">
    <%
        // doe maar niet. Headers zijn dan de deur te vroeg uit
        // en we kunnen geen 500-status meer doen? busyLoading(); // via ResultsetTable is te laat (na REST_GET) dus maar zelf
        buttons = scf_params.list.buttons || [];
        if (!nobuttons)
            buttons.push({ icon: "fa-refresh", title: L("lcl_refresh"), action: "FcltMgr.reload()", id: "btn_scf_refresh" });
        if (model["REST_POST"] && authparams.PRSwritelevel < 9 && authparams.ALGwritelevel < 9)
        {
          var addurl = scf_params.this_path + "?mode=wrap" + transit;
          buttons.push({ icon: "fa-plus", title: L("lcl_add"), action: "scf_add()", id: "btn_scf_add" });
        }

        var xxx_params = { filter : scf_params.filter || shared.qs2json(model),
                           columns: scf_params.list.columns,
                           orderby: scf_params.list.orderby,
                           groupby: scf_params.list.groupby };

        if (!("limit" in xxx_params.filter))
        {
            xxx_params.filter.limit = showAll?S("qp_maxrows2"):S("qp_maxrows")
        }

        var isExcel = ((outputmode==2 || outputmode==6) );                  // && (S("excel_mode")==0));
        var isCSV   = ((outputmode==2 || outputmode==6 || outputmode==4) ); // && (S("excel_mode")==1));

        xxx_params.filter.nolimit = (isExcel || isCSV);

        if (scf_params.incsetting) // Zijn we eigenlijk een include? Dan halen we de
        {                          // echte data op via (ons als include van) de 'parent'
            xxx_params.filter.id = xxx_params.filter[scf_params.incsetting.joinfield]; // Die zal er dan zijn
            xxx_params.include = [ getQParam("model") ];
//            xxx_params.columns = []; // De kolommen van de parent hebben we niet nodig
            var xxx_array = scf_params.orgmodel.REST_GET(xxx_params);
            if (xxx_array.length)
                xxx_array = xxx_array[0][getQParam("model")];
        }
        else
        {
            xxx_params.include = xxx_params.include || [];
            for (i in scf_params.list.columns)
            {
                var xmodel = model;
                var fld = scf_params.list.columns[i];
                if (fld.indexOf(".") > 0) // Bij res_ruimte configurations.res_opstelling_key ofwel <include>.<field>
                {
                    var inctable = fld.split(".")[0];
                    xxx_params.include.push(inctable);
                }
            }
            var xxx_array = model.REST_GET(xxx_params);
        }

        var highlight = filter.scf_highlight;
        if (typeof highlight == "string")
            highlight = highlight.split(",");

        function fnRowClass(oRs)
        {
            if (!highlight)
                return null;
            var key = oRs.Fields("id").Value;
            if (inArray(key, highlight))
                return "updated";
            return null;
        }

        function fnRowChecked(oRs)
        {
            if (!highlight || highlight.length <= 1)
                return false;
            var key = oRs.Fields("id").Value;
            if (inArray(key, highlight))
                return true;
            return false;
        }

        // Uniques misbruiken we om een intelligentere tabelkop te kunnen maken
        var title = model.records_title;
        for (var fld in model.fields)
        {
            var field = model.fields[fld];
            if (field.uniquewith && fld in filter) // Dan de andere waarde tonen als tabel
            {
                // Eigenlijk willen we de records_title van de andere tabel.
                // Die is echter niet included
                title = model.fields[field.uniquewith].label;
            }
        }

        var rst = new ResultsetTable({ dataset: xxx_array,
                                       hasMore: model.total_count > xxx_array.length,
                                       keyColumn: ("id" in model.fields?"id":null),
                                       ID: model.table,
                                       title: title,
                                       showAll: showAll,
                                       canCSV: !nobuttons && model.list.canCSV,
                                       rowClass: model.list.rowClass || fnRowClass,
                                       rowChecked: fnRowChecked,
                                       rowData: scf_params.list.fnRowData,
                                       outputmode: outputmode,
                                       noPrint: nobuttons,
                                       noExcel: nobuttons,
                                       buttons: buttons,
                                       filterParams: xxx_array.filterstring, // Filter parameters in de printafdruk weergeven.
                                       noLoading: true // hebben we al eerder gedaan
                                      });

        function fnfncolCheck(fld)
        {
            return function (oRs)
                {
                    if (oRs.Fields(fld).Value == 1)
                        return L("lcl_Yes")
                    else
                        return L("lcl_No")
                }
        }
        function fnfncolTranslatable(fld, field)
        {
            return function (oRs)
                {
                    var plabel = oRs.Fields(fld).Value;
                    if (field.islcl && plabel && plabel.substr(0, 4) == 'lcl_')
                    {
                        plabel =  L(plabel);
                    }
                    var fn = "FcltMgr.stopPropagation(event);iface.translate('{0}', {1}, this.innerText, '{2}', 'input')".format(model.fields[fld].dbs, oRs.Fields("id").Value, safe.jsstring(plabel))
                    return "<span class='facmgtmultilang' onclick='"+safe.htmlattr(fn)+"'>" + safe.html(plabel) + "</span>";
                }
        }
        function fnfncolFunction(fn)
        {
            return function (oRs)
                {
                    return fn(oRs);
                }
        }
        function fnfncolInclude(inctable, fld)
        {
            return function (oRs)
                {
                    var incdata = oRs.Fields(inctable).Value;
                    var safebuilder = [];
                    var done = {};
                    // Het sorteren in de query is ondoenlijk (door de foreigns) dus maar hier
                    incdata.sort(function (a, b) {
                                var valA = a[fld];
                                if (valA && typeof valA == "object" && "name" in valA)
                                    valA = valA["name"];
                                var valB = b[fld];
                                if (valB && typeof valB == "object" && "name" in valB)
                                    valB = valB["name"];
                                return valA <= valB? -1: 1
                            });
                    var maxinline = 99; // hardcoded om te grote pagina's te voorkomen
                    if (incdata.length < maxinline)
                        for (var i = 0; i < incdata.length && i < maxinline; i++)
                        {
                            var val = incdata[i][fld];
                            if (val && typeof val == "object" && "name" in val)
                                val = val["name"];
                            if (!(val in done)) // Voorkom dubbelen (opstelling/ruimte)
                            {
                                safebuilder.push(safe.html(val));
                                done[val] = 1;
                            }
                        }
                    if (incdata.length > maxinline)
                        safebuilder.push("More than {0}".format(maxinline));
                    return safebuilder.join("<br>");
                }
        }

        function fnfnmyFloat(kolom)
        {
            return function (oRs)
            {
                var v = oRs.Fields(kolom).Value;
                return safe.displayfloat(v, 2, true); // true voor trimZeros, we weten helemaal niet of die 2 zo bedoeld was
            }
        }
        function fntotalShow(column, nrlines)
        {
            if (column.datatype == 'currency')
                return safe.curr(column.totalsum);
            else
                return safe.displayfloat(column.totalsum, 2, true);
        }
        function fnfnmyVal(kolom)
        {
            return function (oRs)
            {
                return oRs.Fields(kolom).Value;
            }
        }
        function fnfnlcl(kolom)
        {
            return function (oRs)
            {
                var v = oRs.Fields(kolom).Value;
                if (v && v.substr(0, 4) == 'lcl_')
                    return L(v)
                else
                    return safe.html(v);
            }
        }

        for (i in scf_params.list.columns)
        {
            var xmodel = model;
            var fld = scf_params.list.columns[i];
            var inctable = null;
            if (fld.indexOf(".") > 0) // Bij res_ruimte configurations.res_opstelling_key ofwel <include>.<field>
            {
                inctable = fld.split(".")[0];
                if (model.includes && inctable in model.includes)
                {
                    xmodel = model.includes[inctable].model;
                    var fld = fld.split(".")[1];
                }
                else
                    inctable = null;
            }

            if (!(fld in xmodel.fields)) // Tijdens ontwikkeling vaak fout
            {
                __DoLog(model.fields);
                __DoLog(scf_params.list.columns);
                abort_with_warning("Field '{0}' not found in model '{1}'".format(fld, model.table));
            }
            var field = xmodel.fields[fld];
            if (field.hidden) // Bij een detailrecord is de parent_key op hidden gezet
                continue;

            var coldata = { caption: field.orglabel? field.orglabel: field.label, content: fld, datatype: field.typ, total: field.total };
            if (outputmode == 4)
            {
                coldata.caption = fld; // Naar csv altijd veldnaam
                coldata.caption = coldata.caption.replace(/^(HIDE_F_|FCLT_X_|FCLT_3D_|FCLT_KEY|FCLT_F_|HTML_|FCLT_D_|FCLT_C_)/i, "");
            }
            if (field.foreign || field.LOV) // Foreign en LOV zijn effectief altijd tekst
                coldata.datatype = 'varchar';
            else
                if (field.typ == 'number' || field.typ == 'key')
                    coldata.datatype = 'number'; // Zo verwacht resultsettable dat
            if (fld == 'id' && field.typ == "key")
                coldata.tdClass = 'listid';

            if (field.autofloat) // Vanuit model_reports hebben we niet altijd correct autodetect
            {                    // van het datatype 'float' gedaan. Daarom hier autofloat
                coldata.amount = fnfnmyVal(fld); // voor optellen
                coldata.content = fnfnmyFloat(fld);
                rst.totalShow = fntotalShow;
            }

            if (field.typ == 'check' || field.typ == 'check0')
            {
               coldata.content = fnfncolCheck(fld);
            }
            if (field.listfunction)
            {
                coldata.content = fnfncolFunction(field.listfunction);
            }
            if (field.islcl)
            {
                coldata.content = fnfnlcl(fld);
            }

            // Child tabellen kunnen we inline localizen
            if (field.translate && S("multi_language_option") && modal)
            {
                coldata.content = fnfncolTranslatable(fld, field);
                coldata.caption = "<span class='facmgtmultilangheader' title='{0}'>{1}</span>".format(L("lcl_vertalingen"), coldata.caption);
            }

            if (scf_params.list.actionscol == scf_params.list.columns[i])
                coldata.hasActions = true;

            if (inctable)
            {
                coldata.content = fnfncolInclude(inctable, fld);
            }

            rst.addColumn(new Column(coldata));
        }

        if (scf_params.list.default_action || default_url)
            rst.addAction({ action: scf_params.list.default_action||"scf_show", caption: L("lcl_edit"), isDefault: true } );

        if (scf_params.list.actions)
        {
            for (var i = 0; i < scf_params.list.actions.length; i++)
                rst.addAction(scf_params.list.actions[i]);
        }

        var cnt = rst.processResultset();
%>
      </body>
    </html>
<%
}
%>