<% /*
     $Revision$
     $Id$

    File:               res_plan_obj_v2.inc
    Description:        Het echte genereren van het planbordje voor objecten
                        via functie make_plan_obj() die een grid oplevert
    Parameters:         params: hour_px
                                reg_key
                                dist_key
                                loc_key
                                geb_key
                                ver_key
                                rui_key
                                rsv_ruimte_key: als meegegeven dan 'edit-mode'
                                res_deel_key: default keuze voor nieuwe reservering

    Context:            Indirect ajax in res_load_plan_obj.asp
                        of rechtstreeks in res_search_plan_obj_v2.asp
    Notes:              Zie res_load_cat.asp voor de catering en res_plan_room_v2.inc voor ruimtes

*/

FCLTHeader.Requires({ js: [rooturl+"/appl/res/res_plan.js", "date.js"] });

function empty_grid_line(row, deel, nr_days)
{
    var index;
    var tb_index;
    var html = '';

    for (tb_index = 0; tb_index < tijdbalken_kop.tijdbalk_arr().length; tb_index++)
    {
        if (nr_days < S('res_plantable_condensed_from')) // >= S('res_plantable_condensed_from') is compact view
        {
          for (index = tijdbalken_kop.tijdbalk_arr()[tb_index].start_column() + 1; index <= tijdbalken_kop.tijdbalk_arr()[tb_index].end_column(); index++)
          {
              // column 3 is empty
              if (index != 3)
              {
                  // first row is location
                  html += '<div class="rc hidden" data-row="' + row + '" style="grid-area: ' + row + '/' + index + ';"></div>';
              }
          }
          html += '<div class="hidden" style="grid-area: ' + row + '/' + index + ';"' + ' data-row="' + row + '"></div>';
        }
        else
        {
            html += '<div class="rc-compact hidden" data-row="' + row + '" style="grid-area: ' + row + '/' + Number(tijdbalken_kop.tijdbalk_arr()[tb_index].start_column() + 1) + '/' + row + '/' + tijdbalken_kop.tijdbalk_arr()[tb_index].end_column() + ';"></div>';
        }
    }
    return html;
}

function res_load_title_obj(ar, pparams)
{
    var rsv_deel_key = ar.rsv_deel_key
    var title_obj = {};
    res.res_set_dialect(ar.rsv_ruimte_key);

    // reserveringsperiode
    if (ar.res_van.getFullYear() == ar.res_tot.getFullYear() &&
        ar.res_van.getMonth() == ar.res_tot.getMonth() &&
        ar.res_van.getDate() == ar.res_tot.getDate()
       )
    {
        var speriod = toTimeString(ar.res_van) + "-" + toTimeString(ar.res_tot);
    }
    else
    {
        var speriod = toDateTimeString(ar.res_van)+ "-" + toDateTimeString(ar.res_tot);
    }

    // plaats reservering
    var rsv_ruimte_key = ar.rsv_ruimte_key;
    var sruimte_icon = "";
    var sruimte_srt = "";
    var sruimte_nr = "";
    if (ar.ruimte_opstel_key)
    {
        sql = "SELECT "+lcl.xsqla('rr.res_ruimte_nr', 'rr.res_ruimte_key')
            + "  FROM res_ruimte rr"
            + "     , res_ruimte_opstelling ro"
            + " WHERE res_ruimte_opstel_key = " + ar.ruimte_opstel_key
            + "   AND rr.res_ruimte_key = ro.res_ruimte_key"
        var oRs2 = Oracle.Execute(sql);
        sruimte_icon = I("fa-map-marker") + "&nbsp;";
        sruimte_nr = oRs2("res_ruimte_nr").Value;
        oRs2.Close();
    }
    else if (ar.alg_ruimte_key)
    {
        sql = "SELECT alg_plaatsaanduiding"
            + "     , alg_plaatsomschrijving"
            + "  FROM alg_v_onroerendgoed_gegevens"
            + " WHERE alg_ruimte_key = " + ar.alg_ruimte_key
        var oRs2 = Oracle.Execute(sql);
        sruimte_icon = I("fa-map-marker-alt") + "&nbsp;";
        sruimte_srt = oRs2("alg_plaatsomschrijving").Value;
        sruimte_nr = oRs2("alg_plaatsaanduiding").Value;
        oRs2.Close();
    }
    else // opdracht
    {
        sql = "SELECT COALESCE (o.mld_opdr_id, o.mld_melding_key||'/'||o.mld_opdr_bedrijfopdr_volgnr) mld_opdr_id"  // goedkoop zonder de prefix
            + "     , mto.mld_typeopdr_image"
            + "  FROM mld_opdr o"
            + "     , mld_typeopdr mto"
            + " WHERE o.mld_typeopdr_key = mto.mld_typeopdr_key"
            + "   AND o.mld_opdr_key = " + ar.mld_opdr_key
        var oRs2 = Oracle.Execute(sql);
        //opdrachticonregel is: this_opdr.mld_opdr.typeopdr_image ? this_opdr.mld_opdr.typeopdr_image : "fa-file-signature";
        sruimte_icon = (oRs2("mld_typeopdr_image").Value ? I(oRs2("mld_typeopdr_image").Value) : I("fa-file-signature")) + "&nbsp;";
        sruimte_nr = oRs2("mld_opdr_id").Value;
        oRs2.Close();
    }

    var sflag = (ar.res_flag > 0 ? ar.res_flag : "");
    var sreservering = L("lcl_reservation") + " " + ar.res_key + "/" + ar.res_volgnr;
    var sstatus = (ar.status_fo_key == 3 ? L("lcl_blokkade") : ar.activiteit);
    var scontact = ar.contact + (ar.contact != ar.host ? " (" + ar.host + ")" : "");
    var sbezoekers = (ar.ruimte_bezoekers > 0 ? ar.ruimte_bezoekers + " " + L("lcl_res_visitors") : "");


    var showTooltip = planbordTooltipShowing(ar.rsv_ruimte_key);
    switch (showTooltip)
    {
        case 0: // geen geheim!
                title_obj.info = [ { t: 1, tclass: "ric",          tval: sflag }
                                 , { t: 1, tclass: "rdk",          tval: sstatus }
                                 , { t: 2, tclass: "",             tval: sreservering }
                                 , { t: 3, tclass: "time-from-to", tval: speriod }
                                 , { t: 3, tclass: "rdt",          tval: ar.ruimte_omschrijving }
                                 , { t: 3, tclass: "rdn",          tval: scontact }
                                 , { t: 1, tclass: "rdp",          tval: sruimte_nr + " " + sruimte_srt, ticon: sruimte_icon }
                                 , { t: 2, tclass: "",             tval: L("lcl_room_n") + ": " + sruimte_nr }
                                 , { t: 2, tclass: "",             tval: sbezoekers }
                                 ];
                break;
        case 1: // details geheim voor FE!
                title_obj.info = [ { t: 1, tclass: "ric",          tval: sflag }
                                 , { t: 3, tclass: "time-from-to", tval: L("lcl_reservation") + " " + speriod }
                                 ];
                break;
        case 2: // geheim voor tooltip FE!
                title_obj.info = [ { t: 1, tclass: "ric",          tval: sflag }
                                 , { t: 1, tclass: "rdk",          tval: sstatus  }
                                 , { t: 2, tclass: "",             tval: sreservering }
                                 , { t: 3, tclass: "time-from-to", tval: speriod  }
                                 , { t: 3, tclass: "rdn",          tval: scontact }
                                 , { t: 1, tclass: "rdp",          tval: sruimte_nr + " " + sruimte_srt, ticon: sruimte_icon }
                                 , { t: 2, tclass: "",             tval: L("lcl_room_n") + ": " + sruimte_nr }
                                 , { t: 2, tclass: "",             tval: sbezoekers }
                                 ];
                break;
    }

    // Maak de inline en tooltip.
    var safe_obj_inline = "";
    var safe_obj_tooltip = "";
    if (title_obj && title_obj.info)
    {
        for (var i=0; i<title_obj.info.length; i++)
        {
            if (title_obj.info[i].tval != "")
            {
                if ((title_obj.info[i].t & 1) == 1)
                {
                    if (title_obj.info[i].tclass == "ric")
                    {
                        var flagnr = title_obj.info[i].tval;
                        safe_obj_inline += "<div class='ric'>"
                                         + "<span title='" + safe.htmlattr(L("lcl_res_flag" + flagnr)) +"'"
                                              + " class='respl resflag" + flagnr + " ress'>"
                                              + "<i class='fas fa-fw fa-square'></i>"
                                         + "</span>"
                                         + "</div>"
                    }
                    else
                    {
                        safe_obj_inline += "<span class='" + title_obj.info[i].tclass + "'>"
                                         + (title_obj.info[i].ticon ? title_obj.info[i].ticon: "")
                                         + safe.html(title_obj.info[i].tval)
                                         + "</span>"
                    }
                }

                if ((title_obj.info[i].t & 2) == 2)
                {
                    safe_obj_tooltip += (safe_obj_tooltip != "" ? "\n" : "") + safe.htmlattr(title_obj.info[i].tval);
                }
            }
        }
        safe_obj_inline = "<div class='rd'>" + safe_obj_inline + "</div>"
        safe_obj_tooltip = " title='" + safe_obj_tooltip + "'";
    }

    var hasTooltip = select_and_planbord_options(pparams, 2);
    var noInline   = select_and_planbord_options(pparams, 8);
    return { safe_inline:  (noInline ? "" : safe_obj_inline)
           , safe_tooltip: (hasTooltip ? safe_obj_tooltip : "")
           };
}

function res_load_title_bez(ar, pparams)
{
    var bez_key = ar.bez_key;
    var title_bez = {};
    var sql = "SELECT b.bez_afspraak_naam"
            + "     , b.bez_afspraak_bedrijf"
            + "     , p.prs_perslid_naam_friendly naam"
            + "     , COALESCE (a.bez_afspraak_telefoonnr, pp.prs_perslid_mobiel,pp.prs_perslid_telefoonnr) bez_afspraak_telefoonnr"
            + "     , a.bez_afspraak_key"
            + "     , a.res_rsv_ruimte_key"
            + "     , a.bez_afspraak_datum"
            + "     , a.bez_afspraak_eind"
            + "  FROM prs_v_perslid_fullnames_all p"
            + "     , bez_bezoekers b"
            + "     , prs_perslid pp"
            + "     , bez_afspraak a"
            + " WHERE p.prs_perslid_key = a.bez_afspraak_host_key"
            + "   AND pp.prs_perslid_key = a.bez_afspraak_host_key"
            + "   AND b.bez_afspraak_key = a.bez_afspraak_key"
            + "   AND b.bez_bezoekers_key = " + bez_key;

    var oRs = Oracle.Execute(sql);
    if (!oRs.Eof)
    {
        var speriod = toTimeString(ar.res_van) + "-" + toTimeString(ar.res_tot);
        var afspraak = oRs("bez_afspraak_naam").Value;
        var bedrijf = oRs("bez_afspraak_bedrijf").Value;
        var naam = oRs("naam").Value;
        var telefoon = oRs("bez_afspraak_telefoonnr").Value;

        var showTooltip = planbordTooltipShowing(ar.rsv_ruimte_key);
        switch (showTooltip)
        {
            case 0: // geen geheim!
                    title_bez.info = [ { tclass: "rdk", tval: afspraak + (bedrijf ? "(" + bedrijf + ")" : "") } ];
                    if (naam || telefoon)
                    {
                        title_bez.info.push( {tclass: "rdn", tval: (naam ? naam + " " : "") + (telefoon ? telefoon : "") } );
                    }
                    break;
            case 1: // details geheim voor FE!
            case 2: // geheim voor tooltip FE!
                    title_bez.info = [ { tclass: "rdk", tval: L("lcl_vis_appointment") }
                                     , { tclass: "time-from-to", tval: speriod }
                                     ];
                    break;
        }
    }
    oRs.Close();

    // Maak de inline en tooltip.
    var safe_bez_inline = "";
    var safe_bez_tooltip = "";
    if (title_bez && title_bez.info)
    {
        for (var i=0; i<title_bez.info.length; i++)
        {
            safe_bez_inline += "<span class='" + title_bez.info[i].tclass + "'>" + safe.html(title_bez.info[i].tval) + "</span>"
            safe_bez_tooltip += (safe_bez_tooltip != "" ? "\n" : "") + safe.htmlattr(title_bez.info[i].tval);
        }
        safe_bez_inline = "<div class='rd'>" + safe_bez_inline + "</div>"
        safe_bez_tooltip = " title='" + safe_bez_tooltip + "'";
    }
    var hasTooltip = select_and_planbord_options(pparams, 2);
    var noInline   = select_and_planbord_options(pparams, 8);
    return { safe_inline:  (noInline ? "" : safe_bez_inline)
           , safe_tooltip: (hasTooltip ? safe_bez_tooltip : "")
           };
}

function select_and_planbord_options(par, opt)
{   // Voor reserveren/bekijken objecten op planbord.
    var forSelectObj = par.forSelectobj || false;
    var res = (  (!forSelectObj && (S("res_planbord_options") & opt) == opt)
              || (forSelectObj && (S("res_forselect_options") & opt) == opt)
              );
    return res;
}


function make_plan_cell(params, theClass, h_start, h_end, tijdbalk, row, titleinfo, theClick, theMouse, theOther, prepost_time)
    {
        var div;
        var overleft="";
        var overright="";
        if (h_start<S("res_t1"))
        {
            h_start = S("res_t1")-S("res_h");
            if (dagen > 0)
                overleft = " continueleft";
            else
                overleft = " overflowleft";
        }

        if (h_end>S("res_t2"))
        {
            h_end = S("res_t2")+S("res_h");
            if (dagen < params.nr_days-1)
                overright = " continueright";
            else
                overright = " overflowright";
        }
        var px_start = Math.round((h_start-S("res_t1"))*params.hour_px + 1); // 1 px speling
        var px_end = Math.round((h_end-S("res_t1"))*params.hour_px);
        var startplanblok = h_start;
        var endplanblok = h_end;

        var px_width = px_end - px_start;

        var theStyleLeft = "";
        var theStyleRight = "";

        var preclean = 0;
        var postclean = 0;
        var gridcolumns = tijdbalk.gridtimecolumns(startplanblok, endplanblok);
        var unitLength = tijdbalk.unit_length();

        // Perhaps cleaning time, (TODO delen? alleen optie en definitief)
        if (prepost_time > 0) // && (ar[ci].fo_status == 1 || ar[ci].fo_status == 2))
        {
            theClass += " res_cleaning";
            // maximaal kwartier 'doorschieten' links/rechts
            preclean = Math.min(prepost_time, h_start - S("res_t1") + 0.25);
            postclean = Math.min(prepost_time, S("res_t2") - h_end + 0.25);

            if ( Math.round(hour_px * postclean - 1) > 0 )
            {
                theClass += " poc";
                // widen reservation with whole postclean time units
                gridcolumns.indexend += Math.ceil(postclean / unitLength);
                gridcolumns.indexdiff += Math.ceil(postclean / unitLength);
                theStyleRight = "border-right-width:"+Math.round(hour_px * postclean - 1)+"px;"
            }
            if ( preclean > 0 )
            {
                var precleanpx = Math.round(hour_px * preclean - 1);
                if (precleanpx > 0)
                    theClass += " prc";
                    // widen reservation with whole preclean time units
                    gridcolumns.indexstart -= Math.ceil(preclean / unitLength);
                    gridcolumns.indexdiff += Math.ceil(preclean / unitLength);
                    theStyleLeft = "border-left-width:"+precleanpx+"px;"
                if (px_start >= 0)
                {
                   px_start -= precleanpx; // border is 1px minder, maar wel altijd een kwartier
                   px_width += 1; // border is 1px minder
                }
            }

            if ( postclean > 0 && overright == "")
                theStyleRight = "border-right-width:"+Math.round(params.hour_px * postclean - 1)+"px;"
            if ( preclean > 0  && overleft == "")
            {
                var precleanpx = Math.round(params.hour_px * preclean - 1);
                theStyleLeft = "border-left-width:"+precleanpx+"px;"
                if (px_start >= 0)
                {
                   px_start -= precleanpx; // border is 1px minder, maar wel altijd een kwartier
                   px_width += 1; // border is 1px minder
                }
            }
        }

        var postcleanAttr = (postclean ? " poc=" + postclean : "");
        var rowAttr = ' data-row="' + row + '" data-disc="' + disc_key + '"';
        var precleanAttr = (preclean ? " prc=" + preclean : "");
        var styleAttr = ' style="' + tijdbalk.gridtimeposition(startplanblok, endplanblok, gridcolumns) + ' grid-row: ' + row + ' ; overflow:hidden;"';
        var div_attr = (theMouse||"")
                     + (theClick||"")
                     + (theOther||"")
                     + postcleanAttr
                     + rowAttr
                     + precleanAttr
                     + styleAttr
                     + titleinfo.safe_tooltip;
        var div_cont = titleinfo.safe_inline;

        if (overleft!=""&&overright!="")
        {   // Maak twee divjes, eentje links en eentje rechts.
            // HTML kan maar één background image tegelijk aan
            div = "<div class='"  + theClass+overleft  + " hidden'" + div_attr + ">" + div_cont + "&nbsp;</div>";
            div += "<div class='" + theClass+overright + " hidden'" + div_attr + ">" + div_cont + "&nbsp;</div>";
        }
        else
        {
            div = "<div class='" + theClass+overleft+overright + " hidden'" + div_attr + ">" + div_cont + "&nbsp;</div>";
        }
        return { div: div, overleft: overleft, overright: overright };
    }


function make_plan_obj(disc_key, res_van, res_tot, params)
{
    if (typeof width_px == "undefined")
    {
      width_px = getQParamInt("width_px", 1024);
    }
    var hour_px = res.hour_px(width_px - 400, nr_days);

    params = params || {};
    params.hour_px = params.hour_px || 48;
    params.rsv_ruimte_key = params.rsv_ruimte_key || -1;
    var res_h_px = params.hour_px * S("res_h");

    if (params.srtact)
      lcl.set_dialect(params.srtact, "RES_SRTACTIVITEIT_KEY");

    var authparams = user.checkAutorisation(autfunction, true, disc_key);
    var canRead = authparams && authparams.PRSreadlevel < 9 && authparams.ALGreadlevel < 9;
    var canWrite = authparams && authparams.PRSwritelevel < 9 && authparams.ALGwritelevel < 9; // Ondersteun (FE) gebruikers met *alleen* FO-leesrechten: kijken planbord

    if (params.rsv_ruimte_key>0) // single-reservering mode
    {
      sql = "SELECT ru.res_ruimte_begintijd"
          + ",      ru.res_ruimte_eindtijd"
          + ",      rr.alg_ruimte_key"
          + ",      ro.res_ruimte_key"
          + "  FROM res_v_aanwezigruimte ru"
          + ",      res_rsv_ruimte rr"
          + ",      res_ruimte_opstelling ro"
          + " WHERE ru.res_ruimte_key = ro.res_ruimte_key"
          + "   AND ro.res_ruimte_opstel_key = rr.res_ruimte_opstel_key"
          + "   AND rr.res_rsv_ruimte_key = " + params.rsv_ruimte_key;
      oRs = Oracle.Execute(sql);
      if (!oRs.eof)
      {
        var alg_ruimte_key = oRs("alg_ruimte_key").value; // de eerste
        var res_ruimte_key = oRs("res_ruimte_key").value;
        // Als de ruimte maar beperkt open is gaan we rekenen met een krappere S("res_t1")/res_t2
        var res_ruimte_begintijd = oRs("res_ruimte_begintijd").Value||S("res_t1");
        var res_ruimte_eindtijd = oRs("res_ruimte_eindtijd").Value||S("res_t2");
        if (res_ruimte_begintijd > res_ruimte_eindtijd) res_ruimte_begintijd = res_ruimte_eindtijd;
        if (res_ruimte_begintijd > S("res_t1")) settings.overrule_setting("res_t1", res_ruimte_begintijd);
        if (res_ruimte_eindtijd > S("res_t2")) settings.overrule_setting("res_t2", res_ruimte_eindtijd);
      }
      else // CV reserverering, altijd S("res_t1")-res_t2
      {
          res_ruimte_key = -1;
          sql = "SELECT alg_ruimte_key,"
              + "       mld_opdr_key"
              + "  FROM res_rsv_ruimte"
              + " WHERE res_rsv_ruimte_key = " + params.rsv_ruimte_key;
          var oRs2 = Oracle.Execute(sql);
          var alg_ruimte_key = oRs2("alg_ruimte_key").value;
          var mld_opdr_key = oRs2("mld_opdr_key").value;
          oRs2.Close();
      }
      oRs.Close();
    }

  var sql;

  var dparams = { res_van: res_van,
                  res_tot: res_tot,
                  disc_key: disc_key
                }
  var existing_res = res.plan_deel_bezet_info(dparams);

  var nr_days = Math.round(1+(res_tot.midnight() - res_van.midnight())/24/60/60/1000);
  params.nr_days = nr_days;

%>
  <div id='timetip'></div>
  <div id="table_dis<%=disc_key%>"
         class="compressed tab_obj_sched planbord planbord<%=params.hour_px%> <%=nr_days>1?" multiday":""%>"
<% if (params.rsv_ruimte_key<0) { // Click om een nieuwe deelreservering aan te maken
      var dt = res_van.getTime();
    %>
<% } %>
  >
  <div class="grid" data-disc="<%=disc_key%>" data-writable="<%=canWrite ? "true" : "false"%>">
    <div class="header deel">
        <div id="<%=disc_key%>-header" cellspacing="0" class="planbordgrid deel compressed planbord multiday">
    <%
        if ("suppressHeader" in params == false || params.suppressHeader == false) {
            tijdbalken_kop = new Tijdbalken(res_van, nr_days, S("res_t1"), S("res_t2"), params.fnStep);
            Response.Write(tijdbalken_kop.render());
        }
    %>
      </div>
    </div>
    <div class="body">
        <div id="<%=disc_key%>-body" cellspacing="0" class="planbordgrid deel compressed planbord multiday">
    <%

  // Nogal suf concept zo: er is een deel (d) en een perslid (p) mogelijkheid
  // dus wordt er hier nogal situationeel geknutseld. Eerst maar eens laten werken
  // wordt alleen hier (en in het oude unsupported planbord) gebruikt) dus toe maar even.
  // Is nog wel erg traaag.
  var select_fields = " r.res_deel_key"
                    + ", " + lcl.xsqla('r.res_deel_opmerking', 'r.res_deel_key')
                    + ", " + lcl.xsql('r.res_deel_omschrijving', 'r.res_deel_key')
                      + " || CASE"
                      + " WHEN (r.res_deel_vervaldatum IS NULL OR r.res_deel_vervaldatum > SYSDATE)"
                      + " THEN ''"
                      + " ELSE " + safe.quoted_sql(L("lcl_inactive_data_suffix"))
                      + " END res_deel_omschrijving"
                    + ", r.res_deel_prijs"
                    + ", r.res_deel_image"
                    + ", " + lcl.xsqla('r.res_deel_eenheid', 'r.res_deel_key')
                    + ", res_disc_params_preposttime"
                    + ", 0 isbulk"
                    + ", 0 total"
                    + ", 0 selected";

  var select_fields_p = select_fields + ", to_number(null) ins_alg_ruimte_key_org"
                    + ", to_number(null) ins_discipline_key"
                    + ", TO_CHAR(NULL) ins_deel_state"
                    + ", to_number(null) ins_deel_key"
                    + ", res_prs_perslid_key prs_perslid_key";

  var select_fields_d = select_fields + ", d.ins_alg_ruimte_key_org"
                    + ", d.ins_discipline_key"
                    + ", d.ins_deel_state"
                    + ", d.ins_deel_key"
                    + ", to_number(NULL) prs_perslid_key";

  var select_bulkfields = " distinct cnt.res_deel_key"
                        + ", res_deel_opmerking"
                        + ", " + lcl.xsql('r.res_deel_omschrijving', 'cnt.res_deel_key') + " || ' (' || cnt.total || ')'" + " res_deel_omschrijving"
                        + ", r.res_deel_prijs"
                        + ", r.res_deel_image"
                        + ", " + lcl.xsqla('r.res_deel_eenheid', 'cnt.res_deel_key')
                        + ", res_disc_params_preposttime"
                        + ", 1 isbulk"
                        + ", cnt.total"
                        + ", sel.selected"
                        + ", d.ins_alg_ruimte_key_org"
                        + ", d.ins_discipline_key"
                        + ", d.ins_deel_state"
                        + ", cnt.ins_deel_key"
                        + ", to_number(NULL) prs_perslid_key";

    var group_by = " GROUP BY "
                 + " r.res_deel_key"
                 + ", res_prs_perslid_key"
                 + ", r.res_deel_opmerking"
                 + ", r.res_deel_omschrijving"
                 + ", r.res_deel_vervaldatum"
                 + ", r.res_deel_prijs"
                 + ", r.res_deel_image"
                 + ", r.res_deel_eenheid"
                 + ", res_disc_params_preposttime"
                 + ", d.ins_alg_ruimte_key_org"
                 + ", d.ins_discipline_key"
                 + ", d.ins_deel_state"
                 + ", d.ins_deel_key";

    var bulk_group_by = " GROUP BY cnt.res_deel_key"
                        + ", res_prs_perslid_key"
                        + ", r.res_deel_opmerking"
                        + ", r.res_deel_omschrijving"
                        + ", r.res_deel_vervaldatum"
                        + ", r.res_deel_prijs"
                        + ", r.res_deel_image"
                        + ", r.res_deel_eenheid"
                        + ", res_disc_params_preposttime"
                        + ", d.ins_alg_ruimte_key_org"
                        + ", d.ins_discipline_key"
                        + ", d.ins_deel_state"
                        + ", cnt.ins_deel_key"
                        + ", cnt.total"
                        + ", sel.selected";


  if (!params.isload)
  {
    group_by += " ORDER BY 3 "; // r.res_deel_omschrijving: Don't use column alias with UNION ...
  }
  else
  {
    bulk_group_by += " ORDER BY 3 ";
  }

  // Iterate through all reservable objects (vertically) and show schedule for them (horizontally)
  var maxrec = (params.loadmore ? S("qp_maxgridrows2") : S("qp_maxgridrows")) + 1;
  var sql1 = get_res_deel_sql(
                    { rsv_ruimte_key: params.rsv_ruimte_key,
                      alg_ruimte_key: alg_ruimte_key,
                      res_ruimte_key: res_ruimte_key,
                      mld_opdr_key: params.mld_opdr_key,
                      select_fields_p : select_fields_p,
                      select_fields_d : select_fields_d,
                      select_bulkfields : select_bulkfields,
                      reg_key : params.reg_key,
                      dist_key : params.dist_key,
                      loc_key        : params.loc_key,
                      loc_key_arr    : params.loc_key_arr,
                      geb_key        : params.geb_key,
                      geb_key_arr    : params.geb_key_arr,
                      ver_key : params.ver_key,
                      ver_key_arr    : params.ver_key_arr,
                      rui_key : params.rui_key,
                      act_key : params.act_key,
                      sdisc : disc_key,
                      group_by: group_by,
                      bulk_group_by: bulk_group_by,
                      autfunction : autfunction,
                      res_tot: res_tot,
                      maxrec: maxrec,
                      withbulk: !!params.isload,
                      res_van: res_van
                     });

  oRs = Oracle.Execute(sql1);
  var cnt = 0;
  var any_nofit = false;
  var row = 1;
  // no description means description is outside of grid (load_plan)
  if (params.ins_discipline_omschrijving)
  {
    row = 2;
  }
  while (!oRs.eof && (row -1) < maxrec)
  { // Doorloop reserveerbare delen binnen filter
    res_deel_key = oRs("res_deel_key").value;
    res_deel_omschrijving = oRs("res_deel_omschrijving").value;
    res_deel_prijs = oRs("res_deel_prijs").Value;
    res_deel_eenheid = oRs("res_deel_eenheid").Value;
    res_deel_image = oRs("res_deel_image").Value;
    ins_deel_state = oRs("ins_deel_state").Value;  // POC. ins_deel_statedate doet denk ik ook mee

    var res_deel_opm2 = oRs("res_deel_opmerking").value;
    var prepost_time = oRs("res_disc_params_preposttime").Value||0;
    var ins_deel_key = oRs("ins_deel_key").value;
    var prs_perslid_key = oRs("prs_perslid_key").value;
    Response.Write(empty_grid_line(row, { res_deel_key: res_deel_key, disc_key: disc_key }, nr_days));

    var showLendOut = false;
    if (oRs("ins_alg_ruimte_key_org").value != null)
    {
        var authparamsINSFOF = user.checkAutorisation("WEB_INSFOF", true, + oRs("ins_discipline_key").Value); // cache't wel
        if (authparamsINSFOF)
            showLendOut = true;
    }

    if (res_deel_eenheid == null) res_deel_eenheid='';
    else res_deel_eenheid='/'+res_deel_eenheid;

    if( res_deel_prijs && res_deel_prijs != 0)
    {
      prijs_text = S("currency_pref") + safe.curr(res_deel_prijs)+S("currency_suff")+res_deel_eenheid;
    }
    else
    {
      prijs_text = '';
      res_deel_prijs = 0.0;
    }

    var ar = existing_res[prs_perslid_key?prs_perslid_key:ins_deel_key]; // Bestaande reserveringen op dit deel

    var ro = " readonly ", st = false;

    // bulk item handling
    if (oRs("isbulk").Value == 1 && oRs("total").Value > 0)
    {
      is_selected = (oRs("selected").Value > 0);
      is_nofit = false;
      // no competing reservation as long as there are bulk objects available
      arSelf = [];
      // preserve [this] reservation in ar, the rest is removed from the array
      var arIndex;
      for (arIndex in ar)
      {
          if (ar[arIndex].rsv_ruimte_key == params.rsv_ruimte_key)
          {
              // not dirty as long as there are bulk items available
              ar[arIndex].dirtlevel = 0;
              arSelf.push(ar[arIndex]);
              break;
          }
      }

      ar = (params.isload ? arSelf : ar);
    }
    // non-bulk itam handling
    else if (params.rsv_ruimte_key>0) {
      // check whether the current resource is reserved for the current reservation
      var is_selected = false;
      var is_nofit = false; // zouden we hier passen?

      if (res_deel_key==params.res_deel_key) // default keuze
      {
        is_selected = true;
        ro = "";
        st = false;
      };
      for (ci=0; ar != null && ci<ar.length; ci++)
      {
        if (ar[ci].rsv_ruimte_key == params.rsv_ruimte_key)
        { // we zijn het zelf
          is_selected = true;
          // Indien het hetzelfde object (ins_deel_key) betreft maar niet hetzelfde reserverbaar deel (res_deel_key), dan disabled weergeven
          ro = (ar[ci].res_status==6 || res_deel_key != ar[ci].res_deel_key? " disabled " : "");
          st = (ar[ci].res_status==6 || res_deel_key != ar[ci].res_deel_key);
        }
        else
        {
            if (res_van.getTime() - prepost_time*60*60*1000 < ar[ci].res_tot.getTime()
             && res_tot.getTime() + prepost_time*60*60*1000 > ar[ci].res_van.getTime())
                is_nofit = true; // Overlap!
        }
      }
      any_nofit |= is_nofit;
    }
%>
    <div class="labelgrid hidden<%=is_selected?' selected':''%><%=is_nofit?' res_nofit':''%>" id="<%=res_deel_key%>"
        data-disc="<%=disc_key%>" data-row="<%=row%>" style="grid-column: 1; grid-row: <%=row%>"
<%
    if (select_and_planbord_options(params, 4) && nr_days < S("res_plantable_condensed_from") && res_deel_opm2) //Anders is het #remark2_xx veld er niet
    { %>
        OnMouseOver="showOpmerking('#remark2_<%=res_deel_key%>', event, true);"
        OnMouseOut="$('#remark2_<%=res_deel_key%>').hide();"
<%  } %>
    >
        <% if (is_selected && res_deel_key!=params.res_deel_key )  // Als res_deel_key==params.res_deel_key komen we uit het
                                                                   // planbord en hebben we hem nog niet echt
        { %>
            <input name='has_<%=res_deel_key%>' type='hidden'>
        <% } %>
<% if (params.rsv_ruimte_key>0) { %>
        <input id='chk_<%=res_deel_key%>' name='chk_<%=res_deel_key%>'
               type='checkbox' <%=is_selected?'checked':''%> <%=ro%>
<%       if (!st) { %>
            onClick="res_deel_grid_click('<%=res_deel_key%>')"
<%        } %>>
<% }
        txt = res_deel_omschrijving + (params.rsv_ruimte_key>0 ? '':(prijs_text?' ('+prijs_text+')':''))
        var safe_state = "";
        var safe_txt = safe.html(txt);
//- zeker/daadwerkelijk bezet (&1)
//- zeker/daadwerkelijk vrij (&0)
//- functioneel bezet (bv &3 (met &2 = onzeker)), optioneel bv iemand is even weg maar nog binnen de toleranties (handdoekje leggen)
//- geblokkeerd (bv &5 bv moet schoongemaakt worden)
//- error (&128?)

        var stateicon ="";
        var statecolorclass ="";
        if (ins_deel_state&128)
        {
            stateicon = "fa-exclamation-triangle";
            statecolorclass = "sens-fatal";
        }
        else if (ins_deel_state&1)
        {
            stateicon = "fa-do-not-enter";
            if (ins_deel_state&4)
            {
                statecolorclass = "sens-blocked";
                stateicon = "fa-times-circle";
            }
            else if (ins_deel_state&2)
            {
                statecolorclass = "sens-uncertain";
                stateicon = "fa-question-circle";
            }
            else
                statecolorclass = "sens-occupied";

        }
        else if (ins_deel_state == 0)
        {
            stateicon = "fa-circle";
            statecolorclass = "sens-free";
        }

        if (ins_deel_state || showLendOut) // POC
            safe_state = "<div "+(statecolorclass ? "class='statusgrid sens-status "+statecolorclass+"' " :"")
            + "title='"+(ins_deel_state ? (L("lcl_deel_state")+" "+safe.htmlattr(ins_deel_state)) : L("lcl_ins_islent_res"))+"'>"
            + I(stateicon, {fastyle: "fas"})
            + (showLendOut ? I("fa-thumbtack respl", {fastyle: "fal"}) : "")
            + "</div>"; // de absolute voorkomt invloed op layout

        var safe_oms = "";
        var imageClass = "";
        var imageStyle = "";
        var res_deel_image = "";
        if (nr_days < S('res_plantable_condensed_from')) // >= S('res_plantable_condensed_from') is compact view
        {
          var this_photoinfo = res.photoinfo(res_deel_key, ins_deel_key, prs_perslid_key);
          res_deel_image = (this_photoinfo.isDefault ? "" : safe.htmlattr(this_photoinfo.photopaththumb));

          if (res_deel_image && (!select_and_planbord_options(params, 1) || params.isload))
          {
              imageClass = " rrphoto";
              imageStyle = " style='background-image: url(\"" + res_deel_image + "\");'";
          }
          if (res_deel_opm2)
              safe_oms += safe.html(res_deel_opm2);
        }
        %>
        <label title='<%=safe.htmlattr(txt)%>' for='chk_<%=res_deel_key%>'><%=safe_txt%></label>
        <div class="rrdet<%=imageClass%>"<%=imageStyle%> style="z-index:2">
<%      if (safe_oms)
        {
           if (select_and_planbord_options(params, 4))
           { %>
                <div class="res_remark" style='text-align:center' id="remark2_<%=res_deel_key%>">
                    <%=safe_oms%>
                </div>
        <% } else { %>
            <div class="rrdesc-wrapper">
                <div class="rrdesc">
                    <%=safe_oms%>
                </div>
            </div>
            <% } %>
<%      } %>
        </div>
    </div>
    <div class="icongrid hidden" style="grid-column: 2; grid-row: <%=row%>" data-disc="<%=disc_key%>" data-row="<%=row%>">
    <%=safe_state%>
    </div>
<%
    if (oRs("isbulk").value == 1 && params.isload)
    {
%>
    <div class="bulkamountwrap" style="grid-area: <%=row%>/2/auto/4; justify-self: end;" data-disc="<%=disc_key%>" data-row="<%=row%>">
        <input class="bulkamount number<%=(oRs("selected").value > 0 ? ' required' : '')%>" type="number" name="amt_<%=res_deel_key%>" min="0" max="<%=oRs("total").value%>" value="<%=oRs("selected").value%>" onchange="res_deel_grid_change('<%=res_deel_key%>')">
    </div>
<%
    }
%>
<%
    divver = { overleft: "", overright: "" };

    var vanmidnight = res_van.midnight().getTime(); // Eén keer uitrekenen
    var totmidnight = res_tot.midnight().getTime();
    var rsv_key = 0;
    var res_flag = 0;
    var tijdbalk;

    for (dagen=0; dagen<nr_days; dagen++)
    {
      tijdbalk = tijdbalken_kop.tijdbalk_arr()[dagen];
        // Maak een dummy res_nieuw aan die we eenvoudig aan kunnen zetten als we in selectie-mode zitten
        //  (niet voor planbord)
        if (!params.planbord && !is_selected || res_deel_key==params.res_deel_key)
        {
            var h_start = (res_van - vanmidnight) /1000/60/60 - 24*dagen;
            var h_end =   (res_tot - totmidnight) /1000/60/60 + 24*(nr_days-1-dagen);
            var safe_titleinfo = {safe_inline: "", safe_tooltip: ""};
            var new_divver = make_plan_cell(params, "gepland res_nieuw", h_start, h_end, tijdbalk, row, safe_titleinfo);
            Response.Write("\n"+new_divver.div);
        }

        for (ci=0; ar && ci<ar.length; ci++)
        {
            var h_start = (ar[ci].res_van - vanmidnight) /1000/60/60 - 24*dagen;
            var h_end   = (ar[ci].res_tot - totmidnight) /1000/60/60 + 24*(nr_days-1-dagen);
            if (h_start>24 || h_end < 0)
                continue;

            var not_available =     (urole == "fe"                                                  // FE mag niet op een reservering klikken, tenzij;
                                && !user.isCollega(ar[ci].contact_key)                              // Ik ben de contactpersoon vd reservering
                                && !(ar[ci].mld_opdr_key > 0 && user.isCollega(prs_perslid_key)));  // Ik ben de gereserveerde persoon

            if (res_deel_key != ar[ci].res_deel_key || ar[ci].dirtlevel > 0 || not_available)
                statClass = "res_nietvrij";
            else
            {
                statClass = { 1 : "res_optie",
                              2 : "res_definitief",
                              3 : "res_blok",
                              4 : "res_vervallen"}[ar[ci].status_fo_key ];
                statClass = (ar[ci].res_status == 5 ? "res_afgemeld" : statClass);
            }

            if (ar[ci].rsv_ruimte_key == params.rsv_ruimte_key && res_deel_key == ar[ci].res_deel_key)
                statClass += " res_current";

            if (ar[ci].dirtlevel & (res.dirtlevel.deel.notavailable | res.dirtlevel.deel.notallowed))
                statClass += " res_fatal";

            var theClass = statClass + " gepland";

            if (ar[ci].dirtlevel & res.dirtlevel.ruimte.notavailable)
                theClass += " res_fatal";

            var rsv_ruimte_key = ar[ci].rsv_ruimte_key;
            var rsv_deel_key = ar[ci].rsv_deel_key;
            var alg_ruimte_key = isNaN(ar[ci].alg_ruimte_key) ? -1 :ar[ci].alg_ruimte_key;
            var bez_key = ar[ci].bez_key;

            res_flag = 0;
            if (rsv_key != rsv_ruimte_key)
            {
              res_flag = ar[ci].res_flag;
              rsv_key  = rsv_ruimte_key;
            }

            var theClick = "";
            var theMouse="";
            var titleinfo = {};

            if (nr_days < S('res_plantable_condensed_from')) // >= S('res_plantable_condensed_from') is compact view
            {
                if (bez_key > 0)
                {
                     safe_titleinfo = res_load_title_bez(ar[ci], params);
                }
                else
                {
                     safe_titleinfo = res_load_title_obj(ar[ci], params);
                }
            }
            else
            {
                safe_titleinfo = { safe_inline: "", safe_tooltip: ""};
            }

            if (canRead && !not_available && bez_key == -1 && params.rsv_ruimte_key < 0)
            {
                theClick = ' onClick="rsv_click(this,\''+urole+'\');"'
                theClass += " click";
            }

            divver = make_plan_cell(params, theClass, h_start, h_end, tijdbalk, row, safe_titleinfo, theClick, theMouse,
                                    " rsv_key='" + rsv_ruimte_key +"' rsv_deel_key='" + rsv_deel_key + "'", prepost_time);
            Response.Write("\n"+divver.div);
        }
    } // dagen
    row++;
    oRs.MoveNext();
  } //end while
  if (params.ins_discipline_omschrijving)
  {
%>
    <div class="insdiscgrid collapsed" data-disc="<%=disc_key%>" data-row="1" style="grid-column: 1 / <%=tijdbalken_kop.end_column()+1%>;grid-row: 1;">
        <%=safe.html(params.ins_discipline_omschrijving)%><span class="badge"><%=row - 2%></span>&nbsp<span class="maxgridrows"><%=row > S("qp_maxgridrows") ? L("lcl_qp_maxrows2").format(S("qp_maxgridrows")) : ""%></span>
    </div>
    <div data-row="<%=row%>" style="grid-column: <%=tijdbalken_kop.end_column()+1%>;grid-row: 1;"></div>
<%
  }
  oRs.close();
%>
  </div>
</div>
  <div class="footer"></div>
</div>
</div>
  <script>
<%
  if (any_nofit)
  {
%>
      function toggleNoFit<%=disc_key%>(visible)
      {
          return $("div.grid > div.body div.labelgrid[data-disc=<%=disc_key%>].res_nofit").filter(":" + (visible ? "visible":"hidden")).each(function() {
              var $this = $(this);
              var show  = $this.is(":visible") == false;
              var rowNr = $this.data("row");
              $this.closest(".grid").find("div[data-row=" + rowNr + "]").toggle(show);
          });
      }
      toggleNoFit<%=disc_key%>(true);
<%
  }
  if (params.isload)
  {
    if (row > maxrec)
    {   // Zet bij overschrijden van het maximaal aantal regels dat getoond wordt een waarschuwing hiervan
        if (row >= S("qp_maxgridrows2"))
        {
            var maxrows_msg = "<a class='resplanbordlimited'>" + L("lcl_qp_maxrows2a").format(maxrec-1) + "</a>";
            var maxrow_click = "";
        }
        else
        {
            var maxrows_msg = "<a class='resplanbordlimited'>" + L("lcl_qp_maxrows1a").format(maxrec-1) + "</a>";
            var maxrow_click = "ItemChoosed_obj(this, 'div_dis" + disc_key + "', " + disc_key + ", " + params.hour_px + ", '&more=1')";
        }
%>
        var $maxrows_msgTable = $("#table_dis<%=disc_key%>");

        var $maxrows_msgHead<%-disc_key%> = $("<div id='<%=disc_key%>-maxrows' onclick=\"<%=maxrow_click%>\"><%=maxrows_msg%></div>");
        $maxrows_msgTable.before($maxrows_msgHead<%-disc_key%>);

        var $maxrows_msgFoot<%-disc_key%> = $("<div id='<%=disc_key%>-maxrows' onclick=\"<%=maxrow_click%>\"><%=maxrows_msg%></div>");
        $maxrows_msgTable.find(".grid .footer").html($maxrows_msgFoot<%-disc_key%>);
<%
    }
%>
    var $autofilterAfter = $("div.grid[data-disc=<%=disc_key%>] > div.header div.planbordgrid");
    var $autofilter<%=disc_key%> = $("<input id='autofilter-<%=disc_key%>' type='text' placeholder='" + L("lcl_autofilter") + "'" + (<%=params.hidefilter == 1? 1 : 0%> == 0? "" : " style='display: none;'") + ">");
    $autofilterAfter.append($autofilter<%=disc_key%>);
    function doFilter<%=disc_key%>(event)
    {
        var valThis = $autofilter<%=disc_key%>.val().toLowerCase();
        if (valThis != window.lastFilter<%=disc_key%>) {
            delayed(100, _doFilter<%=disc_key%>);
        }
        function _doFilter<%=disc_key%>() {
            function textFromCollection(collection)
            {
                var _text = "";
                collection.each(function () { _text += $(this).text().trim(); });
                return _text.toLowerCase();
            }
            var $more = $("div.resplanbordlimited > a");
            var $gridrows;
            if ($more.length > 0 && $more.first().is(":visible"))
            {
                $gridrows = $("div.grid[data-disc=<%=disc_key%>] > div.body div.labelgrid").not(".res_nofit");
            }
            else
            {
                $gridrows = $("div.grid[data-disc=<%=disc_key%>] > div.body div.labelgrid");
            }
            var valThis = $autofilter<%=disc_key%>.val().toLowerCase();
            $gridrows.each(function() {
                var $this = $(this);
                var found = (valThis.trim().length == 0 || textFromCollection($("div[data-disc=" + $this.attr("data-disc") + "][data-row=" + $this.attr("data-row") + "]").not(".rc")).indexOf(valThis) > -1);
                $("div[data-row=" + $this.attr("data-row") + "][data-disc=" + $this.attr("data-disc") + "]").toggle(found);
            });
            FcltMgr.resized();
            window.lastFilter<%=disc_key%> = valThis;
        }
    }
    $autofilter<%=disc_key%>.click(function (e) { e.stopPropagation() })
                    .keyup(function (e) {
                        if (e.which == 27) {
                            $autofilter<%=disc_key%>.val("");
                        }
                        doFilter<%=disc_key%>();
                    });

    var tijdbalken = [<%=tijdbalken_kop.tijdbalk_arr()[0].render_object()%>];

    $("div.grid[data-disc=<%=disc_key%>]").css("grid-template-rows", "60px 1fr");
    $("div.grid[data-disc=<%=disc_key%>] .hidden").removeClass("hidden");
    if (typeof toggleNoFit<%=disc_key%> != "undefined")
    {
        toggleNoFit<%=disc_key%>(true);
    }
    if (window.frameElement && window.frameElement.parentElement && window.frameElement.parentElement.id == "result") /* Niet in het catering overzicht bijv. */
        root.style.overflow = 'hidden';

    setTimeout(function() { $(window).on("resize", resize_borders_margins).trigger("resize"); }, 500);
    function resize_borders_margins()
    {
        set_borders_margins(tijdbalken[0]);
    }
<%
  }
%>
  </script>
<%
    if (any_nofit)
    {
        %><div class="resplanbordlimited" onclick="$('#table_dis<%=disc_key%>').toggleClass('compressed');$(this).toggle();$(this).next().toggle();toggleNoFit<%=disc_key%>(false);FcltMgr.resized(window);">
           <a><%=L("lcl_res_show_full_obj_catalogus")%></a></div>
          <div class="resplanbordlimited" style='display:none' onclick="$('#table_dis<%=disc_key%>').toggleClass('compressed');$(this).toggle();$(this).prev().toggle();toggleNoFit<%=disc_key%>(true);FcltMgr.resized(window);">
           <a><%=L("lcl_res_show_half_obj_catalogus")%></a></div><%
    }
}
%>