<% /*
     $Revision$
     $Id$

    File:               res_plan_room.inc
    Description:        Het echte genereren van het planbordje voor ruimtes
                        via functie make_plan_room() die een kale HTML-table oplevert

    Context:            Indirect ajax in read_load_plan_room.asp
                        of rechtstreeks in res_search_plan_room.asp
    Notes:              Zie res_load_cat.asp voor de catering en res_plan_obj.inc voor ruimtes

*/

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

// params: res_van, res_tot (en vis)
// Wijzigt(!) plan_rooms_info en voegt overal een will_fit aan toe
function set_will_fit(plan_rooms_info, plan_bezet_info, params)
{
  var any_nofit = false;
  for (var i_room in plan_rooms_info)
  {
    var is_nofit = false;
    var room = plan_rooms_info[i_room];
    var ar = plan_bezet_info[room.res_ruimte_key];

    var df = params.res_van.getHours() + params.res_van.getMinutes()/60;
    var dt = params.res_tot.getHours() + params.res_tot.getMinutes()/60;
    if (df < room.begintijd || dt > room.eindtijd)
    {
        is_nofit = true; // Buiten openingstijden
    }
    else if (room.begintijdblok && room.eindtijdblok && df < room.eindtijdblok && dt > room.begintijdblok)
    {
        is_nofit = true; // Tijdens lunch
    }

    if (!is_nofit)
    {
        for (var 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;
          }
          else
          {
              if (params.res_van.getTime() - room.prepost_time*60*60*1000 < ar[ci].res_tot.getTime()
               && params.res_tot.getTime() + room.prepost_time*60*60*1000 > ar[ci].res_van.getTime())
                  is_nofit = true; // Overlap!
          }
        }
    }

    room.will_fit = !is_nofit;
    room.existing_res = ar;
    any_nofit |= is_nofit;
  }
  return any_nofit;
}

// De echte planningblokjes van een regel
function make_plan_regel(room, ar, params, nr_days, hour_px)
{
  var vanmidnight = params.res_van.midnight().getTime(); // Eén keer uitrekenen
  var vanofs = params.res_van.getTimezoneOffset();
  var html = []; // het resultaat

  var begintijd_mask = null;
  var eindtijd_mask = null;
  if (room.begintijd > S("res_t1"))
    begintijd_mask = "<div class='begintijd' style='width:"+((room.begintijd-S("res_t1"))*hour_px)+"px'>&nbsp;</div>";
  if (room.eindtijd < S("res_t2"))
  {
    var start_px = (room.eindtijd - S("res_t1")) * hour_px+1;
    var width_px =  (S("res_t2") - room.eindtijd) * hour_px;
    eindtijd_mask = "<div class='eindtijd' style='left:"+start_px+"px;width:"+width_px+"px'>&nbsp;</div>";
  }
  var is_nofit = false; // zouden we hier passen?

  for (dagen = 0; dagen < nr_days; dagen++)
  {
      html.push('<td class="plantd reserv"><div class="tddiv">' + (begintijd_mask?begintijd_mask:"") + (eindtijd_mask?eindtijd_mask:""));
      if (room.begintijdblok && room.eindtijdblok)
      {
          var px_start = (room.begintijdblok - S("res_t1")) * hour_px;
          var px_end =   (room.eindtijdblok - S("res_t1"))  * hour_px;
          var px_width = px_end - px_start;
          var div = "<div class='gepland res_blok res_lunchblok' style='left:"+px_start+"px;width:"+px_width+"px;'>&nbsp;</div>";
          html.push("\n" + div);
      }

      for (ci = 0; ar && ci < ar.length; ci++)
      {
        var h_start = (ar[ci].res_van.getTime() - vanmidnight) /1000/60/60 - 24*dagen;
        var h_end   = (ar[ci].res_tot.getTime() - vanmidnight) /1000/60/60 - 24*dagen;
        // Correctie voor zomer-/wintertijd
        var arvanofs = ar[ci].res_van.getTimezoneOffset();
        var artotofs = ar[ci].res_tot.getTimezoneOffset();
        if (vanofs > arvanofs)
            h_start ++;
        else if (vanofs < arvanofs)
            h_start --;
        if (vanofs > artotofs)
            h_end ++;
        else if (vanofs < artotofs)
            h_end --;

        if (h_start>24 || h_end < 0)
            continue;

        not_available = false;

        // if we filter on host key we do not want to show the other reservations
        // where our host is not the host.

        var contact_key = ar[ci].contact_key || ar[ci].host_key;
        if ((params.host_key != -1  && params.host_key != ar[ci].host_key) ||
            (params.contact_key != -1  && params.contact_key != contact_key) ||
            (params.urole=='fe' && !user.isCollega(contact_key)))
        {
          not_available = true; // FE en niet een eigen reservering
        }

        if (ar[ci].extern) // uitzondering
            not_available = false;

        if ((params.host_key > 0 && not_available) ||
            (params.contact_key > 0 && not_available) ||
             ar[ci].na_koppel == 1)
          statClass = "res_nietvrij";
        else
        {
          var eigen_res = ((contact_key == user_key) || user.isCollega(contact_key));
          statClass = { 1 : (eigen_res ? "res_optie_eigen" : "res_optie"),
                        2 : (eigen_res ? "res_definitief_eigen" : "res_definitief"),
                        3 : "res_blok",
                        4 : "res_vervallen"}[ar[ci].fo_status];
        }

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

        var theClass = statClass + " gepland" + (room.extern_id != null? " extern" : "");

        if (ar[ci].na_koppel == 1 || params.forSelectRoom || params.urole=='fe')
        {
            // Geen catering indicatie
        }
        else
        {
            if (ar[ci].aantalA > 0)
                theClass += " metcat";
            if (ar[ci].aantalD > 0)
                theClass += " metobj";
        }

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

        if (h_start<S("res_t1"))
        {
            h_start = S("res_t1") - S("res_h");
            if (dagen > 0)
                theClass += " continueleft";
            else
                theClass += " overflowleft";
        }
        px_start = (h_start-S("res_t1"))*hour_px;

        var contright = false;
        if (h_end>S("res_t2"))
        {
            h_end = S("res_t2") + S("res_h");
            if (dagen < nr_days-1)
            {
                theClass += " continueright";
                contright = true;
            }
            else
                theClass += " overflowright";
        }
        px_end = (h_end-S("res_t1"))*hour_px;

        px_width = px_end - px_start;

        var theStyleLeft = ""; // voor cleaning blokje afmeting
        var theStyleRight = "";
        // Perhaps cleaning time, alleen optie en definitief
        if (room.prepost_time > 0 && (ar[ci].fo_status == 1 || ar[ci].fo_status == 2))
        {
            theClass += " res_cleaning";

            // maximaal kwartier 'doorschieten' links/rechts
            var preclean = Math.min(room.prepost_time, h_start - S("res_t1") + 0.25);
            var postclean = Math.min(room.prepost_time, S("res_t2") - h_end + 0.25);

            if ( Math.round(hour_px * postclean - 1) > 0 )
                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)
                    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 res_flag = "";
        if (ar[ci].flag_status > 0)
        {
          //res_flag = "<img src='../pictures/resflag"+ar[ci].flag_status+".png'>";
          res_flag = I("fa-circle respl resflag"+ar[ci].flag_status);
        }

        if (!ar[ci].na_koppel && !not_available && !params.forSelectRoom)
            theClass += " click";

        var div = "<div class='"+theClass+"'";
        if (ar[ci].rsv_ruimte_key)
            div += " rsv_key='" + ar[ci].rsv_ruimte_key + "'"
        if (ar[ci].extern)
        {
            var txt = L("lcl_reservation") + ": " + ar[ci].extern.res_nr // TODO: lcl_reservering_extern?
                        + " " + toTimeString(ar[ci].res_van)
                        + "-" + toTimeString(ar[ci].res_tot)
                        + "\n" + ar[ci].extern.omschrijving;
            div += " title='" + safe.htmlattr(txt) + "'";
            if (ar[ci].extern.deepurl)
                div += " deepurl='" + safe.htmlattr(ar[ci].extern.deepurl) + "'";
        }
        var safetxt = "";
/*
        if (hour_px >= 24) // dan is de omschrijving opgehaald
        {
            if (px_width > 60) // totale balk 60 pixels
                var txt = 'ar[ci].Omschrijving'; // 'ar[ci].omschrijving'
            else
                var txt = '...';
            // TODO: een class die niet wrapt
            safetxt = "<span style='color:white;white-space: nowrap;text-overflow: ellipsis;'>" + safe.htmlattr(txt) + "</span>";
        }
*/
        div += " style='z-index:"+ci+";left:"+px_start+"px;width:"+px_width+"px;"+theStyleLeft+theStyleRight+"'>"
                    +res_flag+safetxt+"&nbsp;</div>";
        html.push("\n"+div);
      }
      html.push("</div></td>")

    if (dagen < nr_days - 1)
    { if (contright) {
        html.push('<td class="between"><div class="' + statClass +  '">&nbsp;</div></td>');
      } else {
        html.push('<td class="between">&nbsp;</td>');
      }
    }
    else
    {
      html.push('<td class="post"><div>&nbsp;</div></td>');
    }
  }
  return html.join("");
}

function make_plan_room(plan_rooms_info, plan_bezet_info, params)
{
  var nnregels = 0;
__Log("start make_plan_room");

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

  // Iterate through all reservable rooms (vertically) and show schedule for them (horizontally)
  var res_ruimte_key, free;

  if (plan_rooms_info.length == 0)
  {
    Response.Write("<table style='width:500px'><tr><td>" + L("lcl_res_none_inplanbord") + "</td></tr></table>");
    return; // quick exit
  }

  var nr_days = Math.round(1 + (params.res_tot.midnight() - params.res_van.midnight()) / 24 / 60 / 60 / 1000);
  // Bereken dynamisch breedte blokjes
  var hour_px = res.hour_px(width_px - 300, nr_days);

  var onclick = "";
  var onmouse = "";
  if (!params.forSelectRoom && authparams.PRSwritelevel < 9 && authparams.ALGwritelevel < 9)
  {
      var dt = params.res_van.midnight().getTime();
      onclick = "onclick=\"room_table_click(event,new Date("+dt+"), " + hour_px + ", "+safe.jsfloat(S("res_t1"))+",'"+params.urole+"',"+params.act+")\"";
      onmouse = "onmousemove=\"room_table_mouse(event,new Date("+dt+"), " + hour_px + ", "+safe.jsfloat(S("res_t1"))+")\"";
      onmouse += " onmouseout=$('#timetip').hide();"
  }

  var xfunc = user.func_enabled2("CAD", { isOptional: true });
  var cad_button = (xfunc && xfunc.canRead("WEB_CADUSE"));

%>
    <script type='text/javascript'>
        function openFG(evt, res_ruimte_key, titel)
        {
            var url = '../cad/ShowRoom.asp?res_ruimte_key='+res_ruimte_key;
            FcltMgr.openModalDetail(url, titel );
            FcltMgr.stopPropagation(evt);
        }
    </script>

<!--[if lt IE 8]>
<style>
    tr.res_nofit.selected {  display: block!important; }
</style>
<![endif]-->
  <div id='timetip'></div>
  <table id="<%=params.id%>" cellspacing="0" hour_px="<%=hour_px%>"
         class="compressed planbord planbord<%=hour_px%> multiday"
         <%=onclick%>
         <%=onmouse%>
  ><thead>
  <tr style='height:36px;vertical-align:top;'>
    <td><label><!--silence--></label></td>
    <td align='right' class="capaciteit"><label><!--silence--></label></td>
    <% Response.Write(res.build_planbord_tijdbalk(params.res_van, nr_days, hour_px, S("res_t1"), S("res_t2"), params.fnStep)); %>
  </tr></thead><tbody>
<%

  var any_nofit = false;
  if (params.forSelectRoom)
  {
    any_nofit = set_will_fit(plan_rooms_info, plan_bezet_info, params);
  }

  for (i_room in plan_rooms_info)
  {
    var room = plan_rooms_info[i_room];

    var bezet_info = plan_bezet_info[room.res_ruimte_key];
    // no_fit is al bepaald met set_will_fit

    var cls = ""
    if (params.forSelectRoom)
    {
      if (params.res_ruimte_key==room.res_ruimte_key)
      {
        cls = " selected";
      }
      else
      {
        if (!room.will_fit)
          cls = " res_nofit";
      }
    }
    if (room.extern_id != null)
    {
      cls += " extern";
    }
%>
    <tr class='<%=cls%>'
<%      if (room.deepurl)
{
        Response.Write(" deepurl='"+safe.htmlattr(room.deepurl)+"'");
        Response.Write(" disc_key='"+params.disc_key+"'");
}
%>
        id='<%=room.res_ruimte_key%>'>
      <td class='label'
          OnMouseOver="showOpmerking('#remark<%=room.res_ruimte_key%>', event);"
          OnMouseOut="$('#remark<%=room.res_ruimte_key%>').hide();"
      <%      if (params.forSelectRoom && room.extern_id == null)
          Response.Write(" onClick='selectRoom(this);' style='cursor:pointer'"); %>
      ><nobr>
<%
    if (cad_button && !params.extern)
        Response.Write("<i class='fa fa-fw fa-map-marker plancad' title='"+L("lcl_prs_wp_fgraph")+"' onclick='openFG(event,"+room.res_ruimte_key+",\"" +safe.jsstring(room.res_ruimte_nr) + "\")'></i>");

    var capc_txt = ''+room.bMin+((room.bMin!=room.bMax)?"-"+room.bMax:"")+" pers."

    var safe_tooltip = safe.html(room.omschrijving);
    if (room.image)
    {
        if (!room.image_url)
            room.image_url = S("res_image_path") + room.image;
        safe_tooltip += "<br><br><img class='resplanfoto' style='height:100px' theSrc='"+safe.htmlattr(room.image_url)+"'>"
    }
%>
        <label><%=safe.html(room.res_ruimte_nr)%></label></nobr>
        <div class="res_remark" style='z-index:9999;text-align:center' id="remark<%=room.res_ruimte_key%>">
            <%=safe_tooltip%>
        </div>
      </td>
      <td class="capaciteit"><nobr><%=capc_txt%></nobr></td>
<%
      nnregels ++;
      Response.Write(make_plan_regel(room, bezet_info, params, nr_days, hour_px));
%>  </tr>
<%
  }
%>
  <tr><td></td>
     <td></td>
     <% Response.Write(res.build_planbord_tijdbalk(params.res_van, nr_days, hour_px, S("res_t1"), S("res_t2"))); %>
  </tr>
  </tbody>
  </table>
<% if (!params.noclicker) { %>
  <script>
    $(function () {
               $("table#<%=params.id%>").on("mouseover", "td div.gepland", function (e)
                {
                    var obj = e.currentTarget;
                    rsv_title(obj);
                });
               $("table#<%=params.id%>").on("click", "td div.click", function (e)
                {
                    var obj = e.currentTarget;
                    rsv_click(obj, '<%=params.urole%>');
                });
    });
  </script>
<% } %>
<%
  if (any_nofit)
  {
    %><div class="resplanbordlimited" onclick="$('table#<%=params.id%>').toggleClass('compressed');$(this).toggle();$(this).next().toggle();FcltMgr.resized()">
       <a><%=L("lcl_res_show_full_room_catalogus")%></a></div>
      <div class="resplanbordlimited" style='display:none' onclick="$('table#<%=params.id%>').toggleClass('compressed');$(this).toggle();$(this).prev().toggle();FcltMgr.resized()">
       <a><%=L("lcl_res_show_half_room_catalogus")%></a></div>
      <div class="mapcontainer"></div><%
  }
__Log("done make_plan_room");
  return nnregels;
}
%>
