/**
* form validator extended
*
* Służy do walidowania poszczególnych pól formularza ajaxowo, po zdarzeniu blur.
*
* Ponadto obsługuje ajaxowe wysyłanie całych formularzy.
*
*
* Udostępnia dwa callbacki w przypadku formularzy całkowicie ajaxowych:
* errorInForm(data) => wywoływany, gdy w formularzu był jakiś błąd
* formSuccess(msg) => wywoływany, gdy formularz został poprawnie wysłany. msg to komunikat sukcesu.
*
* Obsługa:
* -> zeby caly formularz byl ajaxowo wysylany: przycisk wysylajacy formularz (submit albo image) powinien miec klase "ar" (ajax-request)
* -> standardowo kazdy form ma ajaxowa walidacje. Zeby wylaczyc, dany form powinien miec klase nav (no-ajax-validation)
* -> jesli sa pola ktore trzeba walidowac jednoczesnie (np. nowe haslo 1 i nowe haslo 2) => wszystkim takim inputom trzeba dac klase compare
*
* Alex: Pomysł, core
* Bartek: Poprawki, rebuild
*
* copyright webcolon 2008
*/

// określa, czy form jest właśnie wysyłany (ma zapobiegać dbl clickom przy ajaxowych formularzach
var formSubmitProcessing = 0;

$(window).load(function() {


	// opcje dla ajaxForma
	var options = {
		target:     'null',
		dataType:   'json',
		beforeSubmit:  prepareForm,
		success:    function(data) {
			formSubmitProcessing = 0;

			if (data.wasError){
				if(window.errorInForm) {
					errorInForm(data);
				}

				$.each(data, function(key){
					updateField(key,data);
				});
			} else {
				if(window.formSuccess) {
					formSuccess(data['msg']);
				} else {
					$('#message').text(data['msg']);
				}
			}
		}
	};
	$(":submit.ar, :image.ar").parents("form").each(function(){
		$(this).ajaxForm(options);
	});


	$("form:not(.nav) input[type!='submit'], form:not(.nav) textarea").blur(handleBlur);
});


/**
* Obsluga blura na inpucie. Wysle zapytanie o walidacje tego inputa do serwera
*/
function handleBlur() {
	var fields = new Array();

	if($(this).val() != '') {
		var input = $(this)
		var fieldName = $(this).attr("name");
		var tsData = '';
		if($(this).is(":checkbox") && !$(this).is(":checked")) {
			// checkboxy niezaznaczone troche inaczej traktujemy :)
			tsData = fieldName+"=-1";
		} else {
			tsData = input.fieldSerialize();
		}

		// jesli trzeba wyslac wiecej niz jedno pole (np. do porownan), to wszystkim trzeba dac klase "compare"
		if($(this).hasClass('compare')) {
			tsData = '';
			$(".compare").each(function() {
				tsData += "&"+$(this).attr("name")+"="+$(this).val();
			});
		}

		var url = '';
		$(this).parents("form").map(function(){
			//url = this.action+'/validate/'+fieldName;
			url = this.action+'?validate='+fieldName;
		});

		if (url !='' && hasChanged(input,fields) && input.attr('value') != input.attr('title')){

			$.ajax({
				async: true,
				type: "POST",
				dataType: "json",
				url: url,
				data: tsData,
				success: function(data){
					updateField(fieldName,data);
				}
			});
		}

	}
}
function updateField(fieldName,data){
	var input = $("#"+fieldName);

	// hack na pola o nazwie z []
	// symfony dla takich helperow daje nazwe x[0] => x_0
	fieldName = fieldName.replace("[", "_").replace("]", "");
	var lab = $("#error_for_"+fieldName);
	if (!$(lab).length){
	}
	if(data.wasError) {
		// cos jest nie tak
		if(data[fieldName] != undefined) {
			lab.text(data[fieldName]).slideDown("fast");
			input.parent().addClass("fieldError");
		}
	} else {
		lab.slideUp("fast", function() {$(this).empty()});
		input.parent().removeClass("fieldError");
	}
}

/**
* "cache" - walidujemy tylko te pola, ktorych wartosc sie zmienila
*/
function hasChanged(input, fields){
	if(input.is(":checkbox")) {
		// nie keszujemy checkboxow
		return true;
	}

	var name = input.attr("name");
	var val = input.val();
	var index = jQuery.inArray(name,fields);

	// czy tresc = title (dla hint plugin)
	if(val == input.attr('title')) {
		return false;
	}

	//nie ma, dodajemy
	if(index==-1){
		var length = fields.length;
		fields[length] = name;
		fields[++length] = val;
	} else { //jest, czy jest taki sam?
		if (fields[index+1]==val){
			return false;
		} else {
			fields[index+1]=val;
		}
	}
	return true;
}


/**
* Wywolywane tuz przed wyslaniem formularza
**/
function prepareForm(formData, jqForm, options){
	if(formSubmitProcessing == 1) {
		// hej, ten formularz juz jest w trakcie wysylania!
		return false;
	} else {
		formSubmitProcessing = 1;
	}
	// przywracamy poprzednim kontenerom stare ID
	$('#activeMessageBox').each(function() {
		var oldID = $(this).attr('oldID');
		if(oldID == undefined) {
			oldID = "_randWRUVP"; // zajebisty hack :D
		}
		$(this).attr('id', oldID);
	});

	// robimy sobie kontenera na reponse
	$(jqForm).find(".message").each(function() {
		var currID = $(this).attr('id');
		$(this).attr('oldID', currID);
		$(this).attr('id', 'activeMessageBox');

	});

	return true;
}
