var Forms = {};

Forms.select = {};

/**
 * Construye el codigo HTML de un select.
 * Hay tres formas de pasarle los parametros:
 *  + Con 3 parametros: atributos, objeto_de_valores_y_nombres, valor_del_seleccionado_por_defecto
 *  + Con 4 parametros: atributos, lista_de_valores, lista_de_nombres, valor_del_seleccionado_por_defecto
 *  + Con 5 parametros: atributos, lista_de_objetos, campo_valor, campo_texto, valor_del_seleccionado_por_defecto
 *
 * atributos: atributos del tag select <select [atributos] > <option>...</option> </select>
 * valor_del_seleccionado_por_defecto: atributo value de la opción por defecto
 * primera_opcion: [valor, texto] para la primera opcion (generalmente ['', 'Seleccione: '])
 *
 * objeto_de_valores_y_nombres: un objeto de javascript {a:"hola", b:"chao"}. a y b serán los values, "hola" y "chao" el texto visible.
 * lista_de_valores, lista_de_nombres: pueden ser ["a", "b"], ["hola", "chao"], con el mismo efecto de arriba.
 *
 * lista_de_objetos: por ejemplo [{cod: 'CHI', nom: 'Chile'},{cod: 'ARG', nom: 'Argentina'}]
 * campo_valor: campo de cada objeto que entrega el valor de la opcion ('cod' en este caso)
 * campo_texto: campo de cada objeto que entrega el texto de la opcion ('nom' en este caso)
 */
Forms.select.makeHTML = function(/* ver comentario arriba */) {
	function innerMakeHTML(attrs, values, names, selected) {
		var sel = '<select '+attrs+'">';
		for(var i=0;i<values.length;i++) {
			if(selected && values[i] === selected)
				sel += '<option value="'+values[i]+'" selected>'+names[i]+'</option>';
			else
				sel += '<option value="'+values[i]+'">'+names[i]+'</option>';
		}
		sel += '</select>';

		return sel;
	}

	if(arguments.length == 3) {
		var attrs = arguments[0];
		var values = [];
		var names = [];
		var selected = arguments[2];

		for(var i in arguments[1]) {

			if(!arguments[1].hasOwnProperty(i)) continue;


			values[values.length] = i;
			names[names.length] = arguments[1][i];

		}

		return innerMakeHTML(attrs, values, names, selected);
	}

	else if(arguments.length == 4) {
		return innerMakeHTML(arguments[0], arguments[1], arguments[2], arguments[3]);
	}

	else if(arguments.length == 5) {
		var valores = [];
		var textos = [];
		var lista = arguments[1];
		var atrval = arguments[2];
		var atrtxt = arguments[3];

		for(var i=0;i<lista.length;i++) {
			valores.push(lista[i][atrval]);
			textos.push(lista[i][atrtxt]);
		}

		return innerMakeHTML(arguments[0],valores,textos,arguments[4]);
	}
}

/**
 * Agrega al select pasado de parametro los valores y textos de las listas values y names.
 */
Forms.select.populate = function(select, values, names) {
	for(var i=0;i<values.length;i++) {
		Forms.select.addOption(select, values[i], names[i]);
	}
}

Forms.select.populateFromObjectHash = function(select, objhash, valueField, nameField) {
	var vals = [], texts = [];
	for(var i in objhash) {
		if(!objhash.hasOwnProperty(i)) continue;
		vals.push(objhash[i][valueField]);
		texts.push(objhash[i][nameField]);
	}

	Forms.select.populate(select, vals, texts);
}

Forms.select.populateFromObjectList = function(select, objlist, valueField, nameField) {
	var vals = [], texts = [];
	for(var i=0;i<objlist.length;i++) {
		vals.push(objlist[i][valueField]);
		texts.push(objlist[i][nameField]);
	}

	Forms.select.populate(select, vals, texts);
}

/**
 * Agrega una opcion a un select
 * Dos maneras de usarlo:
 * addOption(sel, opt) agrega al select sel la opción opt (opt es un objeto de tipo Option)
 * addOption(sel, val, name) agrega al select sel una opción con valor val y texto visible name
 */
Forms.select.addOption = function(/*sel, opt | sel, val, name  */) {
	if(arguments.length == 2) {
		var sel = arguments[0];
		var opt = arguments[1];
		sel.options[sel.options.length] = opt;
	}

	else if(arguments.length > 2) {
		var sel = arguments[0];
		var val = arguments[1];
		var name = arguments[2];
		sel.options[sel.options.length] = new Option(name, val);
	}
}
/**
 * Inserta la opcion value con el texto texto al select list id
 * Alerternativa de addOption
 */
Forms.select.insertOption = function(value, text, donde){
    var elSel = document.getElementById(donde);
    var elOptNew = document.createElement('option');
    elOptNew.text = text;
    elOptNew.value = value;
    var elOptOld = elSel.options[elSel.selectedIndex];
    try {
      elSel.add(elOptNew, elOptOld); // standards compliant; doesn't work in IE
    }
    catch(ex) {
      elSel.add(elOptNew, elSel.selectedIndex); // IE only
    }
}


/**
 * Borra la ocion index del select list id
 */
Forms.select.removeOption = function(id, index){
	var x=document.getElementById(id);
	x.remove(index);
}

/*Particular a boreal: crea las opciones de
 * un select Hijo que se liga con uno Padre
 * Presupone que hay dos Entidades en memoria ya
 * La padre y la hija, y que la hija tiene .id<Padre> y .nombre como atributos
 * @selectPadre: selectHTMLObject
 * @selectHijo: selectHTMLObject
 * @entidadPadre: string
 * @entidadHijo: string
 *@atributoLigador:string
 *@idSeleccionado:string
 *@stringNombre
 */

Forms.select.ligar=function(selectPadre,selectHijo,entidadPadre,entidadHijo,atributoLigador,idSeleccionado,stringNombre){
	//alert(selectPadre+" "+selectHijo+" "+entidadPadre+" "+entidadHijo+" "+atributoLigador+" "+idSeleccionado+" "+stringNombre)
	 if (selectPadre.value == "" || selectPadre.value == null || selectPadre.value == undefined) {
	 }
	 else {
	 	//Buscamos las instancias de entidadHijo que contengan a entidadPadre.id:
	 	var hijos = Boreal.contenido.modelo.getList(entidadHijo);
	 	var padres = Boreal.contenido.modelo.getList(entidadPadre);
	 	
		//Limpiamos el select Hijo
		var largo = selectHijo.options.length;
		for (var j = 0; j < largo; j++) {
			selectHijo.options[j] = null;
		}
			
		if(!listaHijos)var listaHijos = new Array();else listaHijos = null;
		 	
		var sE='for (var i = 0; i < hijos.length; i++) \n{\n if (hijos[i].'+atributoLigador+' == selectPadre.value) {\n listaHijos.push(hijos[i]);}}';
		eval(sE);
			
		
		if(listaHijos.length>0){		
			for (var z = 0; z < listaHijos.length+1; z++) {
				if(z==0){
					selectHijo.options[z] = new Option("Seleccione","");
				}else{
					
					var Te='if(listaHijos[z-1].id==idSeleccionado)selectHijo.options[z] = new Option(listaHijos[z-1].'+stringNombre+', listaHijos[z-1].id,true);else selectHijo.options[z] = new Option(listaHijos[z-1].'+stringNombre+', listaHijos[z-1].id);';
					eval(Te);
				}
			}
		}else{
			//alert("Debe inidcar una entidad que tenga relacionados")
			//selectHijo.options[z] = new Option("","");
			Forms.select.clear(selectHijo);
		}
	}
}



/**
 * Selecciona la opcion cuyo valor es value.
 */
Forms.select.selectByValue = function(select, value) {
	for(var i=0;i<select.options.length;i++) {
		if(select.options[i].value == value) {
			select.selectedIndex = i;
			return;
		}
	}
}

/**
 * Selecciona la opción que está en posición index.
 */
Forms.select.selectByIndex = function(select, index) {
	select.selectedIndex = index;
}

/**
 * Devuelve el objeto Option seleccionado actualmente.
 */
Forms.select.getSelectedOption = function(select) {
	return select.options[select.selectedIndex];
}

/**
 * Devuelve el valor seleccionado actualmente.
 */
Forms.select.getSelectedValue = function(select) {
	if(typeof select === 'string') {
		select = document.getElementsByName(select)[0];
	}
	return select.options[select.selectedIndex].value;
}

/**
 * Devuelve el texto (no valor!) seleccionado actualmente.
 */
Forms.select.getSelectedText = function(select) {
	if(typeof select === 'string') {
		select = document.getElementsByName(select)[0];
	}
	return select.options[select.selectedIndex].text;
}


/**
 * Convierte el html de un select en un objeto select
 * @param string html
 */
Forms.select.htmlToObject = function(html) {
	var x = document.createElement('div');
	x.innerHTML = html;
	return x.getElementsByTagName('select')[0];
}

/**
 * Recibe un objeto select y entrega su codigo html
 * @param {Object} sel
 */
Forms.select.objectToHtml = function(sel) {
	var x = document.createElement('div');
	x.appendChild(sel);
	return x.innerHTML;
}


/**
 * Borra todo el select
 */

Forms.select.clearSelect = function (sel) {
    sel.options.length = 0;
}
Forms.select.clear = Forms.select.clearSelect; // Nombre alternativo


Forms.checkbox = {};

/**
 * Toma un arreglo de checkboxes (o el nombre del grupo) y devuelve un objeto
 * que asocia al valor de cada checkbox un boolean (true si estaba checkeado, falso si no)
 */
Forms.checkbox.getHash = function(cbs) {
	if(typeof cbs == 'string') cbs = document.getElementsByName(cbs);

	var n = cbs.length;
	var h = {};
	for(var i=0;i<n;i++) {
		h[ cbs[i].value ] = cbs[i].checked;
	}

	return h;
}

/**
 * Simula un click en el checkbox cuyo valor es val, retorna true si se encontro, falso si no.
 */
Forms.checkbox.clickValue = function(cbs, val) {
	if(typeof cbs == 'string') cbs = document.getElementsByName(cbs);

	var n = cbs.length;
	//console.log(n);
	for(var i=0;i<n;i++) {
		if(cbs[i].value == val) {
			cbs[i].click();
			return true;
		}
	}

	return false;
}

/**
 * Entrega un arreglo de los valores que estan checkeados.
 */
Forms.checkbox.getCheckedValues = function(cbs) {
	if(typeof cbs == 'string') cbs = document.getElementsByName(cbs);

	var n = cbs.length;
	var r = [];
	for(var i=0;i<n;i++) {
		if(cbs[i].checked) {
			r[r.length] = cbs[i].value;
		}
	}

	return r;
}

Forms.radio = {};


/**
 * Obtiene el valor seleccionado de un grupo de radios.
 */
Forms.radio.getSelectedValue = function(nameForm,nameField) {
	/*
	if((typeof(radios)).toLowerCase() == 'string') {
		radios = document.getElementsByName(nameForm)[0][nameField];
	}
	*/
	radios = document.getElementsByName(nameForm)[0][nameField];
	
	var n = radios.length;
	for(var i=0;i<n;i++) {
		if(radios[i].checked) {
			return radios[i].value;
		}
	}
	
	return "";
}


/**
 * Simula un click en un radio
 */
Forms.radio.clickValue = function(radios, val) {
	if((typeof(radios)).toLowerCase() == 'string') {
		radios = document.getElementsByName(radios);
	}

	var n = radios.length;
	for(var i=0;i<n;i++) {
		if(radios[i].value == val) {
			radios[i].click();
			return true;
		}
	}

	return false;
}


Forms.radio.makeHTML=function(attrs, values, names, checked){

	var sel = '';
		for(var i=0;i<values.length;i++) {
			if(values[i] == checked)
				sel += '<input type="radio" '+attrs+'  value="'+values[i]+'" checked >'+names[i];
			else
				sel += '<input type="radio" '+attrs+'  value="'+values[i]+'">'+names[i];
		}
	
	return sel;
	
}


Forms.textfield = {};

/**
 * Extiende un textfield para que tenga memoria.
 *
 * El textfield tendra un arreglo historial que guarda todos los cambios que han ocurrido en el textfield.
 *
 * El textfield tambien tendra una variable 'oficial'. Esto puede ser util en la siguiente situacion:
 * tenemos los datos de una persona en varios textfield. Uno de esos textfield es el rut. Queremos que el
 * usuario pueda modificar el rut. El problema es que si modifica el rut, que es llave primaria, ya no tenemos
 * como ubicar la tupla en base de datos para modificarla. La manera de resolver esto es guardar el rut actual
 * en el campo oficial.
 *
 * makeTextfieldConMemoria manipula el atributo onchange del textfield.
 */
Forms.textfield.makeTextfieldConMemoria = function(tf, oficial) {
	tf.oficial = oficial;
	tf.historial = [tf.value];
	tf.onchange = function() {
		this.historial.push(this.value);
	}
}


/**
 * Retorna la cantidad de campos a excepcion de los hiddens
 */
Forms.getNumElementsSinHidden=function(form){
	
	var num = 0;
	for(var i=0;i<form.elements.length;i++){
		if(form.elements[i].type != "hidden"){
		num++;
		}
	}
	return num;
}

