
(function(jQuery){

  /**
   * Loads the departure dates inside the <select name="disponibility"> elements
   * and associates the departure constraints data to the first one.
   * @param peferences the preferred criteria
   * @return void
   */
  jQuery.loadResformDepartureDates = function(peferences){
    var dispoSelector = jQuery("[name='disponibility']"),
    firstSelector = dispoSelector.first(),
    jData = firstSelector.data('taglibResformData');
    if (jData != null) {
      dispoSelector.each(function() {
        jQuery(this).html("<option>" + jQuery.readMessage("loading.message", null) + "</option>");
      });
    }
    firstSelector.data('taglibResformData', null);
      jQuery.ajax({ url: taglibResformPreferences.servletUrl,
             data: peferences,
             success: function(result){
                         var contentList = result.split("<!-- #### -->"),
                             jData,
                             departureCity,
                             formElements = jQuery("[name='disponibility']");

                         // Associate data only to the first one.
                         if (contentList[1].length > 0) {
                           jData = jQuery.parseJSON(contentList[1])
                           formElements.first().data('taglibResformData', jData);
                           departureCity = jData.departureCity;
                           jQuery("[name='depCityCode']").each(function() {
                             jQuery(this).val(departureCity);
                           });
                         }
                         formElements.each(function() {
                           jQuery(this).html(contentList[0]);
                         });
                         jQuery.updateResformPaxConstraintMessages();
                      }
      });
  }

  /**
   * Displays the pax constraints messages for the selected dates.
   * This removes previous existing messages as well.
   */
  jQuery.updateResformPaxConstraintMessages = function() {
    var dispoSelector = jQuery("[name='disponibility']"),
        firstDispoSelect = dispoSelector.first(),
        jData = firstDispoSelect.data("taglibResformData"),
        selectedDispoCode = dispoSelector.first().val(),
        paxConstraints,
        minPax,
        maxPax,
        replacement,
        messageText,
        dynamicMessageClass = jQuery.readMessage("pax.constraint.dynamic_message.class", null);

    if (jData != null) {
          paxConstraints = jData.dispos[selectedDispoCode];
          if (paxConstraints == null) {
            paxConstraints = jData.dispos["otherDates"];
          }
          if (paxConstraints != null) {
            minPax = paxConstraints.minPax;
            maxPax = paxConstraints.maxPax;
            if (minPax != null && maxPax != null) {
               replacement = {"minPax": minPax, "maxPax": maxPax, "pax": minPax};
               if (minPax == 1 && maxPax == 1) {
                 messageText = jQuery.readMessage("pax.constraint.min_1.max_1.message", replacement);
               } else if (minPax == 1) {
                 messageText = jQuery.readMessage("pax.constraint.min_1.max_n.message", replacement);
               } else if (minPax == maxPax) {
                 messageText = jQuery.readMessage("pax.constraint.min_equals_max.message", replacement);
               } else {
                 messageText = jQuery.readMessage("pax.constraint.min_n.max_m.message", replacement);
               }
            } else if (minPax != null) {
               replacement = {"minPax": minPax, "pax": minPax};
               if (minPax == 1) {
                  messageText = jQuery.readMessage("pax.constraint.min_1.message", replacement);
               } else {
                  messageText = jQuery.readMessage("pax.constraint.min_n.messages", replacement);
               }
            } else if (maxPax != null) {
               replacement = {"maxPax": maxPax, "pax": maxPax};
               if (maxPax == 1) {
                 messageText = jQuery.readMessage("pax.constraint.max_1.message", replacement);
               } else {
                 messageText = jQuery.readMessage("pax.constraint.max_n.messages", replacement);
               }
            }
          }
    }
    jQuery(".bookingMessage .dynamicMessage").remove();
    jQuery(".validationBookingMessage .dynamicValidationMessage").remove();
    if (messageText != null && messageText !== "") {
        jQuery('<p class="' + dynamicMessageClass + '">' + messageText + '</p>').appendTo(".bookingMessage");
    }
  }

  /**
   * Calculates the search criteria for the reservation form
   * @return the search criteria
   */
  jQuery.calculateResformCriteria =  function() {
    var criteria = jQuery.extend(true, {}, taglibResformPreferences);
    if (window.updateCustomResformCriteria) {
      criteria = updateCustomResformCriteria(criteria);
    }
    return criteria;
  }

  /**
   * @param messageKey the messageKey in the properties part
   * @replacementVariables an optional key-value object with replacement arguments
   * @return the message value for the requested key, with the replaced variables
   */
  jQuery.readMessage = function(messageKey, replacementVariables) {
    var jData = jQuery("[name='disponibility']").first().data("taglibResformData"),
        messageValue,
        regex;
    if (jData == null) {
      return "??" + messageKey + "??";
    }
    messageValue = jData.messages[messageKey];
    if (messageValue == null) {
      return "";
    }
    if (replacementVariables == null) {
      replacementVariables = {};
    }
    replacementVariables["white-space"] = " ";
    for(keyArg in replacementVariables) {
      regex = new RegExp("\\[\\%" + keyArg + "\\%\\]", "g");
      messageValue = messageValue.replace(regex, replacementVariables[keyArg]);
    }
    return messageValue;
  }

  /**
   * Performs the data validation and writes the error messages in the message container.
   * @return true if the form is valid; false otherwise
   */
  jQuery.validateResform = function() {
    var nbAdults = parseInt(jQuery("[name='nbAdults']").first().val()),
      nbChildren = parseInt(jQuery("[name='nbChildren']").first().val()),
      nbBabies = parseInt(jQuery("[name='nbBabies']").first().val()),
      paxCount = nbAdults + nbChildren + nbBabies,
      dispoSelector = jQuery("[name='disponibility']"),
      firstDispoSelect = dispoSelector.first(),
      selectedDispoCode = dispoSelector.first().val(),
      jData = firstDispoSelect.data("taglibResformData"),
      dynamicMessageClass = jQuery.readMessage("pax.constraint.dynamic_error.class", null),
      paxConstraints = jData.dispos[selectedDispoCode],
      messageText;

      if (paxConstraints == null) {
        paxConstraints = jData.dispos["otherDates"];
      }
      if (paxConstraints != null) {
        minPax = paxConstraints.minPax;
        maxPax = paxConstraints.maxPax;
        if (minPax != null) {
          minPax = parseInt(minPax);
        }
        if (maxPax != null) {
          maxPax = parseInt(maxPax);
        }

        if (minPax != null && maxPax == null) {
          replacement = {"minPax": minPax, "pax": minPax};
          if (paxCount < minPax) {
            if (minPax == 1) {
              messageText = jQuery.readMessage("pax.constraint.min_1.error", replacement);
            } else {
              messageText = jQuery.readMessage("pax.constraint.min_n.error", replacement);
            }
          }
        } else if (minPax == null && maxPax != null) {
            replacement = {"maxPax": maxPax, "pax": maxPax};
            if (paxCount > maxPax) {
              if (maxPax == 1) {
                messageText = jQuery.readMessage("pax.constraint.max_1.error", replacement);
              } else {
                messageText = jQuery.readMessage("pax.constraint.max_n.error", replacement);
              }
            }
        } else if (minPax != null && maxPax != null) {
          replacement = {"minPax": minPax, "maxPax": maxPax, "pax": minPax};
          if (paxCount < minPax || paxCount > maxPax) {
            if (minPax == 1 && maxPax == 1) {
              messageText = jQuery.readMessage("pax.constraint.min_1.max_1.error", replacement);
            } else if (minPax == 1) {
              messageText = jQuery.readMessage("pax.constraint.min_1.max_n.error", replacement);
            } else if (minPax == maxPax) {
              messageText = jQuery.readMessage("pax.constraint.min_equals_max.error", replacement);
            } else {
              messageText = jQuery.readMessage("pax.constraint.min_n.max_m.error", replacement);
            }
          }
        }
        jQuery(".validationBookingMessage .dynamicValidationMessage").remove();
        if (messageText != null) {
          if (messageText !== "") {
              jQuery('<p class="' + dynamicMessageClass + '">' + messageText + '</p>').appendTo(".validationBookingMessage");
          }
          return false;
        }
      }
      return true;
  }


})(jQuery);


jQuery(function() {
 /** Load the departure dates on load. */
  if (window.taglibResformPreferences) {
    /** When asynchronous load is enabled, launch it with the default parameters.  */
    if (taglibResformPreferences.asynchronousLoad === "true") {
      jQuery.loadResformDepartureDates(jQuery.calculateResformCriteria(taglibResformPreferences));
    }

    /** When automatic update is enabled, associate the update function to the  */
    if (taglibResformPreferences.autoUpdate === "true") {
      /** Automatic update on departure city select box change. */
      jQuery("[name='depCityCode']").change(function() {
        var criteria = jQuery.calculateResformCriteria(taglibResformPreferences);
        criteria.departureCity = jQuery(this).val();
        jQuery.loadResformDepartureDates(criteria);
      });

      /** Automatic messages update on departure date select box change. */
      jQuery("[name='disponibility']").change(function() {
        var changedSelectValue = jQuery(this).val();
        jQuery("[name='disponibility']").each(function() {
          if (jQuery(this).val() != changedSelectValue) {
            jQuery(this).val(changedSelectValue);
          }
        });
          jQuery.updateResformPaxConstraintMessages();
      });

      /** Automatic select boxes update on change. */
      jQuery("[name='nbAdults'],[name='nbChildren'],[name='nbBabies']").change(function() {
        jQuery(".validationBookingMessage .dynamicValidationMessage").remove();
        var name = jQuery(this).attr('name'),
            changedValue = jQuery(this).val();
        jQuery("[name='" + name + "']").each(function() {
              if (jQuery(this).val() != changedValue) {
                  jQuery(this).val(changedValue);
                  jQuery(this).change();
                }
        });
      });

    }
  }
});

