/*
Cuidado: - Que el nombre de instancia no sea igual al nombre del formulario html!

VERSION 2.0 (06/03/2007)
========================
- Trabaja sobre las especificaciones W3C, que establece como correcto .getElementById().
- El prefijo 'TV' en el nombre de las funciones significa Trasferir Valor.

VERSION 2.1 (08/03/2007)
========================
- Validación por Enter (en realidad es capaz de devolver cualquier tecla presionada).
- Hace focus en el primer elemento que contenga error.
- Se pueden agrupar elementos a través de la function ControlarGrupo; esto sirve, por ejemplo, para decir que "al menos X de los datos de contacto
  son obligatorios.
  
VERSION 2.2 (12/03/2007)
========================
- Agregué TVImage.
- Agregué marca (para la marquita del alert).
- Todos las frases se gestionan con una sola función: ArmarStrError().
- Adapté 'mínimo' tanto para IE como para Mozilla.
- Solucioné el bug de los TVCheck.
- Agregué la función init(), que asigna a cada elemento el número de orden interno.
  
  Curiosidad: conviene no ponerle atributo name al bt de envío, porque en Mozilla no funciona...
  
VERSION 2.3 (14/03/2007)
========================
- Agregué LlenarCombo y VaciarCombo.

VERSION 2.4 (14/03/2007)
========================
- Agregue la función SetFocusAddEvent() porque descubrí que al utilzar el acordeón de Yahoo se eliminar el manejo del focus en Firefox.
- ATENCION! Los elementos button DEBEN tener id.

VERSION 2.5 (12/06/2007)
========================
- Agregue la función SetFocus() y getElement.

VERSION 2.6 (27/06/2007)
========================
- Conseguí esta función que traba el submit desde la tecla Enter. Debe ser colocada directamente en el documento:

function StopEnterKey(evt) {
	var evt  = (evt) ? evt : ((event) ? event : null);
	var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
	if ((evt.keyCode == 13) && (node.type == "text")) {
		return false;
	}
}
document.onkeypress = StopEnterKey;

- Se puede agregar dentro del if algo como alert(formulario.rotulacion_alert['no_enter_key']); para personalizar el mensaje.
- Esta función rige para todos los formularios del site.

*/
Formulario = function(id_form, idioma, marca) {
	this.form                  = document.getElementById(id_form);
	var idioma_form            = (idioma == undefined) ? 'es' : idioma;
	this.cnt_errores           = 0;
	this.marca                 = (marca != undefined) ? marca : '-';
	this.DetectKey             = DetectKey;
	this.rotulacion_alert      = RotularAlert(idioma_form);
	this.obligatorios          = new Array();
	this.ArmarStrError         = ArmarStrError;
	this.init                  = init;
	this.in_array              = in_array;
	this.SetFocusAddEvent      = SetFocusAddEvent;
	this.SetFocus              = SetFocus;
	this.getElement            = getElement;
	// Funciones de asignación
	this.LlenarCombo           = LlenarCombo;
	this.VaciarCombo           = VaciarCombo;
	this.TVInput               = TVInput;
	this.TVSelectOne           = TVSelectOne;
	this.TVSelectMult          = TVSelectMult;
	this.TVCheckBoxGroup       = TVCheckBoxGroup;
	this.TVRadioGroup          = TVRadioGroup;
	this.TVImage               = TVImage;
	// Funciones de verificación
	this.RevisarInput          = RevisarInput;
	this.RevisarSelectOne      = RevisarSelectOne;
	this.RevisarSelectMult     = RevisarSelectMult;
	this.RevisarCheckBox       = RevisarCheckBox;
	this.RevisarRadio          = RevisarRadio;
	this.RevisarEmail          = RevisarEmail;
	this.ControlarGrupo        = ControlarGrupo;
	this.ControlarObligatorios = ControlarObligatorios;
	// Funciones de envío / limpieza
	this.Validar               = Validar;
	this.Limpiar               = Limpiar;
	this.init();

	function init() {
		var len_form     = this.form.elements.length;
		i                = 0;
		do {
			var elemento = this.form.elements[i];
			if(document.all) {
				elemento.orden = i;
			} else {
				elemento.setAttribute('orden', i);
			}
			this.SetFocusAddEvent(elemento.id);
			i++;
		} while (i < len_form);
	}
	function SetFocus(id) {
		var elemento = this.getElement(id);
		if(elemento) {
			elemento.focus();
			return true;
		}
		return false;
	}
	
	function SetFocusAddEvent(id_elemento, boolOnClick) {
		var elemento = document.getElementById(id_elemento);
		if(elemento.type == "text" || elemento.type == "textarea" || elemento.type == "password") {
			var boolOnClick = (boolOnClick == undefined) ? true : false;
			if(boolOnClick) {
				elemento.onmouseup = function() {
					elemento.focus();
				}
			} else {
				elemento.onmouseup = null;
			}
		}
	}
	
	function getElement(id) {
		var elemento = this.form.elements[id];
		return elemento;
	}
	//////////////////////////////////////
	//////// FUNCIONES DE ENVIO //////////
	//////////////////////////////////////
	function Validar(confirmar) {
		var confirmar  = (confirmar == undefined) ? false : confirmar;
		var confirmado = true;
		if(confirmar) {
			if(!confirm(this.rotulacion_alert['confirma_envio'])) {
				confirmado = false;
			}
		}
		if(confirmado == true) {
			this.form.submit();
			return true;
		}
		return false;
	}
	function Limpiar() {
		if(confirm(this.rotulacion_alert['confirma_limp'])) {
			this.form.reset();
			return true;
		}
		return false;
	}
	
	//////////////////////////////////////
	////// FUNCIONES DE ASIGNACION ///////
	//////////////////////////////////////
	function DetectKey(e) {
		var key = (document.all) ? e.keyCode : e.which;
		return key;
	}
	
	function in_array(value, arr_valores, casesensitive) {
		var casesensitive = (casesensitive == undefined) ? false : true;
		var igualdad      = (casesensitive) ? '===' : '==';
		var comparacion   = 'arr_valores[ind] ' + igualdad + ' value';
		for(ind=0; ind<arr_valores.length; ind++) {
			if(eval(comparacion)) {
				return ind;
			}
		}
		return false;
	}
	
	function LlenarCombo(id_combo_dst, arr_valores) {
		var len              = arr_valores.length;
		var elemento         = this.getElement(id_combo_dst);
		if(elemento) {
			for(var i=0; i<len; i++) {
				elemento.options[i] = arr_valores[i];
			}
			return true;
		}
		return false;
	}
	
	function VaciarCombo(id_combo_dst) {
		var elemento             = this.getElement(id_combo_dst);
		if(elemento) {
			var len              = elemento.options.length;
			var ns               = (navigator.appName == "Netscape")
			for(var i=len-1; i>=0; i--) { 
				 if(ns){
					elemento.options[i] = null;
				} else {
					elemento.remove(i);
				}
			}
			return true;
		}
		return false;
	}
	
	function TVInput(id_input, valor) {
		var elemento         = this.getElement(id_input);
		if(elemento) {
			elemento.value   = valor;
			return true;
		}
		return false;
	}
	function TVSelectOne(id_combo, valor) {
		var elemento       = this.getElement(id_combo);
		if(elemento) {
			var len        = elemento.options.length;
			for(var i=0; i<len; i++) {
				var value  = elemento.options[i].value;
				if(value == valor) {
					elemento.selectedIndex = i;
					break;
				}
			}
			return true;
		}
		return false;
	}
	function TVSelectMult(id_combo, arr_valores) {
		var elemento       = this.getElement(id_combo);
		if(elemento) {
			var len        = elemento.options.length;
			for(var i=0; i<len; i++) {
				var value  = elemento.options[i].value;
				if(this.in_array(value, arr_valores) !== false) {
					elemento.options[i].selected = true;
				}
			}
			return true;
		}
		return false;
	}
	function TVCheckBoxGroup(id_primer_check, arr_valores) {
		var elemento                 = this.getElement(id_primer_check);
		if(elemento) {
			var grupo                = (document.all) ? elemento.grupo : elemento.getAttribute('grupo');
			var orden                = (document.all) ? elemento.orden : elemento.getAttribute('orden');
			var i                    = orden;
			var arr_grupo            = new Array();
			do {
				var elemento         = this.form.elements[i];
				var tmp_grupo        = (document.all) ? elemento.grupo : elemento.getAttribute('grupo');
				var tmp_name         = elemento.name;
				if(tmp_grupo == grupo) {
					arr_grupo.push(tmp_name);
				}
				i++;
			} while (tmp_grupo == grupo);
			var len                  = arr_grupo.length;
			for(j=0; j<len; j++) {
				var name             = arr_grupo[j];
				if(this.in_array(name, arr_valores) !== false) {
					var tmp_elem     = this.form.elements[name];
					tmp_elem.checked = true;
				}
			}
		}
	}
	function TVRadioGroup(id_primer_radio, valor) {
		var name       = this.getElement(id_primer_radio).name;
		var grupo      = this.form.elements[name];
		var len        = grupo.length;
		for(i=0; i<len; i++) {
			var value  = grupo[i].value;
			if(value == valor) {
				grupo[i].checked = true;
				return true;
				break;
			}
		}
		return false;
	}
	function TVImage(id_img, src) {
		document.getElementById(id_img).src = src;
	}
	
	//////////////////////////////////////
	/////// FUNCIONES DE CONTROL /////////
	//////////////////////////////////////
	function RevisarInput(input) {
		var err        = (input.value == '') ? true : false;
		return err;
	}
	function RevisarSelectOne(selectone) {
		var sel        = selectone.selectedIndex;
		sel            = (selectone.size>1) ? sel+1 : sel;
		var err        = (sel <= 0) ? true : false;
		return err;
	}
	function RevisarSelectMult(selectmultiple) {
		var minimo     = (document.all) ? selectmultiple.minimo : selectmultiple.getAttribute('minimo');
		var necesarias = (minimo != undefined) ? minimo : 1;
		var tildadas   = 0;
		var len = selectmultiple.options.length;
		for(j=0; j<len; j++) {
			var selec  = selectmultiple.options[j].selected;
			if(selec == true) {
				tildadas++;
			}
		}
		var err        = (tildadas<necesarias) ? true : false;
		return err;
	}
	function RevisarCheckBox(checkbox) {
		var minimo        = (document.all) ? checkbox.minimo : checkbox.getAttribute('minimo');
		var necesarias    = (minimo != undefined) ? minimo : 1;
		var tildadas      = 0;
		var grupo         = (document.all) ? checkbox.grupo : checkbox.getAttribute('grupo');
		var orden         = (document.all) ? checkbox.orden : checkbox.getAttribute('orden');
		var i             = orden;
		var arr_grupo     = new Array();
		do {
			var elemento  = this.form.elements[i];
			var tmp_grupo = (document.all) ? elemento.grupo : elemento.getAttribute('grupo');
			var tmp_name  = elemento.name;
			if(tmp_grupo == grupo) {
				arr_grupo.push(tmp_name);
			}
			i++;
		} while (tmp_grupo == grupo);
		var len           = arr_grupo.length;
		for(j=0; j<len; j++) {
			var name      = arr_grupo[j];
			if(this.form.elements[name].checked == true) {
				tildadas++;
			}
		}
		var err           = (tildadas<necesarias) ? true : false;
		return err;
	}
	function RevisarRadio(radio) {
		var name       = radio.name;
		var grupo      = this.form.elements[name];
		var len        = grupo.length;
		for(j=0; j<len; j++) {
			var check  = grupo[j].checked;
			if(check == true) {
				return false;
			}
		}
		return true;
	}
	
	function RevisarEmail(id_email) {
		var campo  = this.getElement(id_email);
		if(campo) {
			var email  = campo.value;
			var filter = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/;
			if (!filter.test(email)) {
				alert(this.rotulacion_alert['err_header_2'] + '\n' + this.rotulacion_alert['err_email']);
				campo.focus();
				return true;
			}
		}
		return false;
	}
	function ControlarGrupo(arr_grupo, cnt, alertar) {
		var error        = this.ControlarObligatorios(arr_grupo, false);
		var cnt          = (cnt == undefined) ? 1 : cnt;
		var frase        = (cnt == 1) ? this.rotulacion_alert['ctrl_grupo_sing'] : this.rotulacion_alert['ctrl_grupo_plur'];
		var verificados  = 0;
		var alertar      = (alertar == undefined) ? true : alertar;
		var len          = arr_grupo.length;
		var err_permit   = len-cnt;
		if(error) {
			if(this.cnt_errores > err_permit) {
				if(alertar) {
					var str  = cnt+' '+frase+'\n';
					for(j=0; j<len; j++) {
						str += ('- '+arr_grupo[j]+'\n');
					}
					alert(str);
				}
				return true;
			}
		}
		return false;
	}
	
	function ArmarStrError(elemento, minimo) {
		var indice     = 'err_'+elemento.type;
		var str_return = '';
		str_return    += (this.marca + ' ' + elemento.id + this.rotulacion_alert[indice]);
		str_return    += (minimo != undefined) ? '(' + this.rotulacion_alert['minimo'] + minimo + ')' : '';
		str_return    += '\n';
		return str_return;
	}
	
	///////////////// FUNCION PRINCIPAL
	function ControlarObligatorios(arr_grupo, alertar) { // arr_grupo: exclusivo para el llamado desde la función ControlarGrupo; alertar es un bool para ver si muestro alert
		// Los campos que no tengan ID no entran en el ALL
		var arr_grupo               = (arr_grupo != undefined) ? arr_grupo : null;
		var alertar                 = (alertar == undefined) ? true : alertar;
		var primer_err              = null;
		this.cnt_errores            = 0;
		if(this.in_array('ALL', this.obligatorios) !== false) { // Atajo para que todos sean obligatorios
			this.obligatorios.shift();
			var len_total           = this.form.length;
			for(i=0; i<len_total; i++) {
				var elemento_id     = this.form.elements[i].id;
				if(elemento_id != '') {
					this.obligatorios.push(elemento_id);
				}
			}
		}
		var obligatorios            = (arr_grupo == null) ? this.obligatorios : arr_grupo;
		var len_oblig               = obligatorios.length;
		var str_error               = '';
		for (i=0; i<len_oblig; i++) {
			var elemento            = document.getElementById(obligatorios[i]);
			var tipo                = elemento.type; // type 'image' no es considerada...
			switch (tipo) {
				case 'select-one' :
					var error       = this.RevisarSelectOne(elemento);
					if(error) {
						str_error  += this.ArmarStrError(elemento);
						primer_err  = (primer_err == null) ? elemento.id : primer_err;
						this.cnt_errores++;
					}
					break;
				case 'select-multiple' :
					var error       = this.RevisarSelectMult(elemento);
					if(error) {
						var minimo = (document.all) ? elemento.minimo : elemento.getAttribute('minimo');
						minimo     = (minimo != undefined) ? minimo : 1;
						str_error  += this.ArmarStrError(elemento, minimo);
						primer_err  = (primer_err == null) ? elemento.id : primer_err;
						this.cnt_errores++;
					}
					break;
				case 'checkbox' :
					var error       = this.RevisarCheckBox(elemento);
					if(error) {
						var minimo = (document.all) ? elemento.minimo : elemento.getAttribute('minimo');
						minimo     = (minimo != undefined) ? minimo : 1;
						str_error  += this.ArmarStrError(elemento, minimo);
						primer_err  = (primer_err == null) ? elemento.id : primer_err;
						this.cnt_errores++;
					}
					break;
				case 'radio' :
					var error       = this.RevisarRadio(elemento);
					if(error) {
						str_error  += this.ArmarStrError(elemento);
						primer_err  = (primer_err == null) ? elemento.id : primer_err;
						this.cnt_errores++;
					}
					break;
				default: // 'hidden' || 'text' || 'password' || 'textarea' || 'file'
					var error       = this.RevisarInput(elemento);
					if(error) {
						str_error  += this.ArmarStrError(elemento);
						primer_err  = (primer_err == null) ? elemento.id : primer_err;
						this.cnt_errores++;
					}
					break;
			}
		}
		if(this.cnt_errores>0) {
			if(alertar) {
				alert(this.rotulacion_alert['err_header_1'] + '\n' + str_error);
				this.form.elements[primer_err].focus();
			}
			return true;
		}
		return false;
	}
	///////////////// DEVUELVE UN ARRAY CONTENIENDO LOS ERRORES PARA EL ALERT, DE ACUERDO AL IDIOMA REQUERIDO
	function RotularAlert(idioma) {
		var rotulos                          = new Array();
		// Español:
		rotulos['es']                        = new Array();
		rotulos['es']['err_header_1']        = 'ATENCION. Corrija y reintente el envío: ';
		rotulos['es']['err_hidden']          = ' -> campo oculto sin valor. ';
		rotulos['es']['err_text']            = ' -> campo de texto vacío. ';
		rotulos['es']['err_password']        = ' -> campo de contraseña vacío. ';
		rotulos['es']['err_textarea']        = ' -> área de texto vacía. ';
		rotulos['es']['err_file']            = ' -> archivo sin seleccionar. ';
		rotulos['es']['err_select-one']      = ' -> sin selección. ';
		rotulos['es']['err_select-multiple'] = ' -> no alcanza el mínimo de items seleccionados ';
		rotulos['es']['err_radio']           = ' -> grupo de botones sin selección. ';
		rotulos['es']['err_checkbox']        = ' -> grupo de opciones sin selección ';
		rotulos['es']['minimo']              = 'mínimo ';
		rotulos['es']['err_header_2']        = 'ATENCION. Error en la dirección de eMail. ';
		rotulos['es']['err_email']           = 'La dirección de eMail no es correcta. Por favor verifique y reintente el envío. Para colocar "@", pulse Alt+64. ';
		rotulos['es']['confirma_envio']      = 'Está a punto de enviar la información. Por favor verifique que sea correcta. "Aceptar" para continuar. ';
		rotulos['es']['confirma_limp']       = '¿Desea realmente reiniciar el formulario? Deberá reingresar toda la información. "Aceptar" para continuar. ';
		rotulos['es']['ctrl_grupo_sing']     = ' de estos elementos debe ser completado: ';
		rotulos['es']['ctrl_grupo_plur']     = ' de estos elementos deben ser completados: ';
		rotulos['es']['no_enter_key']        = 'Este formulario no puede validarse usando la tecla "Enter". Para enviar utilice el botón de envío.';
		/////
		return rotulos[idioma];
	}

}

