var VALIDATOR_IN_DEBUG_MODE = false;
var gValidator = new Object;

function Rule(fieldName, pattern, flags, message) {
	this.field   = '';
	this.pattern = '';
	this.flags   = '';
	this.msg     = 'El campo [field] no debe quedar vacio';
	if (('undefined' != typeof(fieldName)) || (null != fieldName)) {
		this.field = fieldName;
	}
	if (('undefined' != typeof(pattern)) || (null != pattern)) {
		this.pattern = pattern;
	}
	if (('undefined' != typeof(flags)) || (null != flags)) {
		this.flags = flags;
	}
	if (('undefined' != typeof(message)) || (null != message)) {
		this.msg = message;
	}
	
	this.message = function(field) {
			if ('undefined' == typeof(field) || null == field) {
				field = '';
			}
			return this.msg.replace(/\[field\]/, field);
		}
}

/**
 * Not empty.
 */
gValidator.VALID_NOT_EMPTY = '.+';

/**
 * Phone number (8-16 digits)
 */
gValidator.VALID_PHONE_NUMBER = '^[-+]?\\b[0-9]{8,16}$';

/**
 * Integers Numbers [0-9] only.
 */
gValidator.VALID_INTEGER_NUMBER = '^[-+]?\\b[0-9]*$';

/**
 * Decimal numbers [0-9][.[0-9]] only.
 */
gValidator.VALID_DECIMAL_NUMBER = '^[-+]?\\b[0-9]*\\.?[0-9]+\\b$';

/**
 * A valid email address.
 */
gValidator.VALID_EMAIL = '^([a-z0-9][a-z0-9_\\-\\.\\+]*)@([a-z0-9][a-z0-9\\.\\-]{0,63}\\.(com|org|net|biz|info|name|net|pro|aero|coop|museum|[a-z]{2,4}))$';

/**
 * A valid year (1000-2999).
 */
gValidator.VALID_YEAR = '^[12][0-9]{3}$';

gValidator.validate = function(form, rules) {
	if (VALIDATOR_IN_DEBUG_MODE) {
		alert('validando el formulario: ' + form.name);
	}
	
	for (var i = 0; i < rules.length; ++i) {
		var r = rules[i];
		if (!gValidator.validateField(r, form)) {
			alert(r.message(r.field));
			return false;
		}
	}
	return true;
}

gValidator.validateField = function(rule, root) {
	var n = null;
	var rg = null;
	var result = false;
	
	rg = new RegExp(rule.pattern);
	
	if (('undefined' == typeof(rg)) || (null == rg)) {
		if (VALIDATOR_IN_DEBUG_MODE) {
			alert('No se pudo crear el objeto RegExp.'
				+ '\npattern: ' + rule.pattern
				+ '\nflags: ' + rule.flags
				+ '\ntipo: ' + typeof(rg));
		}
		return false;
	}
	
	if (VALIDATOR_IN_DEBUG_MODE) {
		alert('buscando tag con nombre: ' + rule.field);
	}
	
	n = searchNodeByName(rule.field, root);
	if (n) {
		if (VALIDATOR_IN_DEBUG_MODE) {
			alert('se encontro tag con nombre: ' + rule.field
				+ '\nValor: ' + n.value);
		}
		
		result = rg.test(n.value);
		if (!result) {
			n.focus();
		}
	}
	return result;
}

var gValidatorOldOnloadFunction = window.onload;
var gRules = new Object();
window.onload = function () {
	var f;
	var forms;
	
	if (VALIDATOR_IN_DEBUG_MODE) {
		alert('Instalando el manejador del formulario');
	}
	
	if ('function' == typeof(gValidatorOldOnloadFunction)) {
		gValidatorOldOnloadFunction();
	}
	
	if ('undefined' == typeof(gRules)) {
		if (VALIDATOR_IN_DEBUG_MODE) {
			alert('No se han definido las reglas a aplicar a los formularios');
		}
		return;
	}
	
	forms = document.getElementsByTagName('form');
	if (forms) {
		if (VALIDATOR_IN_DEBUG_MODE) {
			alert('Formularios encontrados: ' + forms.length);
		}
		
		for (var i = 0; i < forms.length; ++i) {
			f = forms[i];
			if (VALIDATOR_IN_DEBUG_MODE) {
				alert('nombre del formulario: ' + f.name);
			}
			if ('undefined' == typeof(gRules[f.name])) {
				if (VALIDATOR_IN_DEBUG_MODE) {
					alert('No se definieron reglas para el formulario: ' + f.name);
				}
			} else {
				forms[i].onsubmit = function () {
						return gValidator.validate(f, gRules[f.name]);
					}
			}
		}
	}
}
//node.selectedIndex.text
//node.value

function searchNodeByName(name, node) {
	if (name == node.name) {
		return node;
	}
	
	var f = null;
	for (var n = node.firstChild; n != null; n = n.nextSibling) {
		f = searchNodeByName(name, n);
		if (f) {
			break;
		}
	}
	return f;
}

