(function ($) {
	$.fn.ajaxSubmitExt = function(options) {
		var defaults = {
			dataType: 'json',
			messageTimeout: null,
			messageTimeoutLength: 4000,
			beforeCallback: null,
			successCallback: null,
			errorCallback: null,
			clearForm: true
		};

		var options = $.extend(defaults, options);

		var el = $(this);

		if(jQuery().ajaxForm) {
			var displayMessage = function(message) {
				$(el).find('.displayMessage').slideUp(function() {
					$(this).remove();

					clearTimeout(options.messageTimeout);
				});

				$(el).prepend('<div class="displayMessage" style="display: none;">' + message + '</div>');
				
				if(typeof Cufon == 'function') {
					Cufon.refresh();
				}

				$(el).find('.displayMessage').slideDown(function() {
					options.messageTimeout = setTimeout(function() { $(el).find('.displayMessage').slideUp(function() { $(this).remove(); }); }, options.messageTimeoutLength);
				});
			}

			var preSubmit = function(formData, jqForm, opts) {
				$(el).find('ul.errors').slideUp(function() {
					$(this).remove();
				});

				if(typeof options.beforeCallback == 'function') {
					options.beforeCallback(el);
				}
			}

			var postSubmit = function(response) {
				if(options.dataType == 'json') {
					if(response.status == 1) {
						if(options.clearForm == true) {
							$(el).resetForm();
						}

						if(typeof options.successCallback == 'function') {
							options.successCallback(response, el);
						}
					} else {
						if(response.errors != undefined &&  response.errors != null) {
							var validationErrors = response.errors;

							$(el).find('input:visible,select:visible,textarea:visible').each(function() {
								if($(this).attr('name') != undefined && $(this).attr('name') != null && $(this).attr('name') != '') {
									var inputName = $(this).attr('name');

									if(validationErrors[inputName] != undefined && validationErrors[inputName] != null) {
										var errorString = '<ul class="errors" style="display: none;">';

										for(i in validationErrors[inputName]) {
											errorString = errorString + '<li>' + validationErrors[inputName][i] + '</li>';
										}

										errorString = errorString + '</ul>';

										$(this).after(errorString);
									}
								}
							});

							setTimeout(function() { $(el).find('ul.errors').slideDown(600) }, 250);
						}

						if(typeof options.errorCallback == 'function') {
							options.errorCallback(response, el);
						}
					}

					if(response.message != '' && response.message != undefined) {
						displayMessage(response.message);
					}
					
					if(response.fb_message != '' && response.fb_message != undefined && typeof $.facebox == 'function') {
						$.facebox('<div id="fb_message">' + response.fb_message + '<div style="clear: both;"></div></div>');
					}
				} else if(options.dataType == 'html') {
					if(response.substr(0, 6) == 'error:') {
						var response = response.substr(6);

						if(typeof options.errorCallback == 'function') {
							options.errorCallback(response, el);
						}
					} else {
						if(options.clearForm == true) {
							$(el).resetForm();
						}

						if(typeof options.successCallback == 'function') {
							options.successCallback(response, el);
						}
					}
				}
			}

			$(el).ajaxForm({
				dataType: options.dataType,
				beforeSubmit: function(formData, jqForm, opts) { preSubmit(formData, jqForm, opts); },
				success: function(responseText, statusText) { postSubmit(responseText, statusText); }
			});
		} else {
			if(console) {
				console.log('The jQuery ajaxForm plugin does not exist, this is a required dependency of ajaxSubmitExt');
			}
		}
	}
})(jQuery);

