/**
*
* Example
*
* var f = new form("form1");
* f.bindFields();
* f.setFormHandler( f );
* f.addSelectOrOther( "_1integrante_nivel", "_1integrante_nivel_otro", "Seleccione algo" );
* f.addSimpleValidation( "nombres", "non-empty", "Campo Vacío" );
*

* ------------------------------------------Doc----------------------------------------------
* String form::formId;
* HTMLObject form::form;
* Array form::fields;
* Array form::requiredFields;
* Int form::counter;
* Array form::complexFields;
* Array form::validations;
*
*
* form::form(formId);
* form::submit();
* form::setFormHandler();
* form::addField( field );
* form::addSelectRelation( pSelectId, sSelectId, relTable );
* form::addEdadByDate( fldEdadId, dateId );
* form::bindFields();
* form::showFieldsInfo();
* form::addSelectOrOther( selectId, otherId );
* form::addSelectImage( selectId, imageId, dir );
* form::addSimpleValidation( fieldId, validationType, msg );
* form::addDateField( hiddenFieldId, anoFieldId, mesFieldId, diaFieldId );
* form::validateFields();
* form::validateSimple( validation );

* public form( String formId ); v1.0
*
* Especifica el handler que se encargará de validar el formulario cuando este sea enviado.
* public setFormHandler( form form ); v1.0
*
* Especifica un Campo en form::fields
* private addField( String fieldId ); v1.0
*
* Carga todos los campos en form::fields
* bindFields(); v1.0
*
* Muestra un alert con información de los campos especificados en form::fields
* showFieldsInfo(); v1.0
*
* Convierte un <select> y un <input type="text", en un select con posibilidad de escribir un valor que no esté en el.
* addSelectOrOther( String selectId, String otherId, String msg ); v1.0

*
* Convierte tres radio y un textfield en un yes no other y en other se debe escribir un valor, si así se seleccionó en los radios
* addYesNoOther( String yesId, String noId, String otherId, String msg ); v1.0

*
* Convierte dos listas (<select size="[>1]">) y dos botones en una lista de selección y otra de seleccionados pudiendo pasar datos de una lista a la otra
* addListsSelection( String select1Id, String select2Id, String msg ); v1.0
* addListToList( String fSelect, String tSelect, String btnAddId, String btnDelId, Array selected );

*
* Convierte dos password en un password con verificación.
* addPasswordVerify( String passwordId, String password1Id, String msg ); v1.0

*
* Hace que cuando se seleccione alguna opción del menú, la página sea redirigida al valor del item seleccionado
* addJumpMenu( String selectId, String msg ); v1.0

*
* Define varios checkbox como parte de un grupo esto es para que se l epuedan añadir verificaciones a un checkboxGroup
* addCheckBoxGroup( String selectId, String msg ); v1.0

*
* Añade una validación simple, es considerada una validación simple, si la información se maneja en un solo campo.
* addSimpleValidation( String fieldId, String validationType, String msg ); v1.0
*
* Ejecuta todas las validaciónes
* validateFields(); v1.0
*
* Ejecuta una validación simple
* validateSimple( String validation ); v1.0
*
* Añade una validación compleja, es considerada una validación compleja, si la información se maneja en más de un campo.
* addComplexValidation( String fields, String validationType, String msg ); v1.0
*
* Ejecuta una validacion compleja
* validateComplex()
*
**/
function form( formId ){
	this.formId = formId;
	this.form = document.getElementById( formId );
	this.fields = Array();
	this.requiredFields = Array();
	this.counter = 0;
	this.complexFields = Array();
	this.validations = Array();

	this.submit = function (){
		//Esto existe por que el handler no está quedando
		//alert( "form.js linea 86" );
		if( false == this.validateFields()){
			return false;
		} else {
			this.form.submit();
		}
	}
	this.setFormHandler = function (){
		function hndSubmitForm( event ){
			ret = f.validateFields();
			return (ret)?true:false;
		}
		//	document.getElementById( this.formId ).onchange = hndSubmitForm;
	}

	this.addField = function ( fieldId ) {
		fldOffSet = this.fields.length;
		this.fields[fldOffSet] = document.getElementById( fieldId );
	}
	
	this.addSelectRelation = function ( pSelectId, sSelectId, relTable ) {
		ps = document.getElementById( pSelectId );
		ss = document.getElementById( sSelectId );
		var sonOptions = Array();

		for( i = 1 ; i < ss.options.length ; i++ ){
			sonOptions[ ss.options[i].value ] = ss.options[i].text;
		}
		rtb = Array();
		for( pais in relTable ){
			rtb[pais] = Array();
			for( sonId in relTable[pais] ){
				rtb[pais][sonId] = sonOptions[relTable[pais][sonId]];
			}
		}
		ps.relTb = rtb;
		ps.sonSelectId = ss.id;
		function selHnd( event ){
			document.getElementById(this.sonSelectId).options.length = 0;
			document.getElementById(this.sonSelectId).options[0] = new Option( "Seleccione","0" );
			for( val in this.relTb[this.value] ){
				document.getElementById(this.sonSelectId).options[document.getElementById(this.sonSelectId).options.length] = new Option( this.relTb[this.value][val], val );
			}
		}
		ss.options.length = 0;
		ss.options[0] = new Option( "Seleccione","0" );

		document.getElementById( pSelectId ).onchange = selHnd;
	}


	this.addEdadByDate = function ( fldFechaId, fldEdadId ) {
		
		anoid = fldFechaId + "_ano";
		mesid = fldFechaId + "_mes";
		diaid = fldFechaId + "_dia";
		
		fa = document.getElementById( anoid );
		fm = document.getElementById( mesid );
		fd = document.getElementById( diaid );
		fe = document.getElementById( fldEdadId );
		ff = document.getElementById( fldFechaId );
		fe.readOnly =true;
				
		function ds13sd1f5changeHnd( evt ){
			fe.value = calcular_edad(fa.value + "-" + fm.value + "-" + fd.value );
		}
		ff.onchange = ds13sd1f5changeHnd;
	}

	this.bindFields = function () {
		for(var i = 0 ; i < this.form.elements.length ; i++){
			if( fld = this.form.elements[i].id ){
				this.addField( fld );
			}
		}
	}

	this.showFieldsInfo = function (){
		straux = "";
		for(var i = 0 ; i < this.fields.length ; i++) straux += this.fields[i].name;
		alert( straux );
	}

	this.addSelectOrOther = function ( selectId, otherId ){
		fld = new selectOrOther( selectId, otherId );
	}
	this.addSelectImage = function( selectId, imageId, dir ){
		fld = new selectImage( selectId, imageId, dir );
	}
	this.addDateField = function ( hiddenFieldId, anoFieldId, mesFieldId, diaFieldId ) {
		fld = new dateField( hiddenFieldId, anoFieldId, mesFieldId, diaFieldId );
		return fld;
	}
	this.addListToList = function( fSelect, tSelect, btnAddId, btnDelId, selected ){
		fld = new listToList( fSelect, tSelect, btnAddId, btnDelId, selected );
	}

// ValidationType puede ser ( non-empty | email | number | lenght=# ) para un text
// ValidationType puede ser ( non-select ) para un select
	this.addSimpleValidation = function( fieldId, validationType, msg ) {
		sv = new simpleValidation( fieldId, validationType, msg );
		offSet = this.validations.length;
		this.validations[offSet] = sv;
	}
	
	
	this.validateFields = function(){
		for( var i = 0 ; i < this.validations.length ; i++){
			this.validations[i].execute();
		}
		return true;
	}
}

/**
*
*Aquí se empiezan a definir las clases que manejarán los campos
**/
function listToList( fSelect, tSelect, btnAddId, btnDelId, selected ) {

	fs = document.getElementById( fSelect );
	ts = document.getElementById( tSelect );
	this.ab = document.getElementById( btnAddId );
	this.db = document.getElementById( btnDelId );
	this.ab.fs = fs;
	this.ab.ts = ts;
	this.db.fs = fs;
	this.db.ts = ts;
	//Se seleccionan los elementos pasados en selected
	l = fs.options.length;
	for( i=(l-1) ; i>=0 ; i-- ){
		if( in_array( fs.options[i].value, selected ) ){
			ts.options[ts.options.length] = new Option( fs.options[i].text, fs.options[i].value );
			fs.options[i] = null;
		}
	}
	// Handlers
	function addBtnHnd( event ){
		l = this.fs.options.length;
		for( i=(l-1) ; i>=0 ; i-- ){
			if( this.fs.options[i].selected ){
				this.ts.options[this.ts.options.length] = new Option( this.fs.options[i].text, this.fs.options[i].value );
				this.fs.options[i] = null;
			}
		}
		selectAllListItems(this.ts.id);
	}

	function delBtnHnd( event ){
		l = this.ts.options.length;
		for( i=(l-1) ; i>=0 ; i-- ){
			if( this.ts.options[i].selected ){
				this.fs.options[this.fs.options.length] = new Option( this.ts.options[i].text, this.ts.options[i].value );
				this.ts.options[i] = null;
			}
		}
		selectAllListItems(ts.id);
	}
	document.getElementById( btnAddId ).onclick = addBtnHnd;
	document.getElementById( btnDelId ).onclick = delBtnHnd;

	// Funciones útiles
	function selectAllListItems( selectId ){
		list = document.getElementById( selectId );
		l = list.options.length;
		for( i=0 ; i<l ; i++ ){
			list.options[i].selected = true;
		}
	}

	selectAllListItems(ts.id);
}


function yesNoOther( yesId, noId, otherId ) {
	this.fldType = "yesNoOther";
	this.fldYes = document.getElementById( yesId );
	this.fldNo = document.getElementById( noId );
	this.fldOther = document.getElementById( otherId );
}

function jumpMenu( selectId ) {
	this.fldType = "jumpMenu";
	this.fldMenu = document.getElementById( selectId );
}

function selectImage( selectId, imageId, dir ) {
	this.fldType = "selectImage";
	this.fldMenu = document.getElementById( selectId );
	this.fldImg = document.getElementById( imageId );
	this.fldMenu.imgField = this.fldImg;
	this.dir = dir;

	this.setHandler = function(){
		function selectImageChange( event ){
			if( this.value == 0 ){
				//				alert("Seleccione algo");
			} else {
				this.imgField.src = dir + "/" + this.value;
			}
		}
		this.fldMenu.onchange = selectImageChange;
	}
	this.setHandler();
}
function dateField( hiddenFieldId, anoFieldId, mesFieldId, diaFieldId ) {
	this.hf = document.getElementById( hiddenFieldId );
	this.af = document.getElementById( anoFieldId );
	this.mf = document.getElementById( mesFieldId );
	this.df = document.getElementById( diaFieldId );
	this.af.hfId = hiddenFieldId;
	this.mf.hfId = hiddenFieldId;
	this.df.hfId = hiddenFieldId;
	
	fecha = new String( this.hf.value );
	var ar = fecha.split("-");
	this.af.value = Math.abs(ar[0]);
	this.mf.value = Math.abs(ar[1]);
	this.df.value = Math.abs(ar[2]);
	function updateDate( event ){
		this.hf = document.getElementById( this.hfId );
		this.af = document.getElementById( this.hfId + '_ano' );
		this.mf = document.getElementById( this.hfId + '_mes' );
		this.df = document.getElementById( this.hfId + '_dia' );
		ano = ( this.af.value < 10 ) ? "0" + this.af.value : this.af.value ;
		mes = ( this.mf.value < 10 ) ? "0" + this.mf.value : this.mf.value ;
		dia = ( this.df.value < 10 ) ? "0" + this.df.value : this.df.value ;
		this.hf.value = ano + "-" + mes + "-" + dia;
		if( this.hf.onchange != undefined ) this.hf.onchange();
		
	}
	this.af.onchange = updateDate;
	this.mf.onchange = updateDate;
	this.df.onchange = updateDate;
}

function selectOrOther( selectId, otherId ) {
	this.fldType = "selectOrOther";
	this.fldSelect = document.getElementById( selectId );
	this.fldOther = document.getElementById( otherId );
	this.fldSelect.otherField = this.fldOther;
	this.init = function(){
		this.fldOther.style.visibility="hidden";
		this.fldOther.style.display="none";
	}
	this.setHandler = function(){
		function selectOtherChange( event ){
			if( this.value == 0 ){
				this.otherField.style.visibility="hidden";
				this.otherField.style.display="none";
			} else if( this.value == "other" ){
				this.otherField.style.visibility="visible";
				this.otherField.style.display="block";
				this.otherField.value = "Escriba otro Valor";
				this.otherField.readOnly = false;
				this.otherField.focus();
				this.otherField.select();
			} else {
				this.otherField.style.visibility="hidden";
				this.otherField.style.display="none";
				this.otherField.value = this.value;
				this.otherField.readOnly = true;
			}
		}
		this.fldSelect.onchange = selectOtherChange;
	}
	this.init();
	this.setHandler();
}

function simpleValidation( fieldId, validationType, msg ) {
	this.field = document.getElementById( fieldId );
	this.type = validationType;
	this.msg = msg;
	
	this.execute = function (){
		if( this.field.type == "text" || this.field.type == "textarea" ) {
			switch( this.type ){
				case "non-empty":
				if( this.field.value == "" ){
					alert(this.msg);
					this.field.focus();
					return false;
				}
				break;
				case "number":
				if( isNaN(this.field.value) ){
					alert(this.msg);
					this.field.focus();
					return false;
				}
				break;
				case "email":
				var reg   = new RegExp( /^(.+\@.+\..+)$/ );
				if( !this.field.value.match( reg ) ){
					alert(this.msg);
					this.field.focus();
					return false;
				}
				break;
			}
		} else if ( this.field.type == "select-one" ){
			switch( this.type ){
				case "non-select":
				if( this.field.value == 0 ){
					alert(this.msg);
					this.field.focus();
					return false;
				}
				break;
				}
		}
		return true;
	}
}

function in_array( the_needle, the_haystack ){
	var the_hay = the_haystack.toString();
	if( the_hay == '' ){
		return false;
	}
	var the_pattern = new RegExp( the_needle, 'g' );
	var matched = the_pattern.test( the_haystack );
	return matched;
}
function calcular_edad(fecha){
    hoy=new Date();
    var array_fecha = fecha.split("-")
    if (array_fecha.length!=3) return false
    var ano
    ano = parseInt(array_fecha[0]);
    if (isNaN(ano)) return false
    var mes
    mes = parseInt(array_fecha[1]);
    if (isNaN(mes)) return false
    var dia
    dia = parseInt(array_fecha[2]);
    if (isNaN(dia)) return false
    if (ano<=99) ano +=1900
    edad=hoy.getFullYear()- ano - 1;
    if (hoy.getMonth() + 1 - mes < 0) return edad
    if (hoy.getMonth() + 1 - mes > 0) return edad+1
    if (hoy.getUTCDate() - dia >= 0) return edad + 1
    return edad
}