(function($) {
	$.fn.formErrorMessage = function(message) {			
		if(message == undefined) return false;				
		$(this).find('div.error-message').remove();
		$(this).find('div.wait-message').remove();
		var $m = $('<div class="jquery-form-error-message">'+ message +'</div>');
		$m.prependTo(this);
		$m.show();				
	};

	$.fn.formMessage = function(message) {
			
			if(message == undefined) return false;				
			$(this).find('div.error-message').remove();
			$(this).find('div.wait-message').remove();
			var $m = $('<div class="jquery-form-message">'+ message +'</div>');
			$m.prependTo(this);
			$m.show();		
			window.setTimeout(function(){$m.fadeOut();}, 10000);
	};
	
	$.fn.formWaitMessage = function(message_loading) {							
		$(this).find('div.error-message').remove();
		$(this).find('div.wait-message').remove();
		var $m = $('<div class="jquery-form-wait-message">'+ message_loading +'</div>');
		$m.prependTo(this);
		$m.show();				
	};
	
	$.fn.elementErrorMessage = function(message) {
		$(this).each(function(){
			if($(this).is('input[type!=checkbox]')) $(this).addClass('error_input').parent().addClass('error');
			var $m = $('<div class="jquery-form-element-error-message">' + message + '<div>');
			$m.insertAfter(this);
			$m.fadeIn();
		});
	};

	$.fn.clearForm = function() {
		$form = $(this);
		$form.find('.jquery-form-message, .jquery-form-error-message, .jquery-form-wait-message, .jquery-form-element-error-message').remove();
			
		$form.find('*').removeClass('error');
		$form.find('*').removeClass('error_input');
	};

	$.fn.submitForm = function(settings) {
			
		var settings = $.extend({
			messages: { 				
					error: 'Error on form filling',
					ok: 'Ok',
					required: 'Field required',
					email: 'Wrong Email',					
					price: 'Wrong Price',
					date: 'Wrong Date',
					numeric: 'Wrong integer',
					form_not_send: 'Error! Form not send',
					not_similar_password: 'Password and repeat password must be similar',
					loading: 'Loading...'
			},
			selector: ''
		}, settings);
		
		var messages = settings.messages;
		
		var re_email = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*\.(\w{2,}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum))$/i;
		
		$.fn.showFormResultMessage = function(message) {
			var $ms = $('<div class="form-result-message">' + message + '</div>').appendTo(this);			
		};

		var ajaxFormSuccess = function(data, $form) {
			if(data.result) {										
				if(data.eval) eval(data.eval);
				
				if(data.show_result) {	
					$form.fadeOut('slow', function(){
						$form.parent().showFormResultMessage(data.message);								   
					});
										
				} else if(data.message) {
					$form.formMessage(data.message);
				}

				if(data.refresh)
					window.location.reload();

				if(data.redirect)
					window.location.href = data.redirect;				
				
			} else {							
				if(data.eval) eval(data.eval);

				if(data.message) {
					$form.formErrorMessage(data.message);
				}
			}
			
			if(data.error_fields!==undefined) {									
					$.each(data.error_fields, function(k,v) {
						$('#'+k).elementErrorMessage(v);
					});				
				
			};
		};

		$(this).each(function() {
						
			var submitAjaxForm = function(){
				var $form = $(this);
				valid = true;
				$form.clearForm();

				$form.find('.required').each(function(i){
					if(!$(this).attr("disabled"))
						if($(this).val()=='' || ($(this).hasClass('isdef') && ($(this).val()=='http://' || $(this).attr("value")==$(this).attr('defaultValue')))) {
							$(this).elementErrorMessage(messages.required);	
							valid = false;
						}
				});


				$form.find('.validate-date').each(function() {
					if(!$(this).hasClass('error_input') && $(this).val()!='' && !$(this).attr("value").match(/\d{1,2}\.\d{1,2}\.\d{4}$/)) {
						$(this).elementErrorMessage(messages.date);	
						valid = false;
					}
				});


				$form.find('.validate-email').each(function() {
					if(!$(this).hasClass('error_input') && $(this).val()!='' && !$(this).attr("value").match(re_email)) {
						$(this).elementErrorMessage(messages.email);	
						valid = false;
					}
				});

				$form.find('.validate-price').each(function() {
					if(!$(this).hasClass('error_input') && !$(this).attr("value").match(/^\d+(\.[\d]{1,2}){0,1}$/)) {
						$(this).elementErrorMessage(messages.price);	
						valid = false;
					}
				});

				$form.find('.validate-integer').each(function() {
					if(!$(this).hasClass('error_input') && $(this).val()!='' && !$(this).val().match(/^\d+$/)) {
						$(this).elementErrorMessage(messages.numeric);
						valid = false;
					}
				});


				if(	!$form.find('.validate-password:first').hasClass('error_input') 
					&&  !$form.find('.validate-password:last').hasClass('error_input') 
					&& $form.find('.validate-password:first').val()!= $form.find('.validate-password:last').val()
				   ) {
					$form.find('.validate-password').elementErrorMessage(messages.not_similar_password);
					valid = false;
				}

				$(this).find('.checkbox-agreement').each(function() {
					if(!$(this).is(':checked')) {
						$form.find('.validate-password:last').elementErrorMessage( messages.check_agreement);
						valid = false;				
					}
				});

				if(valid) {

					$.ajax({
						type: "POST",
						url: $form.attr('action') + '?' + new Date().getTime(),
						data: $form.serialize(),
						dataType: 'json',
						success: function(data) {ajaxFormSuccess(data, $form)},
						error: function() {
							$form.formErrorMessage(messages.form_not_send);
						}
					});
				} else {

				}

				return false;
			};

			if($(this).is('form')) {
				$form = $(this);
				$(this).submit(submitAjaxForm);
			} else {
				$(this).delegate('form' + settings.selector, 'submit', submitAjaxForm);
			}



		});
	};	
})(jQuery);
