$(function() {
  var autosave_timeout_id = null;
  if ($('form[data-has-draft]').length == 1) {
    var last_auto_save = $('form[data-has-draft]').serialize();
    function autosave() {
      var $form = $('form[data-has-draft]');
      if ($form.hasClass('disabled-during-submit')) return;
      var new_auto_save = $form.serialize();
      if (last_auto_save == new_auto_save) {
        autosave_timeout_id = window.setTimeout(autosave, 5000);
        return;
      }
      $.ajax({
        type: 'POST',
        url: window.location.pathname + 'autosave',
        data: new_auto_save,
        success: function(json) {
          if (json.result == 'success') {
            last_auto_save = new_auto_save;
          }
        },
        complete: function() {
          autosave_timeout_id = window.setTimeout(autosave, 5000);
        }
      });
    }
    autosave_timeout_id = window.setTimeout(autosave, 5000);
    $('#tracking-code a').on('click', autosave);
    $(document).on('wcs:set-last-auto-save', function() {
      last_auto_save = $('form[data-has-draft]').serialize();
    });
  }
  $('.date-pick').each(function() {
    var $date_input = $(this);
    var options = Object();
    options.autoclose = true;
    options.weekStart = 1;
    options.format = $date_input.data('date-format');
    options.minView = $date_input.data('min-view');
    options.startView = $date_input.data('start-view');
    if ($date_input.data('start-date')) options.startDate = $date_input.data('start-date');
    if ($date_input.data('end-date')) options.endDate = $date_input.data('end-date');
    $date_input.datetimepicker(options);
  });
  if ($('.widget-with-error').length && $('.global-errors').length == 0) {
    var first_field_with_error = $($('.widget-with-error')[0]).find('input,textarea,select');
    if (first_field_with_error.length) {
      $(first_field_with_error)[0].focus();
    }
  }
  $(window).bind('pageshow', function(event) {
    $('form').removeClass('disabled-during-submit');
  });
  $('form button').on('click', function(event) {
    if ($(this).hasClass('download')) {
      $(this).parents('form').addClass('download-button-clicked');
    } else {
      $(this).parents('form').removeClass('download-button-clicked');
    }
    return true;
  });
  $('form').on('submit', function(event) {
    var $form = $(this);
    if (autosave_timeout_id) {
      window.clearTimeout(autosave_timeout_id);
    }
    $form.addClass('disabled-during-submit');
    if ($form.hasClass('download-button-clicked')) {
      /* form cannot be disabled for download buttons as the user will stay on
       * the same page; enable it back after a few seconds. */
      setTimeout(function() { $form.removeClass('disabled-during-submit'); }, 3000);
    }
    return true;
  });
  var live_evaluation = null;
  $('form div[data-live-source]').parents('form').on('wcs:change', function(ev, data) {
    if (live_evaluation) {
      live_evaluation.abort();
    }
    var new_data = $(this).serialize();
    if (data && data.modified_field) {
      new_data += '&modified_field_id=' + data.modified_field;
    }
    var live_url = $(this).data('live-url');
    live_evaluation = $.ajax({
      type: 'POST',
      url: live_url,
      dataType: 'json',
      data: new_data,
      headers: {'accept': 'application/json'},
      success: function(json) {
        $.each(json.result, function(key, value) {
          var $widget = $('[data-field-id="' + key + '"]');
          if (value.visible) {
            var was_visible = $widget.is(':visible');
            $widget.css('display', '');
            if ($widget.hasClass('MapWidget') && !was_visible) {
              $widget.find('.qommon-map').trigger('qommon:invalidate');
            }
          } else {
            $widget.hide();
          }
          if (value.items) {
            // replace <select> contents
            var $select = $widget.find('select');
            var current_value = $select.val();
            $select.empty();
            for (var i=0; i<value.items.length; i++) {
              var $option = $('<option></option>', {value: value.items[i].id, text: value.items[i].text});
              if (value.items[i].id == current_value) {
                $option.attr('selected', 'selected');
              }
              $option.appendTo($select);
            }
          }
          if (value.content) {
            // replace comment content
            var $widget = $('[data-field-id="' + key + '"]');
            $widget.html(value.content);
          }
          if (value.source_url) {
            // json change of URL
            $widget.find('[data-select2-url]').data('select2-url', value.source_url);
          }
        });
      }
    });
  });
  $('form div[data-live-source] input, form div[data-live-source] select, form div[data-live-source] textarea').on('change input paste wcs:change', function(ev) {
      var modified_field = $(this).parents('[data-field-id]').data('field-id');
      $(this).parents('form').trigger('wcs:change', {modified_field: modified_field});
  });
  $('form div[data-live-source]').parents('form').trigger('wcs:change');

  /* searchable select */
  $('select[data-autocomplete]').each(function(i, elem) {
    var required = $(elem).data('required');
    var options = {
      language: {
        errorLoading: function() { return WCS_I18N.s2_errorloading; },
        noResults: function () { return WCS_I18N.s2_nomatches; },
        inputTooShort: function (input, min) { return WCS_I18N.s2_tooshort; },
        loadingMore: function () { return WCS_I18N.s2_loadmore; },
        searching: function () { return WCS_I18N.s2_searching; }
      }
    };
    options.placeholder = $(elem).find('[data-hint]').data('hint');
    if (!required) {
      if (!options.placeholder) options.placeholder = '...';
      options.allowClear = true;
    }
    $(elem).select2(options);
  });

  /* searchable select using a data source */
  $('select[data-select2-url]').each(function(i, elem) {
    var required = $(elem).data('required');
    // create an additional hidden field to hold the label of the selected
    // option, it is necessary as the server may not have any knowledge of
    // possible options.
    var $input_display_value = $('<input>', {
            type: 'hidden',
            name: $(elem).attr('name') + '_display',
            value: $(elem).data('initial-display-value')
    });
    $input_display_value.insertAfter($(elem));
    var options = {
      minimumInputLength: 1,
      formatResult: function(result) { return result.text; },
      language: {
        errorLoading: function() { return WCS_I18N.s2_errorloading; },
        noResults: function () { return WCS_I18N.s2_nomatches; },
        inputTooShort: function (input, min) { return WCS_I18N.s2_tooshort; },
        loadingMore: function () { return WCS_I18N.s2_loadmore; },
        searching: function () { return WCS_I18N.s2_searching; }
      }
    };
    if (!required) {
      options.placeholder = '...';
      options.allowClear = true;
    }
    options.ajax = {
      delay: 250,
      dataType: 'json',
      data: function(params) {
        return {q: params.term, page_limit: 10};
      },
      processResults: function (data, params) {
        return {results: data.data};
      },
      url: function() {
        var url = $(elem).data('select2-url');
        url = url.replace(/\[var_.+?\]/g, function(match, g1, g2) {
          // compatibility: if there are [var_...] references in the URL
          // replace them by looking for other select fields on the same
          // page.
          var related_select = $('#' + match.slice(1, -1));
          var value_container_id = $(related_select).data('valuecontainerid');
          return $('#' + value_container_id).val() || '';
        });
        return url;
      }
    };
    var select2 = $(elem).select2(options);
    $(elem).on('change', function() {
      // update _display hidden field with selected text
      var text = $(elem).find(':selected').first().text();
      $input_display_value.val(text);
    });
    if ($input_display_value.val()) {
      // if the _display hidden field was created with an initial value take it
      // and create a matching <option> in the real <select> widget, and use it
      // to set select2 initial state.
      var option = $('<option></option>', {value: $(elem).data('value')});
      option.appendTo($(elem));
      option.text($input_display_value.val());
      select2.val($(elem).data('value')).trigger('change');
      $(elem).select2('data', {id: $(elem).data('value'), text: $(elem).data('initial-display-value')});
    }
  });
});
