(function($, undefined){
	$.fn._ajax_form = function(options){
		var defaults = {
			sendPath			: '/',
			type				: 'post',
			dataType			: "html",
			onFocus			: false, //принимаемые значения соответствуют значениям CSS 'display', 'none'=false
			response			: false,
			send_ajax			: true,
			responseContainer	: '.ajaxresponse',
			responseClear		: false,
			responseTarget		: 'body',
			before			: function(){},
			success			: function(){},
			callBack			: function(){}
		};
		if (options === undefined || options.sendPath === undefined){
			var sendPath = $(this).attr("action");
			if (sendPath != ''){
				options = $.extend(options, {
					sendPath : sendPath
				});
			}
		}
		var options = $.extend(defaults, options);

		return this.each(function(){
			options.before.call(this);
			var form = $(this),
			elementsToFind = ['textarea', 'select', 'input:text', 'input:hidden', 'input:password'],
			send = {
				formElements	: [],
				validationError: false,
				button		: form.find('input:submit, button:submit'),
				datastring	: ''
			};
			$.each(elementsToFind, function(i, value){
				var elements = form.find(value);
				if (elements.length > 0){
					elements.bind('change', checkElement);
					if (options.onFocus && options.onFocus != 'none'){
						if (options.onFocus === true) options.onFocus = 'block';
						elements.bind('focusin', focusInElement);
						elements.bind('focusout', focusOutElement);
					}
					send.formElements.push(elements);
				}
			});
			send.button.bind('click', checkElementsToSend);
			function send_ajax_form() {
				var success = false;
				$.ajax({
					type		: options.type,
					dataType	: options.dataType,
					beforeSend : function(){
						if (options.responseClear)
							$(options.responseTarget).html('');
					},
					url		: options.sendPath.split('?')[0],
					data		: send.datastring,
					complete	: function(){
						options.callBack.call(this);
					},
					success	: function(response) {
						if (options.response){
							if (options.dataType == 'json'){
								var text = (response.error.length == 0) ? '<div class="message">' + response.message + '</div>' :
								'<div class="error">' + response.error + response.debug + '</div>';
							} else {
								var text = response;
							}

							if (options.responseContainer){
								var content = $("<div/>").addClass(options.responseContainer)
								//.css('display','none')
								.html(text);
							} else
								var content = text;

							$(options.responseTarget).append(content);
						}
						if (options.dataType == 'json') {
							if (response.error.length == 0)
								success = true;
						} else
							success = true;

						if (success){
							$.each (send.formElements, function(i,v) {
								v.each (function(){
									var currentElement = $(this);
									if (currentElement.attr('type') != 'hidden' && currentElement.attr('type') != 'submit')
										currentElement.val('')
										.parent().removeClass('valid');
								});
							});
						}

						if (options.dataType == 'json') {
							if (typeof(response.error) == 'undefined')
								response = {'error' : {}};
							options.success.call(this, form, response);
						} else {
							options.success.call(this);
						}
					}
				});
				return false;
			}
			function checkElementsToSend() {
				// reset validation var and send data
				send.validationError = false;
				send.datastring = 'ajax=1';
				$.each (send.formElements, function(i,v) {
					v.each (function(){
						var currentElement = $(this),
						value = currentElement.val(),
						name = currentElement.attr('name');
						send.datastring  += "&" + name + "=" + value;
						if (currentElement.parent().attr("class").match(/error/)) {
							send.validationError = true;
						}
						currentElement.change();
					});
				});
				form.find('input:checked').each(function(){
					var currentElement = $(this),
					value = currentElement.val(),
					name = currentElement.attr('name');
					send.datastring  += "&" + name + "=" + value;
				});
				if(send.validationError == false){
					if(options.send_ajax){
						send_ajax_form();
						return false;
					}
				} else {
					return false;
				}
			}
			function checkElement() {
				var currentElement = $(this),
				surroundingElement = currentElement.parent();
				var value = currentElement.val(),
				classes = currentElement.attr("class"),
				nomatch = true;
				if(classes.match(/is_empty/i)){
					if(value == '') {
						surroundingElement.removeClass("valid");
						surroundingElement.addClass("error");
						send.validationError = true;
					} else {
						surroundingElement.removeClass("error");
						surroundingElement.addClass("valid");
					}
					nomatch = false;
				}
				if(classes.match(/is_email/i)){
					if(!value.match(/^\w[\w|\.|\-]+@\w[\w|\.|\-]+\.[a-zA-Z]{2,4}$/i)) {
						surroundingElement.removeClass("valid");
						surroundingElement.addClass("error");
						send.validationError = true;
					} else {
						surroundingElement.removeClass("error");
						surroundingElement.addClass("valid");
					}
					nomatch = false;
				}
				if(classes.match(/is_phone/i)){
					var min_max = classes.match(/is_phone[-\d+?]*/i)[0].replace(/is_phone[-]*/i, '').split('-', 2),
					phone_default = ['7', '11'];
					value = value.replace(/[^0-9]/g, ''),
					min_max = _remove_empty(min_max),
					phone_default = $.extend(phone_default, min_max);
					if (classes.match(/is_empty/i) && value == '') {
						surroundingElement.removeClass("valid");
						surroundingElement.addClass("error");
						send.validationError = true;
					} else if (value != '' && value.length < parseInt(phone_default[0]) || value.length > parseInt(phone_default[1])){
						surroundingElement.removeClass("valid");
						surroundingElement.addClass("error");
						send.validationError = true;
					} else {
						surroundingElement.removeClass("error");
						surroundingElement.addClass("valid");
					}
					currentElement.val(value);
					nomatch = false;
				}
				if(nomatch && value != '' && currentElement.attr('type') != 'submit'){
					surroundingElement.addClass("valid");
				}
			}
			function focusInElement() {
				$(this).parent().find('.onfocus').css('display', options.onFocus);
			}
			function focusOutElement() {
				$(this).parent().find('.onfocus').css('display', 'none');
			}
			function _remove_empty (someArray){
				var newArray = [];
				var element;
				$.each(someArray, function(element){
					if(someArray[element]!='') {
						newArray.push(someArray[element]);
					}
				});
				return newArray;
			}
		});
	}
})(jQuery);
