wpj.formUtils = {
   dateIntervalPicker: function ($from, $to, $callback) {
      $(document).on('click', '[data-' + $from + $to + '] li a', function () {
         var getValue = $(this).data('date'),
            dateVal = new Date(),
            setFromDate = [],
            setToDate = [dateVal.getDate(), dateVal.getMonth() + 1, dateVal.getFullYear()];

         switch (getValue) {
            case 'today':
               setFromDate = [dateVal.getDate(), dateVal.getMonth() + 1, dateVal.getFullYear()];
               break;

            case 'yesterday':
               dateVal.setDate(dateVal.getDate() - 1);
               setFromDate = [dateVal.getDate(), dateVal.getMonth() + 1, dateVal.getFullYear()];
               setToDate = [dateVal.getDate(), dateVal.getMonth() + 1, dateVal.getFullYear()];
               break;

            case 'lastSevenDays':
               var lastWeek = new Date(dateVal.getFullYear(), dateVal.getMonth(), dateVal.getDate() - 7);
               setFromDate = [lastWeek.getDate(), lastWeek.getMonth() + 1, lastWeek.getFullYear()];
               break;

            case 'lastMonth':
               var lastMonth = new Date(dateVal.getFullYear(), dateVal.getMonth(), dateVal.getDate() - 31);
               setFromDate = [lastMonth.getDate(), lastMonth.getMonth() + 1, lastMonth.getFullYear()];
               break;

            case 'lastYear':
               var lastYear = new Date(dateVal.getFullYear() - 1, dateVal.getMonth(), dateVal.getDate());
               setFromDate = [lastYear.getDate(), lastYear.getMonth() + 1, lastYear.getFullYear()];
               break;

            case 'thisWeek':
               var diff = dateVal.getDate() - dateVal.getDay() + (dateVal.getDay() === 0 ? -6 : 1),
                  dateOfWeekStart = new Date(dateVal.setDate(diff));
               setFromDate = [dateOfWeekStart.getDate(), dateOfWeekStart.getMonth() + 1, dateOfWeekStart.getFullYear()];
               break;

            case 'thisMonth':
               var firstDay = new Date(dateVal.getFullYear(), dateVal.getMonth(), 1);
               setFromDate = [firstDay.getDate(), firstDay.getMonth() + 1, firstDay.getFullYear()];
               break;

            case 'thisYear':
               setFromDate = ['1.1', dateVal.getFullYear()];
               break;

            case 'previousWeek':
               var dateValCopy = new Date(dateVal.getTime());
               var diffFrom = dateVal.getDate() + (dateVal.getDay() === 0 ? - 6 : - dateVal.getDay() - 6),
                  diffTo = dateVal.getDate() + (dateVal.getDay() === 0 ? - 1 : - dateVal.getDay()),
                  dateOfWeekStart = new Date(dateVal.setDate(diffFrom)),
                  dateOfWeekEnd = new Date(dateValCopy.setDate(diffTo));

               setFromDate = [dateOfWeekStart.getDate(), dateOfWeekStart.getMonth() + 1, dateOfWeekStart.getFullYear()];
               setToDate = [dateOfWeekEnd.getDate(), dateOfWeekEnd.getMonth() + 1, dateOfWeekEnd.getFullYear()];
               break;

            case 'previousMonth':
               var firstDay = new Date(dateVal.getFullYear(), dateVal.getMonth() - 1, 1),
                  lastDay = new Date(dateVal.getFullYear(), dateVal.getMonth(), 0);
               setFromDate = [firstDay.getDate(), firstDay.getMonth() + 1, firstDay.getFullYear()];
               setToDate = [lastDay.getDate(), lastDay.getMonth() + 1, lastDay.getFullYear()];
               break;

            case 'previousYear':
               var lastYear = new Date(dateVal.getFullYear() - 1, 1, 1);

               setFromDate = ['1.1', lastYear.getFullYear()];
               setToDate = ['31.12', lastYear.getFullYear()];
               break;
         }

         var panel_body = $(this).closest("body");

         panel_body.find('#' + $from).val(setFromDate.join('.'));
         panel_body.find('#' + $to).val(setToDate.join('.')).trigger("change");

         if ($callback) {
            $callback($(this), getValue);
         }

         $(this).closest("div.panel-body").find('#' + $from + ',' + '#' + $to).css({
            '-moz-box-shadow': 'inset 0 0 10px #e5fccd',
            '-webkit-box-shadow': 'inset 0 0 10px #e5fccd',
            'box-shadow': 'inset 0 0 10px #e5fccd',
         });

         setTimeout(function () {
            $('#' + $from + ',' + '#' + $to).removeAttr("style");
         }, 600);
      });
   },
   serializeForm: function ($rootDiv) {
      var data = [];
      $rootDiv.find('[data-filter-type]').each(function () {
         var collectedValues;
         var collectedTextValues = '';

         switch ($(this).data('filter-type')) {
            case 'autocomplete':
               collectedValues = $(this).val();
               collectedTextValues = wpj.formUtils.autocompleteParams($(this));
               break;

            case 'select':
               collectedValues = $(this).children('option:selected').val();
               collectedTextValues = $(this).children('option:selected').text().replace(/(\n|\r\n)/g,'');
               break;

            case 'checkbox':
               collectedValues = $(this).prop("checked");
               break;

            case 'multiselect':
            case 'input':
               collectedValues = $(this).val();
               break;
         }

         data.push({
            name: $(this).attr('name'),
            values: collectedValues,
            textValues: collectedTextValues
         });
      });
      return JSON.stringify(data);
   },
   autocompleteParams: function(element){
      var textArray = [];
      $.each(element.find('option:selected'), function(key, val){
         textArray.push({
            Val: val.value,
            Tex: val.innerText
         });
      });
      return textArray;
   },

   saveForm: function ($rootDiv,storageName) {
      localStorage.setItem(storageName, wpj.formUtils.serializeForm($rootDiv));
   },
   clearForm: function ($rootDiv, storageName) {
      if (localStorage.getItem(storageName)) {
         wpj.formUtils.setValuesTo($rootDiv ,JSON.parse(localStorage.getItem(storageName)), 'clear');
         localStorage.removeItem(storageName);
      } else {
         wpj.formUtils.setValuesTo($rootDiv, $($rootDiv).find('[data-filter-type]'), 'clear');
      }
   },
   loadForm: function($rootDiv, storageName){
      if (localStorage.getItem(storageName)) {
         wpj.formUtils.setValuesTo($rootDiv,JSON.parse(localStorage.getItem(storageName)), 'load');
      }
   },
   setValuesTo: function ($rootDiv,data, mode) {
      $.each(data, function (key, val) {
         var element = $rootDiv.find("[name='" + val.name + "'][data-filter-type]");
         switch (element.data('filter-type')) {
            case 'autocomplete':
               if (mode == 'load') {
                  $.each(val.textValues, function (keyArray, valArray) {
                     element.append('<option value="' + valArray.Val + '">' + valArray.Tex + '</option>');
                     element.find("option[value='" + valArray.Val + "']").attr("selected", "selected");
                  });
               } else {
                  element.val([]);
               }
               break;

            case 'select':
               if (mode == 'load') {
                  element.val(val.values);
               } else {
                  element.prop('selectedIndex', 0);
               }
               break;

            case 'checkbox':
               element.prop('checked', mode == 'load' ? val.values : false);
               break;

            case 'multiselect':
               element.val(mode == 'load' ? val.values : []);
               break;

            case 'input':
               element.val(mode == 'load' ? val.values : '');
               break;
         }
         element.trigger("chosen:updated");
      });
   },

   initFormSave: function ($rootDiv, storageName, save = true, clearCallback = null) {
      if (save) {
         $($rootDiv).on('change','[data-filter-type]',function(){
            wpj.formUtils.saveForm($rootDiv,storageName);
         }).ready(function(){
            wpj.formUtils.loadForm($rootDiv ,storageName);
         });
      }
      $($rootDiv).on('click', '[data-filter-clear-type]',function(e){
         wpj.formUtils.clearForm($rootDiv,storageName);

         if (clearCallback) {
            clearCallback();
         }

         e.preventDefault();
         return true;
      });
   }
};
