(function($){
	// Create some defaults, extending them with any options that were provided
	$.fn.intlxform = function(options) {
		var _top  = $(this);

		var settings = {
			'type': 'post',
			'action' : '',
			'showResponse' : true,
			'loadingMessage' : 'Checking data',
			'wrapElem' : '',
			'clearForm': true,
			'fieldRemark' : true,
			'hideForm' : false,
			'onSuccess' : null,
			'onFailure' : null,
			'onError' : null,
			'onFinish' : null,
			'headers': {
				'Accept' : 'application/json; charset=utf-8'
			}
		};

		settings = $.extend(settings, options);


		return this.each(function() {
			if(settings.type.length == 0) {
				if($(this).attr('method') != undefined) {
					settings.type = $(this).attr('method');
				}
			}

			if(settings.action.length == 0) {
				if($(this).attr('action') != undefined) {
					settings.action = $(this).attr('action');
				}
			}

			$(this).submit(function(event){
				event.preventDefault();

				// Abort any pending request
				if (request) {
					request.abort();
				}
				// Setup some local variables
				var $form = $(this);
				// Cache all fields
				var $inputs = $form.find("input, select, button, textarea");
				// Serialize the data in the form
				$inputs.each(function() {
					if($(this).attr('data-defaultValue') != 'undefined') {
						if($(this).attr('data-defaultValue') == $(this).val()) {
							$(this).val('');
						}
					}
				});
				var serializedData = $form.serialize();

				$inputs.each(function() {
					if($(this).attr('data-defaultValue') != 'undefined' && $(this).val() =='') {
						$(this).val($(this).attr('data-defaultValue'));
					}
				});

				// Disable the inputs for the duration of the ajax request
				$inputs.prop("disabled", true);
				$form.find(".form-message").text(settings.loadingMessage);
				$form.addClass('loading');

				// Fire off the request
				var request = $.ajax({
					url: settings.action,
					type: settings.type,
					headers: settings.headers,
					data: serializedData
				});

				// Callback handler that will be called on success
				request.done(function (response, textStatus, jqXHR){
					parseFormResponse(response, $form);
				});

				// callback handler that will be called on failure
				request.fail(function (jqXHR, textStatus, errorThrown){
					if(typeof settings.onFailure == 'function') {
						settings.onFailure.call();
					} else {
						console.error(
							"The following error occured: "+
							textStatus, errorThrown
						);
					}
				});

				// callback handler that will be called regardless
				// if the request failed or succeeded
				request.always(function () {
					// reenable the inputs
					$inputs.prop("disabled", false);
					$form.removeClass('loading');
				});

				// prevent default posting of form
				event.preventDefault();
			});
		})

		function parseFormResponse(response, form) {

			form.find(".form-message").text('');
			form.find(".validation-error").removeClass('validation-error');
			form.find(".validation-error-message").remove();

			// Make sure we have a JSON response
			if(typeof response == "string") {
				try {
					response = JSON.parse(response);
				} catch(e) {
					return false;
				}
			}

			// On error occured
			if(!response.response) {
				for(var fieldName in response.errors) {
					var message = response.errors[fieldName];
					var parent = form.find("[name='data[" + fieldName + "]']").last().parent();

					parent.addClass('validation-error');
					if(settings.fieldRemark == true) {
						parent.append('<div class="validation-error-message">' + message + '</div>');
					}
				}

				setTimeout(function () {
					$('html, body').animate({
						scrollTop: $(".validation-error").offset().top - 100
					}, 1000);
				}, 100);


				// Callback: On error
				if(typeof settings.onError == 'function') {
					settings.onError(response);
				}

				// On Success
			} else {

				// Callback: On success
				if(typeof settings.onSuccess == 'function') {
					settings.onSuccess(response);
				}

				// Clear form
				if(settings.clearForm) {
					form.find("input, select, textarea").not('[type=button], [type=submit], [type=reset], .persistent').val('');
				}
			}

			// Show message, if any
			if(response.message != null && response.message != '' && settings.showResponse) {
				var messageElement = form.find(".form-message");

				messageElement.removeClass('form-message-error').removeClass('form-message-success');
				messageElement.addClass(response.response ? 'form-message-success' : 'form-message-error');
				messageElement.text(response.message).show();
			}

			// Callback: On finish
			if(typeof settings.onFinish == 'function') {
				settings.onFinish(response);
			}
		}
	};
})(jQuery);
