﻿var interactivity = (function ($) {
  var FORM_ID_LENGTH = 10;
  var IN_PROGRESS_DEFAULT_TEXT = 'In progress...';
  var options = {
    onApplyErrorList: function (form, errorList) { },
    onFormSubmitted: function (form) { },
    onSpinningStopped: function (form) { }
  };

  function submitForm(sender) {
    var action = $(sender).attr('action');
    if (action == '') action = window.location.href;
    var formId = $(sender).attr('id');
    var serializedForm = $(sender).serializeArray();

    if ($(sender).hasClass('submitting')) { return; }
    if ($(sender).find('input.confirmation').length > 0 && !confirm(encodeCStr($(sender).find('input.confirmation').val()))) { return; }

    $(sender).addClass('submitting');

    if (!formId) {
      formId = 'form' + generateRandomString(FORM_ID_LENGTH);
      $(sender).attr('id', formId);
    }

    serializedForm.push({ name: 'FormId', value: formId });

    startSpinning(sender);

    $(sender).find('.f-result:visible').hide();

    if ($(sender).hasClass('replaceable')) {
      $.post(action, serializedForm, function (response, status, xhr) {
        if (xhr.getResponseHeader('Content-Type').indexOf('text/javascript') !== -1) {
          //it will be executed automatically by jQuery: eval(xhr.responseText);
        } else {
          $(sender).closest('.content-container').html(response);
        }
      });
    } else {
      $.post(action, serializedForm);
    }

    options.onFormSubmitted(sender);
  }

  function encodeCStr(str) {
    return str.replace('\\n', '\n').replace('\\\'', '\'');
  }

  function generateRandomString(stringLength) {
    var randomString = '';

    for (var i = 0; i < stringLength; i++) {
      randomString += Math.floor(Math.random() * 10);
    }

    return randomString;
  }

  function getAjaxSpinnerElement(elementToReplace) {
    var ajaxSpinner = $('<div class="ajax-spinner">&nbsp;</div>');

    ajaxSpinner.css({
      'width': elementToReplace.width(),
      'height': elementToReplace.height() ? elementToReplace.height() : elementToReplace.css('padding-top'),
      'margin-top': elementToReplace.css('margin-top'),
      //'margin-left': elementToReplace.css('margin-left'),
      'line-height': (elementToReplace.height() ? elementToReplace.height() : elementToReplace.css('padding-top')) + 'px' // -1px so the text looks more aligned to the center
    });

    return ajaxSpinner;
  }

  function isIE() {
    return '\v' == 'v'; //works for ie8 too
  }

  function startSpinning(form) {
    var replaceableSelectors = ['.replaceable', '.f-button-block', '.f-buttons', 'button', 'input[type="submit"]'];
    var elementToReplace;
    var ajaxSpinner;
    var ajaxSpinnerText;
    var sizeContainer; // So the form doesn't flicker while submitting
    var i = 0;

    for (i = 0; i < replaceableSelectors.length; i++) {
      elementToReplace = $(form).find(replaceableSelectors[i]);
      if (elementToReplace.length > 0) { break; }
    }

    if (elementToReplace.length === 0) { return; }

    ajaxSpinner = $(form).find('.ajax-spinner');

    if (ajaxSpinner.length === 0) {
      ajaxSpinner = getAjaxSpinnerElement(elementToReplace);
      sizeContainer = $('<div class="ajax-spinner-container"></div>').css({
        'width': elementToReplace.outerWidth(),
        'height': (elementToReplace.outerHeight() ? elementToReplace.outerHeight() : elementToReplace.css('padding-top')),
        'margin-top': elementToReplace.css('margin-top'),
        'float': elementToReplace.css('display') == 'block' ? elementToReplace.css('float') : 'left',
        'padding-top': elementToReplace.css('padding-top')
      }).hide();
      elementToReplace.after(ajaxSpinner);
      ajaxSpinner.wrap(sizeContainer);
    }

    sizeContainer = ajaxSpinner.parent('div');
    sizeContainer.fadeIn('fast');

    elementToReplace.addClass('hidden-by-loader').hide();

    if ($(form).find('.in-progress-text').length > 0) {
      ajaxSpinnerText = $(form).find('.in-progress-text').val();
    }
    else {
      ajaxSpinnerText = IN_PROGRESS_DEFAULT_TEXT;
    }

    ajaxSpinner.html(ajaxSpinnerText);

    $(':input:visible:not(:disabled)', form).addClass('disabled').attr('disabled', 'disabled');
  }

  function stopSpinning($form) {
    $form.removeClass('submitting');
    $form.find('.ajax-spinner').parent('div').hide();
    $form.find('.hidden-by-loader').removeClass('hidden-by-loader').fadeIn('fast');
    $form.find('.disabled').removeClass('disabled').removeAttr('disabled');
  }

  function stopSpinningAllForms() {
    $('form.submitting').each(function () {
      stopSpinning($(this));
    });
  }

  function applyErrorToAllForms(errorMessage) {
    var tempErrorList = [];

    tempErrorList.push({ FieldName: '', ErrorMessage: errorMessage });

    $('form.submitting').applyErrorList(tempErrorList);
  }

  $.fn.addInteractivity = function (customOptions) {

    options = $.extend(options, customOptions);

    //$(this).each(function () {
    if (this.length > 0 && !$(this).data('isInteractive')) {
      switch (this.get(0).tagName.toLowerCase()) {
        case 'form':
          //          if ($(this).find('input[type="hidden"][name="NextAction"]').length === 0) {
          //            $(this).append('<input type="hidden" name="NextAction" />');
          //          }

          //          $(this).find('button:[value!=""]').bind('click', function () {
          //            var tempInnerHtml = '';
          //            if ($.browser.msie) { tempInnerHtml = $(this).html(); $(this).html(''); }
          //            $(this).closest('form').find('input[type="hidden"][name="NextAction"]').val($(this).val());
          //            if ($.browser.msie) { tempInnerHtml = $(this).html(tempInnerHtml); }
          //          });

          //          $(this).find('button:[value!=""]').bind('click', function () {
          //            $(this).closest('form').find('input[type="hidden"][name="NextAction"]').val($(this).val());
          //          });

          if ($(this).hasClass('f-cancellable')) {
            $(this).bind('keyup', function (e) {
              var code = (e.keyCode ? e.keyCode : e.which);
              if (code == 27) {
                $(this).find('.cancel').click();
              }
            });
          }

          $(this).find(':input.disabled').removeClass('disabled').removeAttr('disabled');

          if ($(this).hasClass('f-ajax')) {
            $(document).bind('ajaxComplete', function (e, xhr, options) {
              // If we aborted the request or got an error or got "No response" status code
              if (xhr.status === 0 || xhr.status >= 400 || xhr.status == 204) {

                applyErrorToAllForms(xhr.statusText);
                stopSpinningAllForms();
              } else {
                $('form.f-ajax').addInteractivity();
              }
            });

            $(this).bind('submit', function () { submitForm(this); return false; });
            $(this).data('isInteractive', true);
          }

          var $firstInput = $(this).find(':input:visible:first');
          if ($firstInput.is(':radio') || $firstInput.is(':checkbox')) {
            $firstInput.focus();
          }
          else {
            $firstInput.select();
          }

          return $(this);
          //break;

        case 'a':
          //break;
          return $(this);
        default:
          //break;
          return $(this);
      }
    }
    //});

    return this;
  };

  $.fn.applyErrorList = function (errorList) {
    $(this).stopSpinning();
    options.onApplyErrorList(this, eval(errorList));
  };

  $.fn.stopSpinning = function () {
    var form = $(this);

    stopSpinning(form);
    options.onSpinningStopped(form);
  };

  $.fn.showFormResult = function (content) {
    var form = $(this);

    stopSpinning(form);
    options.onShowCustomResult(form, content);
  }

  return {

    revertInputValue: function (inputName) {
      var $input = $('input[name="' + inputName + '"]');

      $input.val($input.next('input.original-value').val());

      $input.select();
    }
  };
})(jQuery);

/*
var ErrorList = {
FieldName: '',
ErrorMessage: ''
}
*/
