function loadSearchForm(namespace) {
  var startDateName = namespace + "periodFrom";
  var startDateId = "#" + startDateName;
  var endDateName = namespace + "periodTo";
  var endDateId = "#" + endDateName;

  var searchForm = $("#" + namespace + "fm");

  var bindPickers = function (startDate, endDate) {
    startDate.after(
        'selectionChange',
        function (event) {
          var date = event.newSelection[0];
          if (!isNaN(date)) {
            endDate.getCalendar().set('minimumDate', date);
          } else {
            endDate.getCalendar().set('minimumDate', null);
          }
        }
    );

    endDate.after(
        'selectionChange',
        function (event) {
          var date = event.newSelection[0];
          if (!isNaN(date)) {
            startDate.getCalendar().set('maximumDate', date);
          } else {
            startDate.getCalendar().set('maximumDate', null);
          }
        }
    );

    startDate.getCalendar().set('maximumDate', getDateForInput(endDateId));
    endDate.getCalendar().set('minimumDate', getDateForInput(startDateId));
  };

  var createDatePicker = function (A, inputId) {

    $("button.calendar-icon").on("click", function () {
        var input = $(this).siblings("input");
        input.trigger("click");
        input.focus();
        setInputMask(input);
      });

    var currentPicker = getPickerForInput(inputId);
    if (currentPicker !== undefined) {
      return currentPicker;
    }

    var pickerOptions = {
      trigger: inputId,
      mask: getDateMask(),
      popover: {
        on: {
          keydown: function(e) {
            if(e.domEvent._event.key === "Escape") {
              $(inputId).focus();
            }
          },
        },
        toolbars: {
          header: [[{
            icon: 'icon-trash',
            label: 'Clear',
            on: {
              click: function () {
                clearPicker(datepicker);
              },
            }
          }]]
        },
        zIndex: Liferay.zIndex.TOOLTIP
      }
    };

    var datepicker = new A.DatePicker(pickerOptions);
    setPickerForInput(inputId, datepicker);
    return datepicker;
  };

  var setupPickers = function () {
    var startDateInput = $(startDateId);
    var endDateInput = $(endDateId);

    if (startDateInput.length !== 0 && endDateInput.length !== 0) {
      if (!Liferay.Util.isPhone()) {
        var A = getSandbox(namespace);
        var startPicker = createDatePicker(A, startDateId);
        var endPicker = createDatePicker(A, endDateId);

        bindPickers(startPicker, endPicker);
      }
    }
  };

  var clearPicker = function (datepicker) {
    datepicker.get("activeInput").val("");
    datepicker.fire('selectionChange', {
      newSelection: [NaN]
    });
    datepicker.getCalendar().deselectDates();
    datepicker.getCalendar().set("date", new Date());
    datepicker.popover.hide();
  };

  var setInputMask = function (input) {
    var d = 'd';
    var m = 'm';
    var y = 'y';
    var placeholder = d + d + '-' + m + m + '-' + y + y + y + y;

    input.attr("placeholder", placeholder);

    if (input.inputmask !== undefined) {
      input.inputmask("datetime", {
        inputFormat: 'dd-mm-yyyy',
        placeholder: placeholder,
        showMaskOnFocus: false,
        showMaskOnHover: false,
        clearIncomplete: true,
        oncleared: function () {
          clearPicker(getPickerForInput("#" + input.att("id")));
        }
      });
    }
  };

  var getDatePeriodRange = function () {
    var LString = AUI().Lang.String;
    var startDate = getDateForInput(startDateId);
    if (startDate == null) {
      startDate = new Date("1900-01-01");
    }
    var endDate = getDateForInput(endDateId);
    if (endDate == null) {
      endDate = new Date();
      endDate.setFullYear(endDate.getFullYear() + 100);
    }

    var fromLimit = startDate.getFullYear() + LString.padNumber(
        startDate.getMonth() + 1, 2)
        + LString.padNumber(startDate.getDate(), 2)
        + '000000';

    var toLimit = endDate.getFullYear() + LString.padNumber(
        endDate.getMonth() + 1,
        2) + LString.padNumber(
        endDate.getDate(), 2) + '235959';

    return '[' + fromLimit + ' TO ' + toLimit + ']';
  };

  var search = function () {
    var form = AUI.$(document[namespace + "fm"]);
    if (formHasValidPeriodRange()) {
      var range = getDatePeriodRange();
      form.fm('period').val(range);
    }
    submitForm(form);
  };

  var getDateForInput = function (inputSelector) {
    var input = $(inputSelector);
    if (input.length === 0) {
      return null;
    }
    return getDateFromString(namespace, input.val());
  };

  var formHasValidPeriodRange = function () {
    return getDateForInput(startDateId) != null ||
        getDateForInput(endDateId) != null;
  };

  searchForm.on("submit", function (e) {
    e.preventDefault();
    search();
  });

  $('#' + namespace + 'keywords').on('keydown', function (event) {
    if (event.keyCode === 13) {
      search();
    }
  });

  AUI({lang: getLang()}).use(
      'aui-datepicker',
      'aui-datatype-date-parse',
      'datatype-date-format',
      function (A) {
        window[namespace + 'A'] = A;
        setupPickers();
      }
  );
}

function getPickerForInput(inputId) {
  return window[inputId + "Picker"];
}

function setPickerForInput(inputId, picker) {
  window[inputId + "Picker"] = picker;
}

function getLang() {
  var langId = Liferay.ThemeDisplay.getLanguageId();
  return langId.split("_")[0];
}

function getDateFromString(namespace, value) {
  var date = getSandbox(namespace).Parsers.date(getDateMask(),
      value);
  return date !== false ? date : null;
}

function formatDate(namespace, date) {
  var date = getSandbox(namespace).Date.format(date, {
    format: getDateMask()
  });
  return date !== false ? date : null;
}

function isValidDateFormat(value) {
  var dateRegex = new RegExp("\\d\\d-\\d\\d-\\d\\d\\d\\d");
  return dateRegex.test(value);
}

function isValidDateRange(startDateTime, endDateTime) {

  if (startDateTime == null && endDateTime == null) {
    return false;
  }

  if (startDateTime == null || endDateTime == null) {
    return true;
  }

  var startDate = new Date(startDateTime);
  startDate.setHours(0, 0, 0, 0);

  var endDate = new Date(endDateTime);
  endDate.setHours(0, 0, 0, 0);

  return startDate.getTime() <= endDate.getTime();
}

function getDateMask() {
  return '%d-%m-%Y';
}

function getSandbox(namespace) {
  return window[namespace + 'A'];
}

function createAutoCompleteList(namespace, fields, url, onSelect) {

  AUI().use(
      "autocomplete-list",
      "aui-base",
      "aui-io-request",
      "autocomplete-filters",
      "autocomplete-highlighters",
      "datasource",
      "datasource-get",
      function (A) {
        var dataSource = new A.DataSource.IO({
          source: url
        });

        var searchLocator = function (response) {
          var responseData = A.JSON.parse(response[0].responseText);
          return responseData;
        };

        $.each(fields, function (index, field) {

          var valueInput = A.one(field);
          var queryTemplate = function (query) {
            var output = '&' + namespace + 'keywords=' + query;
            return output;
          };

          var autocompleteList = new A.AutoCompleteList({
            inputNode: valueInput,
            resultHighlighter: "phraseMatch",
            render: true,
            source: dataSource,
            requestTemplate: queryTemplate,
            resultListLocator: searchLocator,
            queryDelay: 200
          });

          autocompleteList.on("select", function (data) {
            valueInput.val(data.result.raw);
            if (onSelect !== undefined) {
              onSelect(data.result.raw);
            }
          });

          autocompleteList.on("clear", function (data) {
            valueInput.val("");
          });
        });
      }
  );
}
