var T_DESCONOCIDO = 0;    /* 000000000 */
var T_DNI         = 1;    /* 000000001 */
var T_NIF_L       = 2;    /* 000000010 */
var T_NIF_K       = 4;    /* 000000100 */
var T_NIF_X       = 8;    /* 000001000 */
var T_NIF_Y       = 16;   /* 000010000 */
var T_NIF_Z       = 32;   /* 000100000 */
var T_NIF_M       = 64;   /* 001000000 */
var T_CIF_NUMERO  = 128;  /* 010000000 */
var T_CIF_LETRA   = 256;  /* 100000000 */

/* TIPOS QUE AGRUPAN OTROS TIPOS -> PARA FACILIDAD EN LAS LLAMADAS */

var T_CUALQUIERA       = 511;                                     /* Cualquier Tipo > 111111111 */
var T_PERSONA_FISICA   = T_CUALQUIERA^T_CIF_NUMERO^T_CIF_LETRA;   /* Todos menos los CIFs */
var T_PERSONA_JURIDICA = T_CIF_NUMERO|T_CIF_LETRA;                /* Únicamente CIFs */


/***************************************************************************
* Ayuntamiento de Alicante - Servicio de Informática
* Función: tipoNIF
* Descripción: Analiza un NIF/CIF/NIE y devuelve el tipo de documento
* Argumentos: NIF/NIE/CIF (OJO!!! STRING[9] de números y letras en mayúsculas)
* Valor de retorno: INTEGER - Tipo de documento (Ver constantes T_XXXXXXXXX)
***************************************************************************/
function tipoNIF(as_nif)
{
	li_tipo = T_DESCONOCIDO;

	if(as_nif.match(/^[0-9]{8}[A-Z]{1}$/))
	{
		li_tipo = T_DNI;		
	}
	else if(as_nif.match(/^[LKXYZM]{1}[0-9]{7}[A-Z]{1}$/))
	{
		li_tipo = eval("T_NIF_"+as_nif.charAt(0));
	}
	else if(as_nif.match(/^[ABCDEFGHJUV]{1}[0-9]{8}$/))
	{
		li_tipo = T_CIF_NUMERO;	
	}
	else if(as_nif.match(/^[NPQRSW]{1}[0-9]{7}[A-Z]{1}$/))
	{
		li_tipo = T_CIF_LETRA;	
	}	

	return li_tipo;
}


/***************************************************************************
* Ayuntamiento de Alicante - Servicio de Informática
* Función: validaNIF
* Descripción: Analiza un NIF/CIF/NIE y comprueba si es correcto 
*             (formato y dígito de control)
* Argumentos: - NIF/NIE/CIF (STRING, no se requiere justificación con 0's ni 
*               mayúsculas)
*             - Tipo(s) a validar (INTEGER, Ver constantes T_XXXXXXXXX)
*               NOTA:  se pueden concatenar (T_DNI|T_NIF_X|T_NIF_Y|T_NIF_Z) 
*               NOTA2: por defecto T_CUALQUIERA
* Valor de retorno: INTEGER - Tipo de documento (Ver constantes T_XXXXXXXXX)
***************************************************************************/
function validaNIF(as_nif, as_tipo)
{
	li_retorno = T_DESCONOCIDO;

	as_tipo = as_tipo || T_CUALQUIERA;
	ls_nif  = as_nif.toUpperCase();

	if(ls_nif.length < 9)
	{
		ls_nif  = rellenaNIF(ls_nif);	
	}
	
	li_tipo = tipoNIF(ls_nif);

	if(as_tipo & li_tipo)
	{
		switch(li_tipo)
		{
			case T_DNI:
				ls_parte_numerica = ls_nif.substr(0, 8);
				ls_digito_control = ls_nif.substr(8, 1);
				li_retorno = (ls_digito_control == digitoControlDNI(ls_parte_numerica))?li_tipo:T_DESCONOCIDO;
				break;
			case T_NIF_K:
			case T_NIF_L:
			case T_NIF_M:
			case T_NIF_X:
				ls_parte_numerica = ls_nif.substr(1, 7);
				ls_digito_control = ls_nif.substr(8, 1);
				li_retorno = (ls_digito_control == digitoControlDNI(ls_parte_numerica))?li_tipo:T_DESCONOCIDO;
				break;
			case T_NIF_Y:
				ls_parte_numerica = "1"+ls_nif.substr(1, 7);		
				ls_digito_control = ls_nif.substr(8, 1);											
				li_retorno = (ls_digito_control == digitoControlDNI(ls_parte_numerica))?li_tipo:T_DESCONOCIDO;
				break;
			case T_NIF_Z:
				ls_parte_numerica = "2"+ls_nif.substr(1, 7);
				ls_digito_control = ls_nif.substr(8, 1);
				li_retorno = (ls_digito_control == digitoControlDNI(ls_parte_numerica))?li_tipo:T_DESCONOCIDO;
				break;
			case T_CIF_NUMERO:
			case T_CIF_LETRA:
				ls_parte_numerica = ls_nif.substr(1, 7);		
				ls_digito_control = ls_nif.substr(8, 1);											
				li_retorno = (ls_digito_control == digitoControlCIF(ls_parte_numerica, li_tipo))?li_tipo:T_DESCONOCIDO;					
				break;
		}	
	}
	
	return li_retorno;
}


/***************************************************************************
* Ayuntamiento de Alicante - Servicio de Informática
* Función: digitoControlDNI
* Descripción: Analiza la parte numérica de un NIF/NIE y obtiene el dígito de 
*              control
* Argumentos: Parte numérica de un NIF/NIE (STRING, no se requiere justificación con 0's)
* Valor de retorno: Dígito de control STRING[1]
***************************************************************************/
function digitoControlDNI(as_parte_numerica_dni)
{
	return new String("TRWAGMYFPDXBNJZSQVHLCKE").charAt(parseInt(as_parte_numerica_dni, 10) % 23)
}


/***************************************************************************
* Ayuntamiento de Alicante - Servicio de Informática
* Función: digitoControlCIF
* Descripción: Analiza la parte numérica de un NIF/NIE y obtiene el dígito de 
*              control según su tipo
* Argumentos: - Parte numérica de un CIF (STRING, no se requiere justificación con 0's)
*             - Tipo del CIF (CIF_LETRA/CIF_NUMERO)
* Valor de retorno: Dígito de control STRING[1]
***************************************************************************/
function digitoControlCIF(as_parte_numerica_dni, as_tipo)
{
	ls_retorno = null;

	li_suma = parseInt(as_parte_numerica_dni.charAt(1),10) + parseInt(as_parte_numerica_dni.charAt(3),10) + parseInt(as_parte_numerica_dni.charAt(5),10);

	for (li_cont = 0; li_cont < 7; li_cont += 2)
	{
		ls_prod = new String(2 * parseInt(as_parte_numerica_dni.charAt(li_cont),10));
		if(ls_prod.length > 1)
		{
			li_suma += parseInt(ls_prod.substr(0,1), 10) + parseInt(ls_prod.substr(1,1), 10);
		}
		else
		{
			li_suma += parseInt(ls_prod.substr(0,1), 10);			
		}
	}

	li_resto = ( li_suma%10 ) != 0 ? li_suma%10 : 10;

	li_numero_control = 10 - li_resto;	

	switch(as_tipo)
	{
		case T_CIF_LETRA:
			ls_retorno =  new String("JABCDEFGHI").charAt(li_numero_control);
			break;
		case T_CIF_NUMERO:
			ls_retorno =  li_numero_control;
			break;			
	}

	return ls_retorno;
}


/***************************************************************************
* Ayuntamiento de Alicante - Servicio de Informática
* Función: rellenaNIF
* Descripción: Toma como entrada un NIF/NIE/CIF y lo justifica con ceros 
*              hasta 9 caracteres
*              control según su tipo
* Argumentos: NIF/NIE/CIF (STRING, obv. no se requiere justificación con 0's)
* Valor de retorno: NIF/NIE/CIF justificado hasta 8 caracteres (STRING[9])
***************************************************************************/
function rellenaNIF(as_nif)
{
	if(!isNaN(as_nif.charAt(0))) // T_DNI 
	{
		ls_retorno = as_nif;
		while(ls_retorno.length < 9)
		{
			ls_retorno = "0" + ls_retorno;
		}
	}
	else // T_NIF_K, T_NIF_L, T_NIF_M, T_NIF_X, T_NIF_Y, T_NIF_Z, T_CIF_NUMERO, T_CIF_LETRA 
	{
		ls_letra = as_nif.charAt(0);
		ls_resto = as_nif.substr(1);
		while(ls_resto.length < 8)
		{
			ls_resto = "0" + ls_resto;
		}	
		ls_retorno = ls_letra+ls_resto;
	}

	return ls_retorno;
}

