<% /*
     $Revision$
     $Id$

     File:          Calendar.inc
     Description:   generic interface function for selecting a 'date' and/or time

*/ %>

<%
FCLTHeader.Requires({ plugins: ["jQuery"],
                      js: ["jquery-ui.js", "date.js"],
                      extrahead: _initVrijedagen });

if (!Date.prototype.toISOString) {
    Date.prototype.toISOString = function() {
        function pad(n) { return n < 10 ? '0' + n : n }
        return this.getUTCFullYear() + '-'
            + pad(this.getUTCMonth() + 1) + '-'
            + pad(this.getUTCDate()) + 'T'
            + pad(this.getUTCHours()) + ':'
            + pad(this.getUTCMinutes()) + ':'
            + pad(this.getUTCSeconds()) + 'Z';
    };
}

function _initVrijedagen()
{
  var sql = "SELECT mld_vrije_dagen_datum FROM mld_vrije_dagen WHERE mld_vrije_dagen_id = 'Default'";
  var oRs = Oracle.Execute(sql);
  var mld_vrije_dagen = "0";
  while (!oRs.Eof)
  {
      mld_vrije_dagen += ", " + (new Date(oRs("mld_vrije_dagen_datum").value)).getTime();
      oRs.MoveNext;
  }
  oRs.Close();
%>
  <script type="text/javascript">
    var mld_vrije_dagen = [<%=mld_vrije_dagen%>];
    var mld_vrije_dagen_alt = [];
    var calArray = new Array();
    // Zie ook kenmerk_common.inc. Delen code was iets te lastig
    $(function ()
    {
        var datepickerDefaults = {
                altFormat: "@",
                showOn: "none",
                dateFormat: 'D dd-mm-yy',
                changeYear: true,
                changeMonth: true,
                duration: 'fast',
                dayNames: calendar_names.days,
                dayNamesMin: calendar_names.daysMin,
                dayNamesShort: calendar_names.daysMin,
                weekHeader: calendar_names.weekMin,
                firstDay: 1,
                monthNamesShort: calendar_names.monthsShort,
                monthNames: calendar_names.months,
                showOtherMonths:true,
                selectOtherMonths:true,
                showWeek: true
            };
        if (!(typeof Modernizr == "undefined" || !Modernizr.inputtypes.date || typeof window.orientation == "undefined"))
        {
            datepickerDefaults.beforeShowDay = function(datum)
                                                {
                                                    var vrije_dagen = (mld_vrije_dagen_alt.length > 0 ? mld_vrije_dagen_alt : mld_vrije_dagen);
                                                    if ($.inArray(datum.getTime(), vrije_dagen) > -1)
                                                        return [ true, 'ui-datepicker-vrije-dag' ];
                                                    else
                                                        return [ true, 'ui-datepicker-org247' ];
                                                }
        }

        $.datepicker.setDefaults(datepickerDefaults);
    });
   </script>
<%
}
// TODO met params.mode kan evt beperkingen worden meegegeven, vgl. suggest filtcode

// fieldID is het id van een datumveld in het formulier
// Daartoe wordt een hidden veld aangemaakt met dat id waar de geselecteerde datum in komt
// Een tweede show_<id> veld wordt aangemaakt met de zichtbare datum
//
// params
//      label: te tonen label
//      datum: default datum (jScript date object)
//      timeField ook van-tijd toestaan
//      timeStep in minuten bijvoorbeeld 15 voor kwartieren (wat de default is)
//      timeFrom bijvoorbeeld voor 8 uur 's ochtends (wat de default is)
//      noConvert: Gebruik voor Setting tijden en andere tijden die niet tijdzone gebonden zijn
//      trlass:   wordt ook op de <tr> gezet
//      maxFuture en maxPast: aantal dagen limitering. -1 voor geen limiet
//      trhidden: De hele tr moet hidden en niet alleen het inputveld
//      hidden: de calender is hidden (maar tijd is er mogelijk wel)
//              Bij afhankelijke calenders wordt de datum dan helemaal gelijk gehouden
//      timeTo bijvoorbeeld 18 voor 6 uur 's avonds (wat de default is)
//      readonly: Toon de calendar readonly. Dat wordt er uiteraard ook niets gesubmit (toch?)
//      saveValue: Ondanks het readonly zijn van de datum, deze toch opslaan (hidden waarden veld aanmaken en vullen).
//      onChange: functie om aan te roepen als datum gewijzigd is
//      onChangeDate: functie om aan te roepen als alleen het datumveld gewijzigd is
//      onChangeTime: functie om aan te roepen als alleen het tijdsveld gewijzigd is
//      selectableDays: 0=alle dagen te selecteren, 1=vrije dagen niet te selecteren, 2=weekend niet te selecteren, 3=1+2
//      TODO: TimeTo ook tot-tijd toestaan
function FCLTcalendar (fieldID, params)
{
    params = params || {};
    if ((params.datum == null || params.datum == "") && params.readonly && params.suppressEmpty)
      return; // snel klaar
    var isMobile = ("mobile" in params) ? params.mobile : (typeof mobile != "undefined");
    if (params.label)
    {
      if (isMobile)
      { %>
        <div <%=params.trhidden? "style='display:none'" : ""%>><label class="ed"><%=params.label%></label>
<%    }
      else
      { %>
        <tr <%=params.trclass? "class='" + params.trclass + "'" : ""%> <%=params.trhidden? "style='display:none'" : ""%>>
        <td class="label"><label for="show_<%=fieldID%>" style="white-space: nowrap;"><%=params.label%></label></td>
        <td>
    <% }
    }

    _FCLTcalendar (fieldID, params)

    if (params.label)
    {
      if (params.opmerk)
      { %>
        &nbsp;<%=safe.html(params.opmerk)%>
<%    }
      if (isMobile)
      { %>
        </div>
<%    }
      else
      { %>
        </td></tr>
<%    }
    }
}

function _FCLTcalendar (fieldID, params)
{
  var initDate = params.datum || new Date();
  var isMobile = ("mobile" in params) ? params.mobile : (typeof mobile != "undefined");
  if (params.initEmpty == 1)
  {
      var iniTextDate = "";
      var iniDateDate = "";
      var iniDateVal = null;
      if (params.initTimeEmpty == 1)
        var iniTime = "";
      else
        var iniTime = toTimeString(initDate, { isLocal: params.noConvert });
  }
  else
  {
      var iniTextDate = toDateString(initDate, { isLocal: params.noConvert });
      // Input type=date verwacht het formaat [YYYY-MM-DD]
      var iniDateDate = new Date(initDate.getTime()-(initDate.getTimezoneOffset()*60000)).toISOString().substr(0,10);
      var iniDateVal = initDate.valueOf();
      if (params.initTimeEmpty == 1)
        var iniTime = "";
      else
        var iniTime = toTimeString(initDate, { isLocal: params.noConvert });
  }
  var hiddentag = params.hidden? " style='display:none'" : ""; // Alleen op de calender, niet de tijd
  if (params.readonly)
  { %>
    <span id="show_<%=fieldID%>" class="flddate<%=params.addClass? " " + params.addClass : ""%>" <%=hiddentag%>>
      <%=safe.html(iniTextDate)%>
    </span>
<%}
  else // !params.readonly
  {
      if (!params.hidden)
      { %>
  <span class="input-icon-wrapper">
<%    } %>
  <input id="show_<%=fieldID%>"
         class="flddate<%=params.required?" required":""%><%=isMobile ? MOBILE_UI_CLASSES.input : ""%><%=params.addClass? " " + params.addClass : ""%>"
         type="<%=params.hidden?'hidden':(isMobile ? 'date' : 'text')%>" <%=hiddentag%>
         value="<%=safe.htmlattr(isMobile ? iniDateDate : iniTextDate)%>"
         autocomplete="off"
         nofollow="<%=params.nofollow? 1 : 0%>">

<%  if (!params.hidden)
    { %>
  <span class='dateklikker' onclick='$("#show_<%=fieldID%>").click().focus()'><%=I("fa-calendar")%></span>
  </span>
<%  }
  }
  if (params.timeField)
  {
    if (params.readonly)
    { %>
      <span id="time_from_<%=fieldID%>" class="fldtime <%=(params.timeClass||"")%><%=params.addClass? " " + params.addClass : ""%>">
        <%=safe.html(iniTime)%>
      </span>
<%  }
    else // !params.readonly
    { %>
      <span class="input-icon-wrapper">
        <input type="text"
               class="fldtime<%=params.required?" required":"" + " " + (params.timeClass||"")%><%=isMobile ? MOBILE_UI_CLASSES.input : ""%><%=params.addClass? " " + params.addClass : ""%>"
               id="time_from_<%=fieldID%>" size="5" value="<%=safe.htmlattr(iniTime)%>" autocomplete="off">
        <span class='timeklikker <%=(params.timeClass||"")%>' onclick='$("#time_from_<%=fieldID%>")[0].click(); FcltMgr.stopPropagation(event);'>
          <%=I("fa-clock")%>
        </span>
      </span>
<%  }
  }

  if (!params.readonly || (params.readonly && params.saveValue))
  { %>
    <input type="hidden" id="<%=fieldID%>" name="<%=fieldID%>" value="<%=iniDateVal%>"<%=('volgnr' in params ? ' data-volgnr="' + safe.htmlattr(params.volgnr) + '"' : '')%>>
<%
  }
  if (params.readonly) return; // dan zijn we wel klaar
%>
  <script type="text/javascript">

    function fnBeforeShowDay(date, selectMode)
    {   // selectMode: 0= Alle dagen te selecteren, 1= vrije dagen niet te selecteren
        //           , 2= weekends niet te selecteren, 3= vrije dagen en weekends niet te selecteren
        var organisation247Type = <%=S("res_247organisation")%>;
        var weekend = (!$.datepicker.noWeekends(date)[0]);
        var vrije_dagen = (mld_vrije_dagen_alt.length > 0 ? mld_vrije_dagen_alt : mld_vrije_dagen);
        var day_off = ($.inArray(date.getTime(), vrije_dagen) > -1);
        if (organisation247Type == 1)
        { // 24/7 Organisatie
          if (day_off)
          {
            var disableDay = (day_off && ((selectMode & 1) == 1));
            return [ !disableDay, "ui-datepicker-vrije-dag", "Vrij" ];
          }
          else
          {
            return [ true, "ui-datepicker-org247" ];
          }
        }
        else
        { // Geen 24/7 organisatie.
          if (day_off || weekend)
          { // organisation247Type=2: Weekends are strict holidays (No reservations allowed)
            var disableDay = ( day_off && ((selectMode & 1) == 1)) || (weekend && ((selectMode & 2) == 2) && organisation247Type == 2)
            return [ !disableDay, "ui-datepicker-vrije-dag"];
          }
          else
          {
              return [ true, "" ];
          }
        }
    }

    $(function()
    {
      $("#show_<%=fieldID%>")[0].onSelect = function()
      {
          cal_onChange('<%=fieldID%>',
              { volgnr: <%=params.volgnr?params.volgnr:'null'%>,
                onChange: '<%=safe.jsstring(params.onChange)%>',
                onChangeDate: '<%=safe.jsstring(params.onChangeDate)%>',
                onChangeMulti: '<%=safe.jsstring(params.onChangeMulti)%>'
              });
      }
   <%   // Indien er niveau's zijn in tijd tussen meerdere kalenders
      if (params.volgnr)
      { %>
<%      if (params.volgnr == 1)
        { // Als er opnieuw kalenders worden geladen moet de calArray op nul worden gezet anders worden nieuwe kalenders aan de vorig toegevoegd.
          %>
          if (calArray.length > 0)
          {
            calArray.length = 0;
          }
<%      } %>

        // Nieuwe kalender wordt op volgorde toegevoegd aan calArray
        if (calArray.length == 0)
          calArray.push({ id: "<%=fieldID%>", volgnr: <%=params.volgnr%>}); // Eerste kalender wordt toegevoegd.
        else
        {
          // kalender op volgorde van volgnummer aan calArray toevoegen voor als er meer dan twee calenders worden gebruikt.
          // Toevoegen lege kalender
          // Is het veld al aanwezig dan veld in in calArray NIET toevoegen. Komt voor als calender via jquery load functie wordt herladen.
          var aanwezig = false;
          for (var i = 0; i < calArray.length; i++)
          {
            if (calArray[i].id == "<%=fieldID%>" && calArray[i].volgnr == <%=params.volgnr%>)
              aanwezig = true;
          }
          if (!aanwezig)
          {
            calArray.push({ id: "", volgnr: 0});
            for (var i = 1; i <= calArray.length; i++)
            {
              if (calArray.length - i > 0 && calArray[calArray.length-1-i].volgnr > <%=params.volgnr%>)
              { // Opschuiven
                calArray[calArray.length - i].id = calArray[calArray.length - 1 - i].id;
                calArray[calArray.length - i].volgnr = calArray[calArray.length - 1 - i].volgnr;
              }
              else
              { // Kalender toevoegen
                calArray[calArray.length - i].id = "<%=fieldID%>";
                calArray[calArray.length - i].volgnr = <%=params.volgnr%>;
                break;
              }
            }
          }
        }
   <%   // TODO: Controle of Initiële  datums op volgorde zijn.
        //for (var i = 1; i < calArray.length; i++)
        //{
        //  if (calArray[i].volgnr == < %=params.volgnr% > && $("#" + calArray[i-1].id).val() > $("#" + calArray[i].id).val())
        //    FcltMgr.alert("ERROR: Initiële  datum van kalender met volgnummer " + calArray[i].volgnr + " is eerder als voorafgaande datum");
        //}

      } %>
      if (typeof Modernizr == "undefined" || !Modernizr.inputtypes.date || typeof window.orientation == "undefined")
      {
          $.datepicker._gotoToday = function(id) {
              $(id).datepicker("setDate", new Date()).datepicker("hide").trigger("change").blur();
          };

          $("input#show_<%=fieldID%>").datepicker(
              {   altField: "#<%=fieldID%>",
                  showButtonPanel: true,
                  currentText: L("lcl_date_today"),
                  closeText: L("lcl_cancel"),
                  // Volgorde in tijd: maxPast, minPast, sysdate, minFuture, maxFuture
                  <%=(params.minDate instanceof Date)? "minDate : new Date(" + params.minDate.valueOf() + ")," : ""%>
                  <%=(params.maxDate instanceof Date)? "maxDate : new Date(" + params.maxDate.valueOf() + ")," : ""%>
                  <%=(typeof params.maxPast == "number" && params.maxPast >= 0)? "minDate : '-" + params.maxPast + "d'," : ""%>
                  <%=(typeof params.minPast == "number" && params.minPast >= 0)? "maxDate : '-" + params.minPast + "d'," : ""%>
                  <%=(typeof params.maxFuture == "number" && params.maxFuture >= 0)? "maxDate : '+" + params.maxFuture + "d'," : ""%>
                  <%=(typeof params.minFuture == "number" && params.minFuture >= 0)? "minDate : '+" + params.minFuture + "d'," : ""%>
                  <%=(params.autosize)? "beforeShow: function(input, inst) { setTimeout('FcltMgr.resized(window)', 100) }," : ""%>
                  "onUpdateDatepicker": function() { $(".ui-datepicker-current").removeClass("ui-priority-secondary").addClass("ui-priority-primary"); },
                  numberOfMonths: <%=(device.test(device.isMobile)?1:params.calendars) || 1%>,
                  <%= params.hidden? "showOn:'focus'," : ""%>
                  onSelect: $("#show_<%=fieldID%>")[0].onSelect,
                  onClose: function (dateText, inst) { if ($(frameElement).hasClass("fcltmodal")) { $("#show_<%=fieldID%>").focus(); }},
                  beforeShowDay: function(date) { var selectableDay = <%=(params.selectableDays ? params.selectableDays : 0)%>;
                                                  return fnBeforeShowDay(date, selectableDay);
                                                }
             }).change(cal_show_onChange)
               .val("<%=safe.jsstring(isMobile ? iniDateDate : iniTextDate)%>");
             $("#show_<%=fieldID%>").on('focus', function() { $("#show_<%=fieldID%>").datepicker('show'); });

       <% if (params.autoopen){ %>
            $("#show_<%=fieldID%>").datepicker('show');
            if ($(frameElement).hasClass("fcltmodal"))
                parent.FcltMgr._resizeModal(frameElement);
       <% } %>

          if ($(frameElement).hasClass("fcltmodal"))
          {
              /* Observeer de visibility van de datepicker, als die veranderd, resize dan mijn modal */
              var modal_datepicker_observer = new MutationObserver(function(mutations)
              {
                  mutations.forEach(function(mutationRecord)
                  {
                      if (!mutationRecord.oldValue)
                          return;

                      var oldDisplay = mutationRecord.oldValue.match(/display:\s?(.*?);/);
                      if (oldDisplay === null || oldDisplay.length <= 1)
                          return;

                      var hasOpacity = mutationRecord.oldValue.match(/opacity/);
                      var showing = $(mutationRecord.target).data("showing");

                      if (showing && oldDisplay[1] === "none")
                      {
                          $(mutationRecord.target).data("showing", false);
                          parent.FcltMgr._resizeModal(frameElement);
                      }
                      else if (!showing && oldDisplay[1] === "block" && hasOpacity)
                      {
                          $(mutationRecord.target).data("showing", true);
                          parent.FcltMgr._resizeModal(frameElement);
                      }
                  });
              });

              $(".ui-datepicker").each(function() {
                  $(this).data("showing", <%=(params.autoopen ? "true" : "false")%>);
                  modal_datepicker_observer.observe(this, { attributes: true, attributeFilter: ['style'], attributeOldValue: true });
              });
          }
      }
      else
      {
        var minDateNum = parseInt("<%=(params.minDate instanceof Date) ? params.minDate.valueOf() : ''%>", 10);
        var maxPast = parseInt("<%=(typeof params.maxPast == 'number' && params.maxPast >= 0) ? (params.maxPast * -1) : '0'%>", 10);
        var minFuture = parseInt("<%=(typeof params.minFuture == 'number' && params.minFuture >= 0) ? params.minFuture : '0'%>", 10);

        var maxDateNum= parseInt("<%=(params.maxDate instanceof Date) ? params.maxDate.valueOf() : ''%>", 10);
        var minPast = parseInt("<%=(typeof params.minPast == 'number' && params.minPast >= 0) ? (params.minPast * -1) : '0'%>", 10);
        var maxFuture = parseInt("<%=(typeof params.maxFuture == 'number' && params.maxFuture >= 0) ? params.maxFuture : '0'%>", 10);

        function adjustDate(dateString, minDays, plusDays) {
          if (!dateString) return "";
          var date = new Date(dateString);
          date.setDate(date.getDate() + minDays + plusDays);
          return date.toISOString().split('T')[0];
        }

        var minDate = adjustDate(minDateNum, maxPast, minFuture);
        var maxDate = adjustDate(maxDateNum, minPast, maxFuture);

        $("#show_<%=fieldID%>").val("<%=safe.jsstring(iniDateDate)%>")
                                .attr("type", "date")
                                .attr("min", minDate)
                                .attr("max", maxDate)
                                .change(function ()
                                    {
                                      <%=safe.jsstring(params.onChangeDate)%>;
                                      var dt = new Date(this.value);
                                      $('#<%=fieldID%>').val(dt.getTime());
                                      $("#time_from_<%=fieldID%>").change().focusout();
                                    });
      }
<%
      if (params.timeField)
      {
        if (typeof params.startTime == "number")
        {
          var hh = Math.floor(params.startTime);
          var mi = params.startTime * 60 % 60;
          params.startTime = (hh < 10? "0" : "") + hh + ":" + (mi < 10? "0" : "") + mi;
        }
        if (typeof params.endTime == "number")
        {
          var hh = Math.floor(params.endTime);
          var mi = params.endTime * 60 % 60;
          params.endTime = (hh < 10? "0" : "") + hh + ":" + (mi < 10? "0" : "") + mi;
        }
        params.intervals = (params.intervals && params.intervals.length ? params.intervals : []);
%>
      if (typeof Modernizr == "undefined" || !Modernizr.inputtypes.date || typeof window.orientation == "undefined")
      {
        $("#time_from_<%=fieldID%>").timePicker(
            { step: <%=Math.round(params.timeStep || 15)%>,
              startTime : "<%=params.startTime%>",
              endTime : "<%=params.endTime%>",
              columns: <%=params.intervals.length && params.intervals.length < S("timepickercolumns") ? params.intervals.length : S("timepickercolumns")%>,
              intervals: <%=(params.intervals.length ? '["' + params.intervals.join('","') + '"]' : '[]')%>,
              onChange: function (newVal)
              {
                $("#time_from_<%=fieldID%>").removeClass('bad');
                if ($('#<%=fieldID%>').val() != "")
                { // Er is een tijd ingevuld m.b.v. de timePicker
                  var dt = new Date(parseInt($('#<%=fieldID%>').val())).midnight();
                  var tm = $("#time_from_<%=fieldID%>").timePickerGetTime().getTime();
                  dt.setSeconds(tm / 1000); // setSeconds gaat goed om met zomertijd/wintertijd
                  $('#<%=fieldID%>').val(dt.getTime());
                }
             <% if (params.volgnr)
                { %>
                  cal_checkVolgnr("<%=fieldID%>", <%=params.volgnr%>, true);
             <% }
                if (params.onChange) {
                  Response.Write(params.onChange);
                }
                if (params.onChangeTime) {
                  Response.Write(params.onChangeTime);
                } %>
              }
            })
            if (typeof Modernizr != "undefined")
            {
              $("#time_from_<%=fieldID%> + div.time-holder").hide();
            }
       }
      else
      {   // Native activeren
          $("#time_from_<%=fieldID%>").attr("type", "time")
      }

         $("#time_from_<%=fieldID%>").focusout(function () { time_show_onChange('time_from_<%=fieldID%>',
                                                                              '<%=fieldID%>',
                                                                              { <%=params.volgnr ? "volgnr: " + params.volgnr + "," : ""%>
                                                                                onChange: '<%=safe.jsstring(params.onChange)%>',
                                                                                onChangeTime: '<%=safe.jsstring(params.onChangeTime)%>'});
                                                             FcltMgr.resized(); })
                                     .focus(function () { this.select() });
<%    } %>
    });
  </script>
<%
}
%>