<% /*
     $Revision$
     $Id$

    File:        scaffolding.inc

    Description:
    Parameters:
    Context:
    */

var mode = getQParamSafe("mode", getQParam("id","")!=""?"wrap":"search");
if (mode == "save" || mode == "delete")
    var JSON_Result = true;
%>
<!-- #include file="../Shared/common.inc" -->
<!-- #include file="./scaffolding_common.inc" -->
<% if (mode == "wrap" || mode == "show" || mode == "edit" || mode == "search") { %>
<!-- #include file="../Shared/iface.inc" -->
<% } %>
<% if (mode != "save" && mode != "delete" && mode != "wrap") { %>
<% if (mode != "list" && mode != "print") { %>
<!-- #include file="../Shared/calendar.inc" -->
<!-- #include file="../Shared/selector.inc" -->
<!-- #include file="../Shared/afdelingselector.inc" -->
<!-- #include file="../Shared/persoonselector.inc" -->
<!-- #include file="../Shared/kostenplaatsselector.inc" -->
<!-- #include file="../Shared/stdmeldingselector.inc" -->
<!-- #include file="../Shared/disciplineselector.inc" -->
<!-- #include file="../Shared/flexfileselector.inc" -->
<!-- #include file="../Shared/plaatsselector.inc" -->
<% } %>
<!-- #include file="../Shared/data_recordset.inc" -->
<!-- #include file="../Shared/resultset_table_v2.inc" -->
<% } %>
<!-- #include file="../Shared/json2.js" -->
<!-- #include file="../api2/api2.inc" -->
<!-- #include file="./scaffolding_search.inc" -->
<!-- #include file="./scaffolding_list.inc" -->
<!-- #include file="./scaffolding_wrap.inc" -->
<!-- #include file="./scaffolding_show.inc" -->
<!-- #include file="./scaffolding_edit.inc" -->
<!-- #include file="./scaffolding_save.inc" -->
<!-- #include file="./scaffolding_delete.inc" -->
<!-- #include file="./scaffolding_print.inc" -->
<%
function scaffolding(model, scf_params)
{
    if (typeof model == "function") // Nieuwe stijl is het een function. Even compatible.
        model = new model();
    scf_params = scf_params || {};

    var imodel = getQParam("model", ""); // include model
    if (model.includes && imodel in model.includes)
    {
        if ("included" in scf_params)
            scf_params = scf_params.included[imodel] || {}
        else
            scf_params = {}; // settings gelden alleen op het hoofdmodel?
        scf_params.orgmodel = model;
        scf_params.incsetting = model.includes[imodel];
        // scf_params.incsetting.joinfield zal nu ook altijd in de url voorkomen
        // var parent_key = getQParamInt(scf_params.incsetting.joinfield);
        model = model.includes[imodel].model;
        if (typeof model == "function") // Nieuwe stijl is het een function. Even compatible.
            model = new model();
        scf_params.transit = { "model": imodel };
    }

    // Originele URL voor IIRF rewrite
    var orgurl = Request.ServerVariables("HTTP_X_REWRITE_URL");
    if (orgurl.Count)
        scf_params.this_fullpath = String(orgurl).split("?")[0];
    else
    {
        var orgurl = Request.ServerVariables("HTTP_X_ORIGINAL_URL"); // Origineel van IIS Rewriter
        if (orgurl.Count)
            scf_params.this_fullpath = String(orgurl).split("?")[0];
        else
            scf_params.this_fullpath = String(Request.ServerVariables("SCRIPT_NAME"));
    }
    scf_params.this_path = scf_params.this_fullpath.substring(rooturl.length + 1);

    // Algemene normalizing
    def(model, "record_title",  model.record_name);
    def(model, "records_title",  model.records_name);
    for (var fld in model.fields)
        def(model.fields[fld], "label", fld)

    if ("includes" in model)
    {
        for (var inc in model.includes)
            def(model.includes[inc], "joinfield", model.fields.id.dbs);
    }

    def(model, mode, {});
    def(model, "list", {});
    def(model, "edit", {});
    def(model, "print", {});

    if ("id" in model.fields && "name" in model.fields)
        def(model.list, "columns",  ["id", "name"]);
    else
        if ("id" in model.fields)
            def(model.list, "columns",  ["id"]);
        else
            def(model.list, "columns",  []);

    switch (mode)
    {
        case "search":
            scaffolding_search(model, scf_params);
            break;
        case "list":
            scaffolding_list(model, scf_params);
            break;
        case "wrap":
            scaffolding_wrap(model, scf_params);
            break;
        case "show":
            scaffolding_show(model, scf_params);
            break;
        case "edit":
            scaffolding_edit(model, scf_params);
            break;
        case "save":
            scaffolding_save(model, scf_params);
            break;
        case "delete":
            scaffolding_delete(model, scf_params);
            break;
        case "print":
            scaffolding_print(model, scf_params);
            break;
    }
}

function scf_ROFIELDTR(model, fld, val, key, params)
{
    var params = params || {};
    var field = model.fields[fld];
    if (!field)
    {   // Vanuit scaffolding_search
        field = model.fields[fld.replace(/^(start_|end_)/,"")];
    }
    var txt = val;
    if (txt === null || typeof txt === "undefined")
    {
        if (field.typ == "check")
            txt = 0;
        else if (field.typ == "label")
        {
            scf_LABELTR(fld, field, params);
            return;
        }
        else
            return; // Altijd suppressEmpty
    }
    var org_lcl;
    if (field.islcl && txt && txt.substr(0, 4) == 'lcl_')
    {
        org_lcl = txt;
        txt = L(txt);
        //if (Session("logging") > 0)
        field.label += " <span class='orglcl'>&lt;" + org_lcl + "&gt;</span>";
    }
    var title = "";
    var infoPointer = null;
    var fso = Server.CreateObject("Scripting.FileSystemObject");
    if (typeof txt == "object")
    {
        if ("name" in txt) // Foreigns
        {
            if ("id" in txt)
                title = "Key: " + txt["id"];
            else if ("size" in txt) // Foto's
                title = "Size: {0} bytes".format(txt["size"]);
            if ("content_url" in txt) // Plaatjes en zo
                infoPointer = { Url: txt["content_url"], NewWindow: true };
            else if ("infoPointer" in field)
            {
                infoPointer = field.infoPointer;
                infoPointer.Url += txt.id;
            }
            else if ("foreign" in field)
            {   // Probeer een infopointer te gokken
                var guesses = [field.foreign.modelname, field.foreign.tbl, field.dbs.replace(/\_key$/, "")]
                for (var i = 0; i < guesses.length; i++)
                {
                    var tbl = guesses[i];
                    if (!infoPointer && tbl)
                    {
                        if (tbl.match(/[^a-zA-Z0-9_]/)) // safety, anders fout bij appl\mgt\ins_srtkenmerk.asp?mode=show&id=21
                            continue;

                        var url = "appl/mgt/" + tbl + ".asp";
                        if (fso.FileExists(Server.MapPath("../../" + url)))
                            infoPointer = { Url: url + "?mode=wrap&id=" + txt.id };
                    }
                }
            }
            txt = txt["name"];
        }
        else
            if (field.typ == "datetime")
                txt = toDateTimeString(txt);
            else if (field.typ == "time")
                txt = toTimeString(txt);
            else if (typeof txt == "date" || txt instanceof Date)
                txt = toDateString(txt);
    }
    if (field.iscurrency)
        txt = safe.curr(txt);

    var params = { title: title, infoPointer: infoPointer, org_lcl: org_lcl };
    if (field.translate && key)
        params.translate = { fld: field.dbs, key: key }

    if (field.bits)
    {
        var params_bits = params;
        scf_GROUP_START(model, fld, val, params_bits);

        for (var i=0; i < field.bits.length; i++)
        {
            var bit = field.bits[i];
            if (bit.typ == "check")
            {
                params_bits.readonly = true;
                scf_GROUP_CHECK(bit, "bit_group", val, params_bits, key);
            }
            if (bit.typ == "radio")
            {
                params_bits.readonly = true;
                scf_GROUP_RADIO(bit, "bit_group", val, params_bits);
            }
            else if (bit.typ == "LOV")
            {
                var data = (val.id & bit.mask);
                ROFIELDTR("fldtxt", bit.label, data, params);
            }
        }
        scf_GROUP_END();
    }
    else if (field.typ == "check" || field.typ == "check0")
        ROCHECKBOXTR("fldtxt", field.label, txt, params);
    else
    {
        if (!field.hidden_fld)
        {
            if (field.typ == "memo")
            {
                ROTEXTAREATR("fldtxt", field.label, txt, params);
            }
            else
            {
                ROFIELDTR("fldtxt", field.label, txt, params);
            }
        }
    }
}

function scf_RWFIELDTR(model, fld, val, key, params)
{
    var params = params || {};
    var field = model.fields[fld];

    if (!params.search)
    {
         params.required = field.required;
         params.requiredlevel = field.requiredlevel;
    }

    if (!field)
    {   // Vanuit scaffolding_search
        field = model.fields[fld.replace(/^(start_|end_)/,"")];
    }
    if (field.islcl && val && val.substr(0, 4) == 'lcl_')
    {
        return scf_ROFIELDTR(model, fld, val);
    }

    // we doen automatische listboxen maar vanuit model_generic kan dat te gortig worden
    if (field.foreign && params.search && "num_rows" in field && field.num_rows > 1000) /* of S("qp_maxrows") */
        field.foreign = null;

    if (field.foreign)
    {
        if (typeof field.foreign == 'function')
        {
            scf_ROFIELDTR(model, fld, val, key, params); // Te ingewikkeld?
        }
        else
        {
            var predefined = ""; // Een voorgedefinieerde foreign
            var foreign = field.foreign;
            if (typeof foreign == 'string')
            {
                var predefined = field.foreign.toUpperCase();
                foreign = foreignKeyTable(foreign);
                if (!foreign)
                    MISSING_FOREIGN;
            }
            else if (foreign)
                predefined = foreign.selectorforeign || "";

            if (predefined == "PRS_KOSTENPLAATS")
            {
                FCLTkostenplaatsselector(fld,
                       "sg" + fld,
                       user_key,
                       { label: field.label,
                         kostenplaatsKey: val?val.id:null,
                         filtercode: "foreignfiltercode" in field? field.foreignfiltercode : "AA",
                         required: params.required
                       });
            }
            else if (predefined == "PRS_PERSLID")
            {
                FCLTpersoonselector(fld,
                       "sg" + fld,
                       { label: field.label,
                         perslidKey: val?val.id:null,
                         required: params.required
                       });
            }
            else if (predefined == "PRS_AFDELING")
            {
                FCLTafdelingselector(fld,
                       "sg" + fld,
                       { label: field.label,
                         departmentKey: val?val.id:null,
                         required: params.required
                       });
            }
            else if (predefined == "MLD_STDMELDING")
            {
                FCLTstdmeldingselector(fld,
                       "sg" + fld,
                       { label: field.label,
                         stdmelding_key: val?val.id:null,
                         autfunctionKey: -1,
                         show_expired: true,
                         required: params.required
                       });
            }
            else if (predefined == "MLD_DISCIPLINE")
            {
                FCLTdisciplineselector(fld,
                       "sg" + fld,
                       { label: field.label,
                         disc_key: val?val.id:null,
                         perslidKey: user_key,
                         module: "MLDA",
                         autfunctionKey: -1,
                         required: params.required
                       });
            }
            else if (predefined == "ALG_RUIMTE")
            {
                FCLTplaatsselector(null,
                       { ruimtekey: val?val.id:null,
                         startlevel: 2,
                         eindlevel: 5,
                         required: params.required,
                         requiredlevel: params.requiredlevel,
                         filtercode: "foreignfiltercode" in field?field.foreignfiltercode:"FAC",
                         whenEmpty: L("lcl_search_generic")  // want filter
                       });
            }
            else if (predefined == "ALG_GEBOUW")
            {
                FCLTplaatsselector(null,
                       { ruimtekey: val?val.id:null,
                         startlevel: 2,
                         eindlevel: 3,
                         required: params.required,
                         requiredlevel: params.requiredlevel,
                         filtercode: "foreignfiltercode" in field?field.foreignfiltercode:"FAC",
                         whenEmpty: L("lcl_search_generic")  // want filter
                       });
            }
            else if (predefined == "ALG_LOCATIE")
            {
                FCLTplaatsselector(null,
                       { ruimtekey: val?val.id:null,
                         startlevel: 2,
                         eindlevel: 2,
                         required: params.required,
                         filtercode: "foreignfiltercode" in field?field.foreignfiltercode:"FAC",
                         whenEmpty: L("lcl_search_generic")  // want filter
                       });
            }
            else if (predefined.match(/ALG_VERDIEPING|RES_RSV_RUIMTE|MLD_UITVOERENDE|MLD_OPDR|MLD_MELDING|CNT_CONTRACT/) || !foreign)
            {
                ROFIELDTR("fldtxt", field.label, "TODO: suggest met " + field.foreign);
            }
            else // dan maar gewone select
            {
                var sql = "SELECT " + foreign.key
                        + "     , " + foreign.desc
                        + "  FROM " + foreign.tbl + " " + (foreign.alias||"")
                        + (foreign.where?" WHERE "  + foreign.where:"")
                        + " ORDER BY 2";
                var emptyOption = "";
                if (!params.search)
                {
                    if ("emptyoption" in field)
                        emptyOption = field.emptyoption;
                    else
                        if (val && val.id && params.required)
                            emptyOption = null;
                }
                if (val && typeof val == "object" && "id" in val)
                {   // dereference
                    val = val.id;
                }
                FCLTselector(fld, sql, { label: field.label,
                                         initKey: val||null,
                                         emptyOption: emptyOption,
                                         emptyKey: (field.typ=="key"?-1:""),
                                         readonly: (foreign.readonly?foreign.readonly:false),
                                         required: params.required
                                       });
            }
        }
    }
    else if (field.bits)
    {
        var params_bits = params;
        scf_GROUP_START(model, fld, val, params_bits);

        for (var i=0; i < field.bits.length; i++)
        {
            var bit = field.bits[i];
            if (bit.typ == "check")
            {
                scf_GROUP_CHECK(bit, "bit_group", val, params_bits, key);
            }
            else if (bit.typ == "radio")
            {
                scf_GROUP_RADIO(bit, "bit_group", val, params_bits);
            }
            else if (bit.typ == "LOV")
            {
                var data = (val & bit.mask);
                var sql = api2.splitLOV2sql(bit.LOV);
                FCLTselector(bit.name,
                             sql,
                             { label: bit.label,
                               initKey: params.search?"":data
                             });
            }
        }
        scf_GROUP_END();
    }
    else if (field.LOV)
    {
        if (field.required && field.LOV.split(";").length == 2 && val && val.id == field.LOV.split(";")[0])
        {   // Dit zou FCLTselector ook wel mogen doen....
            scf_ROFIELDTR(model, fld, val);
            return;
        }
        var sql = api2.splitLOV2sql(field.LOV);
        var emptyOption = "";
        if (!params.search)
        {
            if ("emptyoption" in field)
                emptyOption = field.emptyoption;
            else
                if (val && ("id" in val) && params.required)
                    emptyOption = null;
        }
        FCLTselector(fld, sql, { label: field.label,
                                 initKey: params.search?"":(val?val.id:null),
                                 emptyOption: emptyOption,
                                 emptyKey: (field.typ=="key"?-1:""),
                                 required: params.required,
                                 extraclass: params.extraclass
                               });
    }
    else if (field.typ == "check" || field.typ == "check0")
            RWCHECKBOXTR(fld, "fldcheck", field.label, val);
    else if (fld.match(/^(start_|end_)fclt_d_/))
            FCLTcalendar (fld, { initEmpty: 1,
                                 label: field.label,
                                 volgnr: fld.match(/^start_/)?1:2,
                                 required: true,
                                 autosize: field.autosize
                               });
    else if (field.typ == "date" || (field.typ == "datetime" && params.search))
            FCLTcalendar(fld, { label    : field.label,
                                datum    : val,
                                timeField: false,
                                initEmpty: !val,
                                initTimeEmpty: !val,
                                volgnr   : 1,
                                required : params.required,
                                autosize : field.autosize
                              });
    else if (field.typ == "datetime")
            FCLTcalendar(fld, { label    : field.label,
                                datum    : val,
                                timeField: true,
                                initEmpty: !val,
                                initTimeEmpty: !val,
                                timeStep : S("res_h")*60,
                                startTime: S("res_t1"),
                                endTime  : S("res_t2"),
                                volgnr   : 1,
                                required : params.required,
                                autosize : field.autosize
                              });
    else if (field.typ == "label")
    {
        scf_LABELTR(fld, field, params);
    }
    else if (field.typ == "button")
    {
        scf_BUTTONTR(fld, field, params);
    }
    else if (field.typ == "div")
    {
        scf_DIV(fld, field, params);
    }
    else if (field.flexmodule)
    {
        FCLTflexfileselector(fld,
               "sg" + fld,
               {
                 filename: val?val.name:"",
                 label: field.label,
                 flexmodule: field.flexmodule,
                 required: params.required
               });

    }
    else
    {
        if (field.translate && key)
          params.translate = { fld: fld.dbs, key: key };

        params.maxlength = field.len;
        if (field.typ == "memo")
        {
          var pclass = "fld" + (params.required ? " required" : "");
          RWTEXTAREATR(fld, pclass, field.label, val, params);
        }
        else
        {
          switch (field.typ)
          {
              case "varchar": params.datatype = "text"; break;
              case "number":
              case "float": params.datatype = field.typ; break;
              default: params.datatype = "";
          }
          RWFIELDTR(fld, "fld", field.label, val, params);
        }
    }
}

function scf_RWHIDDENTR(model, fld, val)
{
    var v_val = val;
    if (val && typeof val == "object" && "id" in val)
        v_val = val.id;

    var field = model.fields[fld];
    if (val && field && (field.typ == "date" || field.typ == "datetime"))
    {
        v_val = val.valueOf();
    }

    Response.Write('<input type="hidden" id="'+ fld + '" name="' + fld + '" value="' + safe.htmlattr(v_val) + '">');
}

function scf_LABELTR(fld, field, params)
{
    if (field.label || field.labelvalue)
    {
        if (field.labelvalue)
            Response.Write('<tr><td>'+field.label+'</td><td>'+field.labelvalue+'</td></tr>');
        else
            Response.Write('<tr><td colspan="2">'+field.label+'</td></tr>');
    }
}

function scf_BUTTONTR(fld, field, params)
{   // JGL: <div><tr> is ongeldige html. Durf het niet aan te passen
    Response.Write('<div id="tr_'+fld+'"><tr><td class="label">'
                  +'<label for="'+fld+'">'+(field.label?field.label+':':'')+'</label>'
                  +'</td><td><button id="'+fld+'" name="'+fld+'">'+field.defaultvalue+'</button></td></tr></div>');
}

function scf_DIV(fld, field, params)
{
    Response.Write('<div id="'+fld+'" name="'+fld+'">'+field.defaultvalue+'</div>');
}

function scf_GROUP_START(model, fld, val, params)
{
    var field = model.fields[fld];

    scf_RWHIDDENTR(model, fld, val);
    scf_LABELTR(fld, field, params);
}
function scf_GROUP_END()
{
}
function scf_GROUP_CHECK(pgroup, pclass, pvalue, params, pkey)
{
    var params = params||{};
    var group_val = pvalue & pgroup.mask;
    var isallreadonly = params.readonly || (mode == "show");

    Response.Write("<tr " + (params.trclass?"class=\""+params.trclass+"\"":"") +">");
    Response.Write("<td class=\"label " + pclass + "\">");
    Response.Write("<label>" + (pgroup.label?safe.html(pgroup.label):"") + "</label>");
    Response.Write("</td>");

    Response.Write("<td>");
    for (var i=0; i<pgroup.radios.length; i++)
    {
        var bit = pgroup.radios[i];
        var defaultchecked = pkey < 0 && bit.defaultvalue == 1;
        var ischecked = (bit.mask == 0
                        ? (group_val == bit.mask)
                        : ((group_val & bit.mask) == bit.mask)
                        );
        var isreadonly = isallreadonly || bit.readonly;

        Response.Write("<input type=\"hidden\" id=\"has_" + bit.name + "\" name=\"has_" + bit.name + "\" value=\"1\""
                      + (params.readonly ? " disabled" : "")
                      +">");
        Response.Write("<input type=\"checkbox\" id=\"" + bit.name + "\" name=\"" + bit.name + "\""
                      +" class=\"fldcheck\""
                      + (ischecked || defaultchecked ? " CHECKED" : "")
                      + (params.hidden ? " style=\"visibility:hidden\"" : "")
                      + (isreadonly? " disabled" : "")
                      + (params.html ? params.html : "")
                      +">");
        if (bit.label)
        {
            Response.Write("<label for=\"" + bit.name + "\">" + (bit.label ? bit.label :"") + "</label>");
        }
        Response.Write("<br>");
    }
    Response.Write("</td>");
    Response.Write("</tr>");
}
function scf_GROUP_RADIO(pgroup, pclass, pvalue, params)
{
    var params = params||{};
    var group_val = pvalue & pgroup.mask;
    var isallreadonly = params.readonly || (mode == "show");

    Response.Write("<tr " + (params.trclass?"class=\""+params.trclass+"\"":"") +">");
    Response.Write("<td class=\"label " + pclass + "\">");
    Response.Write("<label>" + (pgroup.label?safe.html(pgroup.label):"") + "</label>");
    Response.Write("</td>");

    Response.Write("<td>");
    for (var i=0; i<pgroup.radios.length; i++)
    {
        var bit = pgroup.radios[i];
        var ischecked = (group_val == bit.mask);
        var isreadonly = isallreadonly || bit.readonly;

        if (mode=="show" && ischecked)
        {
            Response.Write("<span>&nbsp;" + safe.html(bit.label) + "<br></span>");
        }
        else if (mode=="edit")
        {
            Response.Write("<input name=\"" + pgroup.name + "\" type=\"radio\" value=\"" + bit.mask + "\""
                          + (ischecked?" checked":"")
                          + (isreadonly? " disabled" : "")
                          +">");
            Response.Write("&nbsp;" + safe.html(bit.label) + "<br>");
        }
    }
    Response.Write("</td>");
    Response.Write("</tr>");
}
%>
