
/**
* Requiere que se defina el mensaje de error en el atributo "title" de cada campo a ser validado
* Se debe asignar el tipo de validación en el atributo class del elemento a validar
*/
jQuery.fn.validacion = function() {

        var no_validados = new Array();
        var clase_error = "errorForm";
        var clases = new Array("vrequerido","vemail","vnumero","valfa","valfanumerico","vdecimal","vunosolo","vfecha");
        var avisos = new Array("es","en");
        avisos["es"] = new Array("Es un campo requerido","No es una dirección de correo válida","Debe estar formado solamente por dígitos","Debe estar formado solamente por letras","Debe estar formado por letras y números","Debe estar formado por un valor entero o decimal utilizando la coma como separador de decimales","Tienes que seleccionar uno o más valores en una única opción.");
        var title = true; // Debe o no enseñar la etiqueta title como parte del error        
        var form_actual = "";
		var tipo = "despues";
		var alerta = false;
		var alerta_string = "";
		var idm = jQuery("html").attr("lang");
		var idioma = "es";
		if (avisos[idm]) {
			idioma = idm;
		}

        return this.each(function() {
			form_actual = this;
			jQuery(this).submit(function() {
				tipo = $(this).hasClass("vantes") ? "antes" : "despues";				
				alerta = $(this).hasClass("valerta") ? true : false;	
				alerta_string = "";
				limpiarFormulario(this);
				no_validados = new Array();
				var buscados = buscaElementos(this);
				if (buscados==false) {
					if (alerta) {
						alert(alerta_string);
					}
					return false;
				} else {
					return true;
				}
			});
        });

        function buscaElementos(form) {
			$.each(clases,function(pos, clase) { 
				jQuery("."+clase, form).each(function() { 
					var elemento = this;
					if (validar(elemento, clase, pos)==false) {
						no_validados.push(elemento.name);
					}
				});
			});
			return (no_validados.length>0) ? false : true;
        };

        function limpiarFormulario(form) {
                jQuery("div ."+clase_error,form.elements).remove();
        };

        function avisarError(elemento, pos_tipo) {
        		var aviso = avisos[idioma][pos_tipo];
                var descripcion = (elemento.title && title) ? elemento.title : aviso;                
                var id = elemento.id ? elemento.id : elemento.name;
                var id_insercion = id+"-error";
                if (jQuery("#"+id_insercion).attr("class")==clase_error) {
                } else if (!alerta) {
                        var insercion = "<div class=\""+clase_error+"\" id=\""+id_insercion+"\">"+descripcion+"</div>";
						tipo=="despues" ? jQuery(elemento).after(insercion) : jQuery(elemento).before(insercion);
                }
                if (alerta) {                	
                	alerta_string = alerta_string ? alerta_string+"\n"+descripcion : descripcion;
                } else {
                	jQuery("#"+id_insercion).fadeIn("slow");
                }
        };
        
        function in_array(needle, haystack, strict) {
            var found = false, key, strict = !!strict;
            for (key in haystack) {
                if ((strict && haystack[key] === needle) || (!strict && haystack[key] == needle)) {
                    found = true;
                    break;
                }
            }
            return found;
        }

        function validar(elemento, tipo, pos_tipo) {
        		if (!in_array(jQuery(elemento).attr("name"), no_validados)) {
	                var v_elemento = jQuery(elemento).val();
	                var dev = true;
	                if (typeof v_elemento=="undefined" || v_elemento==null) {
	                		v_elemento = "";
	                }
	                if (!isArray(v_elemento)) {
	                        v_elemento = new Array (v_elemento);
	                } else {
	                        if (v_elemento.length==0) {
	                                if (!validarValor(elemento, tipo, pos_tipo, "")) {
	                                        dev = false;
	                                }
	                        }
	                }
	                for (var i=0; i<v_elemento.length; i++) {
	                        if (!validarValor(elemento, tipo, pos_tipo, v_elemento[i])) {
	                                dev = false;
	                        }
	                }
	                return dev;
                } else {
                	return true;
                }
        };

        function validarValor(elemento, tipo, pos_tipo, valor) {
	        	if ((jQuery(elemento).attr("type")=="radio" || jQuery(elemento).attr("type")=="checkbox") && tipo=="vrequerido") {
	            	if (!(jQuery(":"+jQuery(elemento).attr("type")+"[name='"+jQuery(elemento).attr("name")+"']:checked").length)) {
	            		avisarError(elemento, pos_tipo);
	            		return false;
	            	} else {
	            		return true;
	            	}
	            } else {
	                if (eval(tipo+"(valor)")==false) {
	                        avisarError(elemento, pos_tipo);
	                        return false;
	                } else {
	                        return true;
	                }
	            }
        };

        function valfa (valor) {
                return (vrequerido(valor)==false) ? true : evaluar(valor, "^[0-9]+$");
        };

        function valfanumerico(valor) {
                return (vrequerido(valor)==false) ? true : evaluar(valor, "^[a-zA-Z]+$");
        };

        function vnumero(valor) {
                return (vrequerido(valor)==false) ? true : evaluar(valor, "^[0-9]+$");
        };

        function vdecimal(valor) {
                return (vrequerido(valor)==false) ? true : evaluar(valor, "^[0-9\,]+$");
        };

        function vrequerido (valor) {
                return !evaluar(valor, /^\s*$/);
        };

        function vemail(valor) {
                return (vrequerido(valor)==false) ? true : evaluar(valor, "^[a-z0-9]+([_\\.-][a-z0-9]+)*"+"@([a-z0-9]+([\.-][a-z0-9]{1,})+)*$");
        };
		
		function vfecha(valor) {
			return (vrequerido(valor)==false) ? true: evaluar(valor, "^[0-9\,]{2}/[0-9\,]{2}/[0-9\,]{4}$");
		}

        function vunosolo(valor) {
                var cant = 0;
                jQuery(".vunosolo",form_actual).each(function() {
                        var texto = jQuery(this).val();
                        cant = (texto.search(/^\s*$/)>-1!=false) ? cant : cant+1;
                });
                return cant==1 ? true : false;
        };
        
        function evaluar(valor, expresion) {
                return valor.search(expresion)>-1 ? true : false;
        };

        function isArray(obj) {
                if (obj.constructor.toString().indexOf("Array") == -1) {
                        return false;
                } else {
                        return true;
                }
        };
};

jQuery(function($) {
	$("form").validacion();
});
