//Función Trim para javascript
function Trim ( Cadena ){
	return(Cadena.replace(/^\s+/,'').replace(/\s+$/,''));
}

// Sustituye una cadena por otra dentro de una cadena :p
function str_replace(sCadena, sCadenaBuscada, sCadenaSustituta) {
	return sCadena.split(sCadenaBuscada).join(sCadenaSustituta);
}

/*
Regresa true si el mail es valido
regresa true en caso de ser válida y false en caso contrario
*/
function ValidaMail( valor ) {
	var Retorno=true;
	if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(valor)){}
	else {
		alert("La dirección de correo electrónico: " + valor + " es incorrecta.");
		Retorno = false;
	}
	return Retorno;
}

/*
Esta función lo que hace es recibir un componente,y los caracteres permitidos que puede contener , 
con una longitud máxima dada por el argumento máximo, y si este puede o no ir vacío, y por último el el nombre 
del campo por si se requiere enviar mensajes a la pantalla.
Decuelve true en caso de no haber errores y false en caso contrario
*/
function Validador ( Componente, sPermitidos ,iMaxima, bVacio, sNombreDelComponente ){
	var sCadena;
	var bRetorno=true;
	var bPermitido=true;
	var bSigue=true;
	var i,j;
	var Letra;
	
	sCadena=Trim(Componente.value);
	
	
	//Comprobamos que la cadena no esté vacía en caso de que no se pueda
	if ( bVacio != true ){
		if (  sCadena.length == 0 )
		{
			bRetorno=false;
			alert("El campo "+sNombreDelComponente+" no puede estar vacío.");
		}
	}
	
	//Comprobamos que la longitud de la cadena no sea mayor a la longitud Maxima permitida
	if ( bRetorno != false ){
		if ( sCadena.length > iMaxima )
		{
			bRetorno=false;
			alert("El campo "+sNombreDelComponente+" no puede tener mas de " + iMaxima + " caracteres.");
		}
	}
	
	//Comprobamos que sólo contenga letras
	if ( bRetorno != false ){
		for ( i=0; i<sCadena.length && bPermitido==true; i++ ){
			Letra=sCadena.charAt( i );
			for ( j=0; j<sPermitidos.length && bSigue==true; j++){
				if ( Letra==sPermitidos.charAt( j ) ) bSigue=false;
			}
			if ( bSigue==true ) 
				bPermitido=false;
			else 
				bSigue=true;
		}

		if ( bPermitido==false )
		{
			bRetorno=false;
			alert("Se ha introducido el siguiente caracter no permitido: "+Letra + "\n\nEl campo "+sNombreDelComponente+" unicamente puede contener los siguientes caracteres: \n\n"+sPermitidos);
		}

	}
	
	return bRetorno;
}

/*Esta funcion se encarga de revisar que únicamente en valor del componente contenga letras,  con una longitud máxima, si puede o no ir vacío, y
recibe el nombre del campo para enviar los mensajes a pantalla*/
function ValidaLetras ( Componente, iMaxima, bVacio, sNombreDelComponente ){
	var sPermitidos = "ABCDEFGHIJKLMNÑOPQRSTUVWXYZÁÉÍÓÚ" + "abcdefghijklmnñopqrstuvwxyzáéíóú. ";
	return Validador (Componente, sPermitidos ,iMaxima, bVacio, sNombreDelComponente);
}

/*Esta funcion se encarga de revisar que únicamente en valor del componente contenga numeros,  con una longitud máxima, si puede o no ir vacío, y
recibe el nombre del campo para enviar los mensajes a pantalla*/
function ValidaNumeros ( Componente, iMaxima, bVacio, sNombreDelComponente ){
	var sPermitidos = "1234567890";
	return Validador (Componente, sPermitidos ,iMaxima, bVacio, sNombreDelComponente);
}

/*Esta funcion se encarga de revisar que únicamente en valor del componente contenga solo alfanumericos,  con una longitud máxima, si puede o no ir vacío, y
recibe el nombre del campo para enviar los mensajes a pantalla*/
function ValidaAlfanumericos ( Componente, iMaxima, bVacio, sNombreDelComponente ){
	var sPermitidos = "ABCDEFGHIJKLMNÑOPQRSTUVWXYZÁÉÍÓÚ" + "abcdefghijklmnñopqrstuvwxyzáéíóú. " + "1234567890";
	return Validador (Componente, sPermitidos ,iMaxima, bVacio, sNombreDelComponente);
}

function ValidaAlfaNumRFC ( Componente, iMaxima, bVacio, sNombreDelComponente ){
	var sPermitidos = "ABCDEFGHIJKLMNÑOPQRSTUVWXYZ" + "abcdefghijklmnñopqrstuvwxyz" + "1234567890";
	return Validador (Componente, sPermitidos ,iMaxima, bVacio, sNombreDelComponente);
}

function ValidadorRegex (Componente, sExpRegular ,iMaxima, bVacio, sNombreDelComponente, MenErr){
	var sCadena;
	var bRetorno=true;
	var bPermitido=true;
	var bSigue=true;
	var i,j;
	var Letra;
	Componente.value=Trim( Componente.value );
	sCadena=Trim(Componente.value);
	
	if ( bVacio != true && Componente.value.length == 0 ){
		alert("El campo "+sNombreDelComponente+" no puede estar vacío.");
		return false;
	}
	
	if ( Componente.value.length > iMaxima ){
		alert("El campo "+sNombreDelComponente+" no puede tener mas de " + iMaxima + " caracteres.");
		return false;
	}
	
	if ( Componente.value.search( sExpRegular ) == -1 ){
		alert( MenErr );
		return false;
	}
	
	return true;
}

function ValidaNumeroFlotante ( Componente, iMaxima, bVacio, sNombreDelComponente ){
	var MensajeErrorFormato="El campo "+sNombreDelComponente+ " no contiene el formato de un número entero o número con punto decimal.";
	var ExpresionReg = "^([0-9]+[.][0-9]+)$|(^[0-9]+$)";
	return ValidadorRegex (Componente,ExpresionReg,iMaxima,bVacio,sNombreDelComponente,MensajeErrorFormato);
}

/*Pasa a mayusculas el contenido de el campo que se le envie*/
function ToMayusculas ( Componente ){
	Componente.value=Componente.value.toUpperCase();
}

/*  Devuelve una cadena sin ceros a la izquierda, esta función la implemento por que la función parseInt falla
con los valores de entrada "08" y "09" */
function QuitaCeros ( strNumero ) {
	var i;
	var Retorno;
	for ( i=0; i<strNumero.length; i++ )
		if ( strNumero.substr(i,1)!="0" ) break;
	Retorno=strNumero.substr(i,strNumero.length);
	if ( Retorno.length==0 ) Retorno="0";
	return Retorno;
}

//Verifica si la cadena recibida contiene únicamente caracteres numéricos
function EsNumero (Numero){
	var Retorno=false;
	if ( /^([0-9])*$/.test(Numero) && Numero.length>0 ) Retorno=true;
	return Retorno;
}

function EsLetraRFC ( sCadena ){
	var bRetorno=true;
	var i,j;
	var Letra;		
	var bPermitido=true;
	var bSigue=true;
	var sPermitidos="ABCDEFGHIJKLMNÑOPQRSTUVWXYZabcdefghijklmnñopqrstuvwxyz";
	for ( i=0; i<sCadena.length && bPermitido==true; i++ ){
		Letra=sCadena.charAt( i );
		for ( j=0; j<sPermitidos.length && bSigue==true; j++){
			if ( Letra==sPermitidos.charAt( j ) ) bSigue=false;
		}
		if ( bSigue==true ) 
			bPermitido=false;
		else 
			bSigue=true;
	}
	
	if ( bPermitido==false ){
		bRetorno=false;
	}	
	return bRetorno;
}

function EsAlfaNumerico ( sCadena ){
	var bRetorno=true;
	var i,j;
	var Letra;		
	var bPermitido=true;
	var bSigue=true;
	var sPermitidos="ABCDEFGHIJKLMNÑOPQRSTUVWXYZabcdefghijklmnñopqrstuvwxyz1234567890";
	for ( i=0; i<sCadena.length && bPermitido==true; i++ ){
		Letra=sCadena.charAt( i );
		for ( j=0; j<sPermitidos.length && bSigue==true; j++)	if ( Letra==sPermitidos.charAt( j ) ) bSigue=false;
		if ( bSigue==true ) 	bPermitido=false;
		else 					bSigue=true;
	}
	if ( bPermitido==false )	bRetorno=false;
	return bRetorno;	
}

//Función que revisa el formato del RFC
function RevisarRFC ( Cadena ){
/*	var Retorno=true;
	var Letras="";
	var Numeros="";
	Letras = Componente.value.substr(0,4);
	Numeros = Componente.value.substr(4,6);
	Homoclave = Componente.value.substr(10);;
	
	if ( !EsNumero( Numeros ) || !EsLetraRFC(Letras) || !EsAlfaNumerico(Homoclave) ){
		alert("Formato de RFC Incorrecto");
		Retorno=false;
	}

	return Retorno;
*/
	if ( Cadena.search("^[A-Za-zÑñ]{4}[0-9]{6}[0-9A-Za-z]{3}$")!=-1 ) return true;
	else return false;
}

function ComprobarCURP ( Cadena ){
	if ( Cadena.search("^[A-Za-zÑñ]{4}[0-9]{6}[HMhm][A-Za-z]{5}[0-9A-Za-z]{2}$")!=-1 ) return true;
	else return false;
}

function AjustaCampo ( Componente ){
	Componente.value=Trim( Componente.value );
	ToMayusculas ( Componente );
}

function FechaIntsString ( Dia, Mes, Anio ){	
	//Primero pasamos Dia, Mes y Anio a cadenas por que si no va a haber errores
	FechaDia = Dia + "";
	FechaMes = Mes + "";
	FechaAnio = Anio + "";
	
	var i=0;
	var FechaFinal = "" + FechaAnio;

	if ( FechaMes.length < 2) FechaFinal = FechaFinal + "0" + FechaMes;
	else FechaFinal = FechaFinal + FechaMes;
	
	if ( FechaDia.length < 2) FechaFinal = FechaFinal + "0" + FechaDia;
	else FechaFinal = FechaFinal + FechaDia;
	
	return FechaFinal;
}

/*Esta función regresa true si la fecha es valida y false de lo contrario */
function FechaValida ( Dia,Mes,Anio ){
	var fecha;
	var Retorno=false;
	fecha = new Date( Anio, Mes-1, Dia );		
	if ( Dia == fecha.getDate() && Mes == (fecha.getMonth()+1) && Anio == fecha.getFullYear() ){
		Retorno=true;
	}
	return Retorno;
}

//Regresa true en caso de que el año que le sea enviado sea bisiesto
function bisiesto( Anio ){ 
	return FechaValida ( 29,2,Anio );
} 	

function DifFechas ( FechaInicial, FechaFinal, TiempoTranscurrido ){
	var array_nacimiento = new Array(3);
	var array_actual = new Array(3);
	var anos=0, dias=0, anos=0;
	var dias_mes_anterior=0;

	array_nacimiento[0] = parseInt( QuitaCeros ( FechaInicial.substr( 0, 4 ) ) );
	array_nacimiento[1] = parseInt( QuitaCeros ( FechaInicial.substr( 4, 2 ) ) );
	array_nacimiento[2] = parseInt( QuitaCeros ( FechaInicial.substr( 6, 2 ) ) );
	array_actual[0] = parseInt( QuitaCeros ( FechaFinal.substr( 0, 4 ) ) );
	array_actual[1] = parseInt( QuitaCeros ( FechaFinal.substr( 4, 2 ) ) );
	array_actual[2] = parseInt( QuitaCeros ( FechaFinal.substr( 6, 2 ) ) );
	
	anos =  array_actual[0] - array_nacimiento[0]; // calculamos años 
	meses = array_actual[1] - array_nacimiento[1]; // calculamos meses 
	dias =  array_actual[2] - array_nacimiento[2]; // calculamos días 	
	
	if (dias < 0) { 
		--meses; 

		//ahora hay que sumar a dias los dias que tiene el mes anterior de la fecha actual 
		switch ( array_actual[1] ) { 
			case 1:		dias_mes_anterior=31; break; 
			case 2:		dias_mes_anterior=31; break; 
			case 3:  	//dias_mes_anterior = ( bisiesto(array_actual[0]) ) ? 29 : 28 ;  break;
						if ( bisiesto( array_actual[0]) ) dias_mes_anterior=29; 
						else dias_mes_anterior=28; 
						break; 
			case 4:		dias_mes_anterior=31; break; 
			case 5:		dias_mes_anterior=30; break; 
			case 6:		dias_mes_anterior=31; break; 
			case 7:		dias_mes_anterior=30; break; 
			case 8:		dias_mes_anterior=31; break; 
			case 9:		dias_mes_anterior=31; break; 
			case 10:	dias_mes_anterior=30; break; 
			case 11:	dias_mes_anterior=31; break; 
			case 12:	dias_mes_anterior=30; break; 
			default: alert("Error en el Switch" + array_actual[1] );
		} 
		dias = dias + dias_mes_anterior; 
		
		if (dias < 0){
			--meses;
			if(dias == -1)	dias = 30; 
			if(dias == -2)	dias = 29;
		} 
	} 

	//ajuste de posible negativo en meses 
	if (meses < 0) { 
		--anos; 
		meses=meses + 12; 
	} 	
	
	TiempoTranscurrido[0]=anos;
	TiempoTranscurrido[1]=meses;
	TiempoTranscurrido[2]=dias;
	
}

/*Esta función compara dos fechas enviadas, devuelve:
-1->Si la fecha 1 es menor a la fecha 2
0-> Si las fechas son iguales 
1-> Si la fecha 2 es menor a la fecha 1*/
function ComparaFechas ( Dia1, Mes1, Anio1, Dia2, Mes2, Anio2 ){
	var Retorno;
	if ( Anio1 < Anio2 ) {
		Retorno=-1;
	}
	else if ( Anio1 > Anio2 ){
		Retorno=1;
	}
	else{ //Son iguales
		if ( Mes1 < Mes2 ) {
			Retorno=-1;
		}
		else if ( Mes1 > Mes2 ){
			Retorno=1;
		}
		else{ //Los meses son iguales
			if ( Dia1 < Dia2 ) {
				Retorno=-1;
			}
			else if ( Dia1 > Dia2 ){
				Retorno=1;
			}
			else{ //Todo es igual
				Retorno=0;
			}
		}
	}
	return Retorno;
}

function SeleccionarIndiceCombo ( ComboBox, Indice ){
	var i;
	for ( i=0; i<ComboBox.length; i++ ){
		if ( ComboBox[i].value == Indice ){
			ComboBox[i]. selected = true;
			break;
		}
	}
}

//Valida que la fecha introducida sea válida y no sea mayor que la fecha de del día actual
function ValidaFechaConHoy ( Dia,Mes,Anio,NombreCampo ) {
	var FechaHoy;
	var FechaIntroducida;
	if ( !FechaValida ( Dia,Mes,Anio ) ){
		alert("El campo "+NombreCampo+" contiene una fecha inválida, por favor, escriba una fecha correcta en dicho campo.");
		return false;
	} 
	
	FechaHoy=new Date();
	FechaIntroducida = new Date( Anio, Mes-1, Dia ,0,0,0 );
	FechaHoy=new Date( FechaHoy.getFullYear(), FechaHoy.getMonth(), FechaHoy.getDate(),0,0,0 );	
	if ( FechaIntroducida > FechaHoy ) {
		alert( "La fecha introducida en el campo "+ NombreCampo +" debe ser menor a la fecha del día actual." );
		return false;
	}
	return true;
}

function VerificaIntervaloFechas ( Dia1, Mes1, Anio1, Dia2, Mes2, Anio2, NombreFecha1, NombreFecha2 ){
	//Primero validamos que las fechas sean válidas
	if ( !FechaValida(Dia1,Mes1,Anio1) ){
		alert("El campo de fecha "+ NombreFecha1 +" contiene una fecha inválida.");
		return false;
	}
	
	if ( !FechaValida(Dia2,Mes2,Anio2) ){
		alert("El campo de fecha "+ NombreFecha2 +" contiene una fecha inválida.");
		return false;
	}
	
	if ( ComparaFechas ( Dia1, Mes1, Anio1, Dia2, Mes2, Anio2 ) != -1 ){
		alert("La fecha del campo \""+NombreFecha1+"\" no puede ser posterior ni igual a la fecha del campo \""+NombreFecha2+"\".");
		return false;
	}
	
	return true;
}

/*Devuelve la cadena llegada como parametro por una que no tiene acentos*/
function SinAcentos ( sPalabra ){
	var Retorno = sPalabra;
	var aLetBus = "ÁÉÍÓÚáéíóú";
	//ÁÀÄÂÉÈËÊÍÌÏÎÓÒÖÔÚÙÜÛáàäâéèëêíìïîóòöôúùüû
	//AAAAEEEEIIIIOOOOUUUUaaaaeeeeiiiioooouuuu
	var aLetSus = "AEIOUaeiou";  
	for ( i=0; i<aLetBus.length; i++ ){
		Retorno = str_replace ( Retorno, aLetBus.substr(i,1), aLetSus.substr(i,1) );
	}
	return Retorno;
}

/*Devuelve la primera vocal de una cadena indicándole desde dónde empezar a revisar con su parametro iInicio*/
function PrimeraVocal ( sPalabra, iInicio ){
	var Vocales = "AEIOUaeiou";
	var cadChar = "";
	var Retorno = "";
	for ( i=iInicio; i<sPalabra.length; i++ ){
		cadChar = sPalabra.substr(i,1);
		for ( j=0; j<Vocales.length; j++ ){
			if ( cadChar == Vocales.substr(j,1) ){
				Retorno = Vocales.substr(j,1);
				j = Vocales.length;
				i = sPalabra.length;
			}
		}
	}
	return Retorno;
}

/*Quita las palabras sobrantes de los nombres y además quita los Nombres comunes si se trata de un nombre*/
function QuitaComunes ( sNombre, bEsNombre ){
	var Retorno = Trim( sNombre );
	var Sobrantes = new Array(".", ",", "DE ", "DEL ", "LA ", "LOS ", "LAS ", "Y ", "MC ", "MAC ", "VON ", "VAN ");
	var Nombres = new Array("MA ","MARIA ","J ","JOSE ");
	for ( i=0; i<Sobrantes.length; i++ )	Retorno = str_replace( Retorno, Sobrantes[i], "" );
	if ( bEsNombre ){
		for ( i=0; i<Nombres.length; i++ )	Retorno = str_replace( Retorno, Nombres[i], "" );
	}
	return Trim( Retorno );
}

/*Sustituye las palabras ofensivas...*/
function QuitaProhibidas ( sRfc ){
	var Retorno = sRfc;
	var sPalabras = "BUEI&BUEY&CACA&CACO&CAGA&CAGO&CAKA&CAKO&COGE&COJA&";
	sPalabras += "KOGE&KOJO&KAKA&KULO&MAME&MAMO&MEAR&";
	sPalabras += "MEAS&MEON&MION&COJE&COJI&COJO&CULO&";
	sPalabras += "FETO&GUEY&JOTO&KACA&KACO&KAGA&KAGO&";
	sPalabras += "MOCO&MULA&PEDA&PEDO&PENE&PUTA&PUTO&";
	sPalabras += "QULO&RATA&RUIN";
	aPalabras = sPalabras.split("&");
	for ( i=0; i<aPalabras.length; i++ ){
		Retorno = str_replace( Retorno, aPalabras[i], aPalabras[i].substr(0,3)+"X" );
	}
	return Retorno;
}

/*
	Función que devuelve el RFC, los datos enviados a esta función ya debieron haber sido validados.
*/
function consigueRFC ( sNombre, sApellidoPat, sApellidoMat, sDia, sMes, sAnio ){

	var Retorno = "";
	
	//Pasamos a mayúsculas el nombre
	sNombre = Trim ( sNombre.toUpperCase() );
	sApellidoPat = Trim( sApellidoPat.toUpperCase() );
	sApellidoMat = Trim( sApellidoMat.toUpperCase() );
	
	//Guardamos los nombres originales
	var sNombreOriginal = sNombre;
	var sApellidoPatOriginal = sApellidoPat;
	var sApellidoMatOriginal = sApellidoMat;		

	//Le sustituimos los acentos a los elementos
	sNombre = SinAcentos ( sNombre );
	sApellidoPat = SinAcentos ( sApellidoPat );
	sApellidoMat = SinAcentos ( sApellidoMat );

	//Le quitamos las U con dieresis.
	sNombre = str_replace(sNombre, "Ü", "U");
	sApellidoPat = str_replace(sApellidoPat, "Ü", "U");
	sApellidoMat = str_replace(sApellidoMat, "Ü", "U");
	
	//Quitamos las palabras sobrantes de los apellidos y los nombres comunes
	sNombre = QuitaComunes ( sNombre, true );
	sApellidoPat = QuitaComunes ( sApellidoPat, false );
	sApellidoMat = QuitaComunes ( sApellidoMat, false );
	
	
	//Empezamos a generar el RFC
	Retorno = sApellidoPat.substr(0,1);
	Retorno += PrimeraVocal ( sApellidoPat, 1 );
	if ( sApellidoMat=="" ) Retorno += "X";
	else Retorno += sApellidoMat.substr(0,1);
	Retorno += sNombre.substr(0,1);
	
	//Ahora acomodamos los caracteres numéricos
	sAnio = sAnio.substr( 2,4 );
	if ( sMes.length < 2 ) sMes = "0"+sMes;
	if ( sDia.length < 2 ) sDia = "0"+sDia;
	Retorno += sAnio+sMes+sDia;
	
	//Ahora solo modificamos las palabras prihibidas...
	Retorno = QuitaProhibidas ( Retorno );
	
	return Retorno;
}

function consigueCURP ( sNombre, sApellidoPat, sApellidoMat, sDia, sMes, sAnio, sSexo, sEdo ){
	var rfc = consigueRFC( sNombre, sApellidoPat, sApellidoMat, sDia, sMes, sAnio );
	var curp = rfc + sSexo + sEdo;
	return curp;
}
	
