(function($) {
	$.xForm = function(form, opt) {
		var options = $.extend({}, $.xForm.defaults);
		function set_options(opt) {
			if(typeof(opt)!=='object') opt={};
			options = $.extend(options, opt);
		};


		function check() {
			$().blur();
			passed=true;
			if(options.req!=undefined && options.req!=null && options.req!="") {
				$.each(options.req, function(key,req){
					field_failed = check_field(req);
					if(field_failed[0]==true) {
						field_error(req, field_failed[1]);
						passed=false;
						return false;
					}
				});
			}
			return passed;
		};


		function check_field(req) {
			field_failed=true;
			action_text=options.text_default;
			type=req.TYP;

			field=$(form).find("[name='"+req.NAM+(type=='multiselect' ? '[]':'')+"']");
			if(field.length==0) return [field_failed, action_text];
			if(type==undefined || type=="") type=field.attr('type').toLowerCase();

			switch(type) {
				default:
				case 'text':
					field_failed=(field.length>0 && $.trim(field.val()).length < req.LEN);
					action_text=options.text_wypelnij;
				break;

				case 'email':
					regex = /^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/;
					field_failed=(field.length>0 && !regex.test($.trim(field.val())));
					action_text=options.text_wypelnij;
				break;

				case 'telefon':
					regex = /\.*[0-9]{9,}\.*/;
					tel=$.str_replace([' ','(',')','-',',','.','+'],['','','','','','',''],$.trim(field.val()));
					field_failed=(field.length>0 && !regex.test(tel));
					action_text=options.text_wypelnij;
				break;

				case 'kod':
					regex = /[0-9]{2}-[0-9]{3}/;
					field_failed=(field.length>0 && !regex.test($.trim(field.val())));
					action_text=options.text_wypelnij;
				break;

				case 'data':
					field_failed=($.str_replace(["_","-"], ["",""], $.trim(field.val())).length<8 && req.LEN>0);
					action_text=options.text_wypelnij;
				break;

				case 'int':
					v=$.trim(field.val());
					field_failed=(v.length==0 || v<=0 || isNaN(v) || v%1!=0);
					action_text=options.text_wypelnij;
				break;

				case 'int_zero':
					v=$.trim(field.val());
					field_failed=(v.length==0 || v<0 || isNaN(v) || v%1!=0);
					action_text=options.text_wypelnij;
				break;

				case 'int_negative':
					v=$.trim(field.val());
					field_failed=(v.length==0 || isNaN(v) || v%1!=0);
					action_text=options.text_wypelnij;
				break;

				case 'cena':
				case 'float':
					v=$.trim(field.val());
					field_failed=(v.length==0 || v<=0 || isNaN(v));
					action_text=options.text_wypelnij;
				break;

				case 'float_zero':
					v=$.trim(field.val());
					field_failed=(v.length==0 || v<0 || isNaN(v));
					action_text=options.text_wypelnij;
				break;

				case 'float_negative':
					v=$.trim(field.val());
					field_failed=(v.length==0 || isNaN(v));
					action_text=options.text_wypelnij;
				break;

				case 'checkbox':
					field_failed=($(field).is(':checked')!=true);
					action_text=(field.length==1 ? options.text_zaznacz : options.text_wybierz);
				break;

				case 'radio':
					field_failed=($(field).is(':checked')!=true);
					action_text=options.text_wybierz;
				break;

				case 'select':
					field_failed=($(field).val()=="" || $(field).val()==0);
					action_text=options.text_wybierz;
				break;

				case 'multiselect':
					field_failed=true;
					action_text=options.text_wybierz;
					if(typeof($(field).val())=='object' && $(field).val()!=null) field_failed=($(field).val().length < req.LEN);
				break;

				case 'file':
				case 'image':
					if($("#"+$(field).attr('id')+"_queue").length==1) {
						field_failed=(($("#"+$(field).attr('id')+"_queue div.completed").length + $("#"+$(field).attr('id')+"_db_data input[type='checkbox']:not(:checked)").length) < req.LEN);
						ext_not_passed=false;
					} else {
						file_name=$.trim($("#"+$(field).attr('id')+"_").val());
						ext_not_passed=false;
						ext=file_name.split('.').pop().toLowerCase();
						if(req.EXT!=undefined && req.EXT!="" && file_name.length>0) {
							if($.inArray(ext, req.EXT.split("|"))==-1) ext_not_passed=true;
						}
						field_failed=(file_name.length==0 || ext_not_passed==true);
					}
					action_text=(ext_not_passed==true ? options.text_rozszerzenia.replace("$EXT", req.EXT.replace(new RegExp("\\|", 'g'), ", ").toUpperCase()) : options.text_wybierz);
				break;

				case 'nip':
					nip=$.str_replace([' ','-'],['',''],$.trim(field.val()));
					field_failed=(nip.length!=10 || isNaN(nip) || nip==0);
					action_text=options.text_wypelnij;
				break;

				case 'regon':
					regon=$.str_replace([' ','-'],['',''],$.trim(field.val()));
					field_failed=(regon.length<9 || isNaN(regon) || regon==0);
					action_text=options.text_wypelnij;
				break;

				case 'pesel':
					pesel=$.str_replace([' ','-'],['',''],$.trim(field.val()));
					field_failed=(pesel.length!=11 || isNaN(pesel) || pesel==0);
					action_text=options.text_wypelnij;
				break;
			}

			return [field_failed, action_text];
		};


		function post() {
			if(typeof(SID)=="undefined") { alert("No SID!"); return false; }

			$.ajax({
				url: '/includes/ajax.php?SID='+SID+'&type=form&id='+$(form).attr('id')+(opt.inline_req==1 ? '&inline_req=1':''),
				data: $(form).serialize(),
				type: 'post',
				dataType: opt.response_type,
				cache: false,
				error: function(request) { alert('ServerSide form validation error!'); },
				success: function(response) {
					opt.pending=0;
					if(response.indexOf('<!-- FORM_SUBMIT -->')==-1) {
//						$(form).parent().css('opacity',1);
						$(form).find('.submit').removeClass('button_dis').removeAttr('disabled','disabled');
					}
					if(opt.response_type=='html' && opt.response_target!="") $('#'+opt.response_target).html(response);
				}
			});
		};


		function field_error(req, action_text) {
//			$(form).parent().css('opacity',1);
			$(form).find('.submit').removeClass('button_dis').removeAttr('disabled','disabled');

			if(req.TYP=='multiselect') {
				field=$(form).find("[name='"+req.NAM+"[]']");
			} else {
				field=$(form).find("[name='"+req.NAM+"']");
			}

			if(field.length==0) { alert('Field to validate "'+req.NAM+'" not found in the form!'); return false; }
			if(field.length>1) field=$(form).find("[name='"+req.NAM+"']:first");
			field_label=$(form).find("label[for='"+req.NAM+"'] span").html();

			if(action_text==undefined || action_text=="") {
				check = check_field(req);
				action_text = check[1];
			}

			switch(options.notif) {
				default:
				case 'alert':
					field_label=$("label[for='"+req.NAM+"'] span").html();
					alert_text = (req.LAB!=undefined && req.LAB!="" ? req.LAB.replace("$LABEL",field_label).replace('<b>','').replace('</b>','') : action_text+': '+field_label+'"');
					alert(alert_text);
					field.focus();
				break;

				case 'nice_alert':
					field_label=$("label[for='"+req.NAM+"'] span").html();
					alert_text = (req.LAB!=undefined && req.LAB!="" ? req.LAB.replace("$LABEL",field_label) : action_text+': '+field_label+'"');
					nice_alert(alert_text);
					field.focus();
				break;

				case 'js':
					if(field.length>1) field=$(form).find("[name='"+req.NAM+"']:first");
//					foc=$("#"+$(field).attr('id')+"_focus");
					foc=$("#"+($(field).attr('id')==undefined ? $(field).attr('name'):$(field).attr('id'))+"_focus");

					focus_field=(foc.length==1 ? foc : field);

					if(!on_screen(focus_field)) {
						$.scrollTo(focus_field,250,{offset:-38, easing:'easeOutBack'});
						alert_show_time=275;
					} else {
						field.focus();
						alert_show_time=0;
					}

					NAM_clean=$(focus_field).attr('id')+'_'+req.NAM.replace('[','_').replace(']','_');
					if($("#tip_"+$(focus_field).attr('id')).length==0) {
						span_text = (req.LAB!=undefined && req.LAB!="" ? req.LAB.replace("$LABEL",field_label) : action_text+': "<b>'+field_label+'</b>"');
							var_offsetX=0;
							var_offsetY=6;

							if($(focus_field).attr("type")=="checkbox") {
								var_offsetX=-8;
								var_offsetY=5;
							}


							$(focus_field).poshytip({
								content: 			'<span class="err"></span>'+span_text,
								classNameExtra:	'tip_error',
								showOn: 				'none',
								alignTo: 			'target',
								alignX: 				'inner-left',
								alignY: 				'top',
								offsetX: 			var_offsetX,
								offsetY: 			6,
	/*
								alignX: 				'right',
								alignY: 				'inner-top',
								offsetX: 			6,
								offsetY: 			0,
	*/
							});


//							off=field.offset();
//							second_offset=false;
//							if(off.top==0 || off.left==0) { off=field.parent().offset(); second_offset=true; }
//							$("body").append('<span class="form_error" id="error_'+NAM_clean+'" style="top:'+off.top+'px; left:'+off.left+'px; margin:'+(second_offset==true ? 1 : (field.outerHeight(true)/2-10))+'px 5px 0px '+(options.error_alt_pos==true ? 15 : (field.outerWidth(true)+16))+'px;"><span class="arr"></span><span class="err"></span>'+span_text+'</span>');

//							$("body").append('<span class="form_error" id="error_'+NAM_clean+'" style="display:none"></span>');

							setTimeout(function(){
								$(focus_field).poshytip('show');

								field.addClass('error');
								field.focus();
							},alert_show_time);
						}

						clearTimeout(options.error[NAM_clean]);
						options.error[NAM_clean]=setTimeout(function(){
//							foc=$("#"+$(form).find("[name='"+req.NAM+(req.TYP=='multiselect' ? '[]':'')+"']").attr('id')+"_focus");
							if($(field).attr('id')==undefined) {
								foc=$("#"+$(form).find("[name='"+req.NAM+(req.TYP=='multiselect' ? '[]':'')+"']").attr('name')+"_focus");
							} else {
								foc=$("#"+$(form).find("[name='"+req.NAM+(req.TYP=='multiselect' ? '[]':'')+"']").attr('id')+"_focus");
							}

							focus_field=(foc.length==1 ? foc : $(form).find("[name='"+req.NAM+"']"));

							$(focus_field)
								.poshytip('disable').poshytip('destroy')
								.removeClass('error');
							$('div[id="tip_'+($(focus_field).attr('id'))+'"]').remove();
						}, (req.TIM!=undefined && req.TIM!=0 ? req.TIM: options.error_show_time));
				break;
			}
		};

		set_options(opt);

		var api = {
			check: check,
			post: post,
			field_error: field_error,
			set_options: set_options
		};
		return api;
	};


	$.fn.xForm = function(options, callback) {
		if($(this).data('xForm')) {
			if(opt==='api') {
				return $(this).data('xForm');
			} else {
				$(this).data('xForm').set_options(options);
			}
		} else {
			form_obj=this;
	      var opt = (typeof(options)==='object') ? options:{};
			$("#"+$(this).attr('id')+"_js").remove();
			if(opt.req!=undefined && opt.req!=null && opt.req!="") {
				$.each(opt.req, function(key,req){
					if(req.TYP=='multiselect') {
						field=$(form_obj).find("[name='"+req.NAM+"[]']");
					} else {
						field=$(form_obj).find("[name='"+req.NAM+"']");
					}

					if(field.length>0 && $(form_obj).find("label[for='"+req.NAM+"'] b.req").length==0) $(form_obj).find("label[for='"+req.NAM+"']").append('&nbsp;<b class="req">*</b>');
				});
			}

			$(form_obj).bind("submit", function() {
				if(opt.pending==1) return false;
				if(api.check(opt)==true) {
//					$(this).parent().css('opacity',0.4);
					$(this).find('.submit').addClass('button_dis').attr('disabled','disabled');
					opt.pending=1;
					api.post();
				} else {
					opt.pending=0;
				}
				return false;
			});

			var api = $.xForm(this, opt);
			if(typeof(callback)==='function') callback.call(api);
		}
		return this;
	};


	$.xForm.defaults = {
		notif: 					"js",
		response_type:			"script",
		response_target:		null,
		error_show_time:		1250,
		error_alt_pos:			false,
		text_default: 			"Proszę wypełnić pole",
		text_wypelnij: 		"Wypełnij pole",
		text_zaznacz: 			"Zaznacz pole",
		text_wybierz: 			"Dokonaj wyboru w polu",
		text_rozszerzenia:	"Dozwolone roszerzenia to: <b>$EXT</b> dla pliku w polu",
		error:					Array()
	};
}(jQuery));