/*
Script para validaci?n gen?rica de formularios. v 1.1 13-DIC-2006

DEPENDENCIAS
Necesita la librer?a kinetica.js v 1.0.0 27-SEP-2006 o superior

INSTRUCCIONES
Para hacerla funcionar, el formulario a validar debe tener la id 'formulario',
debe tener un bot?n submit, y los campos deben tener tres atributos extra:
	- tipodato -> numero, texto, email, rut, fecha, etc...
	- obligatorio -> Si es false, el campo s?lo se validar? si hay texto en ?l.
	- msgerror -> el mensaje de error que se emitir? al usuario en caso de que el campo falle la validaci?n.

La validaci?n se hace en el evento 'onsubmit' del formulario y se registra autom?gicamente.
Lo ?nico que se necesita es incluir este archivo y agregar los atributos a los campos que necesiten
ser validados

*/

var errores = Array();
$(document).ready(function() {

	/*VALIDADOR DE TEXTO GENERICO*/
	// * solo valida existencia de texto!
	$("input[@tipodato='texto']").each(function() {
		this.validation = function() {
			var o = $(this);
			if(o.attr("obligatorio") == 'true') {
				if($.trim(o.val()).length == 0) {
					errores.push($(this).attr("msgerror"));
				}
			}
		};
	});

	/*VALIDADOR DE EMAIL*/
	// * valida por expresi?n regular
	$("input[@tipodato='email']").each(function() {
		this.validation = function() {
			var o = $(this);
			var regex = /^(\w|[-])+(\.(\w|[-])+)*@((\[([0-1]?\d?\d|2[0-4]\d|25[0-5])\.([0-1]?\d?\d|2[0-4]\d|25[0-5])\.([0-1]?\d?\d|2[0-4]\d|25[0-5])\.([0-1]?\d?\d|2[0-4]\d|25[0-5])\])|((([a-zA-Z0-9])+(([-])+([a-zA-Z0-9])+)*\.)+([a-zA-Z])+(([-])+([a-zA-Z0-9])+)*))$/;
			if(o.attr("obligatorio") == 'true') {
				if(!regex.test(o.val())) {
					errores.push($(this).attr("msgerror"));
				}
			} else if($.trim(o.val()).length > 0)  {
				if(!regex.test(o.val())) {
					errores.push($(this).attr("msgerror"));
				}
			}
		};
	});

	/*VALIDADOR DE RUT*/
	// * valida por funcion especial + expresion regular (15216626-k)
	$("input[@tipodato='rut']").each(function() {
		this.validation = function() {
			var o = $(this);
			var dvcalc = function (T){var M=0,S=1;for(;T;T=Math.floor(T/10)) S=(S+T%10*(9-M++%6))%11;return S?S-1:'k';};
			var regex = /^[1-9]{1}[0-9]{6,7}[-]{1}[0-9kK]{1}$/;
			var rut = o.val().split("-")[0];
			var dv = o.val().split("-")[1];

			if(o.attr("obligatorio") == 'true') {
				if(!regex.test(o.val())) {
					errores.push($(this).attr("msgerror"));
				} else {
					if(dvcalc(rut) != dv.toLowerCase()) errores.push($(this).attr("msgerror"));
				}
			} else if($.trim(o.val()).length > 0)  {
				if(!regex.test(o.val())) {
					errores.push($(this).attr("msgerror"));
				} else {
					if(dvcalc(rut) != dv.toLowerCase()) errores.push($(this).attr("msgerror"));
				}
			}
		};
	});

	/*VALIDADOR DE NUMEROS*/
	//valida por expresion regular.
	$("input[@tipodato='numero']").each(function() {
		this.validation = function() {
			var o = $(this);
			var regex = /^[0-9.,]+$/;
			if(o.attr("obligatorio") == 'true') {
				if(!regex.test(o.val())) {
					errores.push($(this).attr("msgerror"));
				}
			} else if($.trim(o.val()).length > 0)  {
				if(!regex.test(o.val())) {
					errores.push($(this).attr("msgerror"));
				}
			}
		};
	});

	/*VALIDADOR DE FECHAS*/
	//utiliza expresion regular, considera a?os biciestos en formato dd/mm/yyyy
	$("input[@tipodato='fecha']").each(function() {
		this.validation = function() {
			var o = $(this);
			var regex = /^(((0[1-9]|[12][0-9]|3[01])([-./])(0[13578]|10|12)([-./])(\d{4}))|(([0][1-9]|[12][0-9]|30)([-./])(0[469]|11)([-./])(\d{4}))|((0[1-9]|1[0-9]|2[0-8])([-./])(02)([-./])(\d{4}))|((29)(\.|-|\/)(02)([-./])([02468][048]00))|((29)([-./])(02)([-./])([13579][26]00))|((29)([-./])(02)([-./])([0-9][0-9][0][48]))|((29)([-./])(02)([-./])([0-9][0-9][2468][048]))|((29)([-./])(02)([-./])([0-9][0-9][13579][26])))$/;
			if(o.attr("obligatorio") == 'true') {
				if(!regex.test(o.val())) {
					errores.push($(this).attr("msgerror"));
				}
			} else if($.trim(o.val()).length > 0)  {
				if(!regex.test(o.val())) {
					errores.push($(this).attr("msgerror"));
				}
			}
		};
	});

	/*VALIDADOR PARA COMPARACION*/
	//compara este campo con el valor de otro (especial para re-ingreso de email). debe agregar otro atributo 'objetivo' con el id del otro campo
	$("input[@tipodato='compara']").each(function() {
		this.validation = function() {
			var o = $(this);
			if(o.attr('objetivo').length == 0) { return true; }
			var t = $('#'+o.attr('objetivo'));

			if(o.attr("obligatorio") == 'true') {
				if(o.val() != t.val()) {
					errores.push($(this).attr("msgerror"));
				}
			} else if($.trim(o.val()).length > 0)  {
				if(o.val() != t.val()) {
					errores.push($(this).attr("msgerror"));
				}
			}
		};
	});

	/*VALIDADOR DE SELECTBOXES*/
	//Opciones inv?lidas en el select deben tener valor -1
	$("select").each(function() {
		this.validation = function() {
			var o = $(this);

			if(o.attr("obligatorio") == 'true') {
				if(o.val() == -1) {
					errores.push($(this).attr("msgerror"));
				}
			}
		};
	});



// para textarea (experimental)
$("textarea").each(function() {
		this.validation = function() {
			var o = $(this);
			if(o.attr("obligatorio") == 'true') {
				if(o.val() == "") {
					errores.push($(this).attr("msgerror"));
				}
			}
		};
	});


	/*VALIDADOR DE TAMA?O MAXIMO*/
	//Se debe agregar el atributo limit contenga el numero de car?cteres m?ximos
	$("input[@tipodato='limitmax'], textbox[@tipodato='limitmax']").each(function() {
		this.validation = function() {
			var o = $(this);
			if(o.attr("limit") > 0) {
				if(o.val().length < o.attr("limit")) {
					errores.push($(this).attr("msgerror"));
				}
			}
		};
	});

	$("#formulario").submit(function(){
		$("input, select,textarea",this).each(function(){
			if(this.validation) { this.validation(); }
		});
		if(errores.length > 0) {
			var msg = "Debe corregir los siguientes errores:\n";
			$.each(errores, function(i) {
				msg=msg+"  -"+this+"\n";
			});
			alert(msg);
			errores = Array();
			return false;
		}
		else {
			return true;
		}
	});
});

/*
//pretendo usar esto en un futuro no muy lejano... ;)
Element.prototype.getElementsByNodeType = function(type) {
   var nodes = [];
   var node;
   for(var i = 0; i < this.childNodes.length; i++) {
      node = this.childNodes[i];
      if(node.nodeType == type) nodes.push(node)
      if(node.hasChildNodes()) {
         nodes = nodes.concat(node.getElementsByNodeType(type))
      }
   }
   return nodes;
}
/*
  ELEMENT_NODE       = 1;
  ATTRIBUTE_NODE     = 2;
  TEXT_NODE          = 3;
  CDATA_SECTION_NODE = 4;
  ENTITY_REFERENCE_NODE = 5;
  ENTITY_NODE        = 6;
  PROCESSING_INSTRUCTION_NODE = 7;
  COMMENT_NODE       = 8;
  DOCUMENT_NODE      = 9;
  DOCUMENT_TYPE_NODE = 10;
  DOCUMENT_FRAGMENT_NODE = 11;
  NOTATION_NODE      = 12;
*/
