/**
 * @author Fernando Reig Aparicio
 * @copyright 2006
*/
var extension_js = true;	

/* ----------------------------------------------------------
							String
-------------------------------------------------------------*/
/**
 * Devuelve una cadena de texto sin caracteres blancos por la izquierda
 * @access public
 */
String.prototype.ltrim = 
function(caracteres){
	var i=0;
	var s = "";
	if (typeof(caracteres)=="undefined")
		var caracteres = " \t";
	var r = new RegExp("["+caracteres+"]");
	while((i<this.length) && r.test(this.charAt(i)))
		i++;
	return this.substring(i);
}

/**
 * Devuelve una cadena de texto sin caracteres blancos por la derecha
 * @access public
 */
String.prototype.rtrim = 
function(caracteres){
	var i=this.length-1;
	var s = "";
	if (typeof(caracteres)=="undefined")
		var caracteres = " \t";
	var r = new RegExp("["+caracteres+"]");
	while((i>=0) && r.test(this.charAt(i)))
		i--;
	return this.substring(0,i+1);
}

/**
 * Devuelve una cadena de texto sin caracteres blancos por la izquierda y la derecha
 * @access public
 */
String.prototype.trim = 
function(){
	return this.ltrim().rtrim();
}

String.prototype.lpad = 
function (lon, car){
	var i,s;	
	s=this.valueOf();
	lon = lon - s.length;
	if (lon<=0)
		return s;
		
	for (i=0; i<lon; i++)
		s=car+s;
	
	return s;
}

/* ----------------------------------------------------------
							Array
-------------------------------------------------------------*/
/**
 * Busca alguna coincidencia en el vector con <code>s</code>
 * y si la ncuentra devuelve su posicin
 * @param object s
 * @access public
 */
Array.prototype.search = 
function(s){
	var i;
	for (i=0;i<this.length;i++){
		if (this[i]==s)
			return i;
	}//for
	return -1;
};

/**
 * Añade los elementos de los arrays especificados al array actual
 * y devuelve su nueva longitud
 * @param object
 * @access public
 */
Array.prototype.merge = 
function(){
	var i, j, v;
	for (i=0;i<arguments.length;i++){
		v = arguments[i];
		if (v.push)
		{
			for(j=0; j<v.length; j++)
			{
				this.push(v[j]);
			}
		}
		else
			this.push(v);
	}//for
	return this.length;
};

/**
 * Elimina el elemento en la posicion indicada
 * @param int iPos Posición del elemento a eliminar
 * @return bool
 */
Array.prototype.remove = 
function(iPos){
	//si la posicion indicada se sale del vector
	if ((iPos>=this.length) || (iPos<0))
		return false;
	
	var i;
	for(i=iPos; i<this.length-1; i++){
		this[i] = this[i+1];
	}
	
	this.length--;
	return true;
}

/**
 * Elimina la primera ocurrencia del elemento <code>e</code> en el vector
 * @param object e
 * @return bool
 * @access public
 */
Array.prototype.removeElement = 
function(e){
	return this.remove(this.search(e));
}

/**
 * @access public
 */
Array.prototype.processElements = 
function(func){
	var i;
	for (i=0; i<this.length; i++){
		func.call(null, this[i]);
	}
}

Array.prototype.appendToSelect = 
function(e, bOnlyNew){
	if(e==null || !e.options)
		return false;
		
	var eOpcion;
	//alert(this);
	for(var i=0; i<this.length; i++){
		if (bOnlyNew){
			var b = false;
			for(var j=0; j<e.options.length; j++){
				if (e.options[j].value==this[i]){
					b = true;
					break;
				}	
			}
			if (b)
				continue;
		}
	//alert(this[i]);
		eOpcion = document.createElement("option");
		eOpcion.value = this[i];
		eOpcion.text = this[i];
		eOpcion.selected = true;
		
		if (/microsoft/i.test(navigator.appName)){ //si se trata de IExplorer
			e.add(eOpcion,0);
		}else{
			e.add(eOpcion,null);	
		}
	}
}

/* -----------------------------------------------------------
							Date
--------------------------------------------------------------*/

/**
 * Dice si dos fechas son iguales
 * @return bool
 * @access public
 */
Date.prototype.equals = 
function(d){
	return this.toString()==d.toString();
}

/**
 * Devuelve una cadena de texto con la fecha en formato ISO (YYYY-MM-DD)
 * @return string
 * @access public
 */
Date.prototype.toStringISODate = 
function(separador){
	var ano = this.getFullYear();
	var mes = new Number(this.getMonth()+1).zeroFill(2);
	var dia = new Number(this.getDate()).zeroFill(2);
	if (separador==undefined)
		var separador = "-";
	
	return ano+separador+mes+separador+dia;
}

/**
 * Devuelve una cadena de texto con la fecha en formato europeo (DD-MM-YYYY)
 * @return String
 * @access public
 */
Date.prototype.toStringEuropeDate = 
function(separador){
	var ano = this.getFullYear();
	var mes = new Number(this.getMonth()+1).zeroFill(2);
	var dia = new Number(this.getDate()).zeroFill(2);
	if (separador==undefined)
		var separador = "-";
	
	return dia+separador+mes+separador+ano;
}

/**
 * Devuelve una cadena de texto con la fecha en formato americano (MM-DD-YYYY)
 * @return string
 * @access public
 */
Date.prototype.toStringUSADate = 
function(separador){
	var ano = this.getFullYear();
	var mes = new Number(this.getMonth()+1).zeroFill(2);
	var dia = new Number(this.getDate()).zeroFill(2);
	if (separador==undefined)	
		var separador = "-";
	
	return mes+separador+dia+separador+ano;
}

/**
 * Devuelve una cadena de texto con la hora (HH:mm)
 * @param bool bSeconds
 * @return string
 * @access public
 */
Date.prototype.toStringHour = 
function(bSeconds){
	if (typeof(bSeconds)=="undefined")
		var bSeconds = true;
		
	var s = this.getHours()+":"+this.getMinutes();
	if (bSeconds)
		s+=(":"+this.getSeconds());
	return s;
}

/** 
 * Dice si el año actual (this.getFullYear()) es bisiesto o no
 * @return	bool
 * @access	protected
 */
Date.prototype.isLeapYear = 
function(){
	return (this.getFullYear()%4==0);
}

/**
 * 	Dado un mes, devuelve el numero de dias que tiene el mismo
 * @param	int	iMes Número 0-11 del mes 
 * @return	int	Numero de dias del mes
 * @access	protected
 */
Date.prototype.getNumDaysMonth = 
function(){
	var iMes = this.getMonth();

	switch(iMes){
	case 0: //enero
	case 2: //marzo
	case 4: //mayo
	case 6: //julio
	case 7: //agosto
	case 9: //octubre
	case 11: //diciembre
		return 31;
	case 1: if (this.isLeapYear()) return 29; else return 28; //febrero
	default:
		return 30;
	}

}
	
/**
 * Obtiene el nombre del mes indicado
 * @param int iMes Número del mes (0-11). si no se especifica se toma el mes sealado del calendario
 * @return	string	Nombre del mes indicado
 * @param protected
 */
Date.prototype.getMonthName = 
function(){
	var iMes = this.getMonth();
	return Date.monthName(iMes);
}

/**
 * Obtiene el nombre del mes indicado
 * @param int iMes Número del mes (0-11). Si no se especifica se toma el mes sealado del calendario
 * @return	string	Nombre del mes indicado
 * @access protected
 */
Date.prototype.getDayName = 
function(){
	return Date.dayName(this.getDay());
}
	

/**
 * Dice si el dia indicado se trata de un día festivo o no
 * @param	int	iDia  Día del mes
 * @param	int	iMes  Número del mes (0-11)
 * @param	int	iAno  Año
 * @return	bool Devuelve <code>true</code> si el dia es festivo y <code>false</code> en caso contrario
 * @access	protected 
 */
Date.prototype.isBankHoliday = 
function(){
	/*FESTIVOS NACIONALES:
	1 de enero: Año Nuevo
	6 de enero: Epifanía del Señor
	25 de marzo: Viernes Santo
	15 de agosto: Fiesta de la Asunción de la Virgen
	12 de octubre: Fiesta Nacional de España
	1 de noviembre: Todos los Santos
	6 de diciembre: Día de la Constitución
	8 de diciembre: Inmaculada Concepción
	*/
	if (this.getDay()==0) //si es domingo
		return true;
	var iDia = this.getDate();
	switch(this.getMonth()){
	case 0: //enero
		return (iDia==1 || iDia==6);
	case 2: //marzo
		//return (iDia==25);
		break;
	case 7: //agosto
		return (iDia==15);
	case 9: //octubre
		return (iDia==12);
	case 10: //noviembre
		return (iDia==1);
	case 11: //diciembre
		return (iDia==6 || iDia==8);
	}//switch
	return false;
}

/**
 * Dice si el primer dia del mes es lunes = 0, martes=1,...., domingo=1
 * @return	int	(0..6)
 * @access	protected
 */
Date.prototype.getFirstDayMonth = 
function(){
	var d = new Date(this.getFullYear(), this.getMonth(), 1);
	return (d.getDay()+6)%7; //0=lunes, 1=martes,... 6=domingo
}


/**
 * Dice si la se encuentra entre el intervalo de fechas pasado
 * @param 	Date	oIni	Fecha inicial
 * @param	Date	oFin	Fecha final
 * @return	bool 
 * @access public
 */
Date.prototype.between = 
function(oIni, oFin){  
	if (!oIni && !oFin)
		return false;
	var aux;
	
	if (!oIni){ //se no se ha especificado una fecha de inicio
		return (this.getTime()<=oFin.getTime());
	}else
	if (!oFin){ //si no se ha especificado una fecha de fin
		return (this.getTime()>=oIni.getTime());
	}
	
	if (oIni.getTime()>oFin.getTime()){ //si la fecha inicial es mayor que la final se intercambian
		aux = oIni;
		oIni = oFin;
		oFin = aux;
	}
	
	//se se ha especificado el intervalo completo
	return ((this.getTime()>=oIni.getTime()) && (this.getTime()<=oFin.getTime()));
}

/**
 * @param sting sFecha a parsear
 * @return CDate
 * @access public
 */
Date.prototype.parseDate = 
function(sFecha){
	var s = "[\\t ]*[-\\/][\\t ]*";
	var regs = null;
	if ((regs = new RegExp('([0-9]+)'+s+'([0-9]+)'+s+'([0-9]+)([\\t ]+([0-9]+):([0-9]+)(:([0-9]+))?)?').exec(sFecha))){
		if (regs.length<3) //no se ecuentran al menos 3 cifras en la cadena
			return null;		

		//utlizamos Number  pq si se le hace un parseInt sobre un texto 0X siendo X un numero cualquiera
		//se interpreta como un octal y devulve su valor a decimal
		for(var i=0; i<regs.length; i++)
			regs[0] = parseInt(new Number(regs[0]).valueOf());
	
		//esta en formato europeo
		if (regs[3]>31){
			this.setFullYear(regs[3], regs[2]-1, regs[1]);
		}else
		//esta en formato ISO
		if (regs[1]>31){
			this.setFullYear(regs[1], regs[2]-1, regs[3]);
		}else
		//esta en formato americano
			this.setFullYear(regs[3], regs[1]-1, regs[2]);

		var hrs = 0;
		var mins = 0;
		var secs = 0;
		if (!isNaN(regs[5])){
			hrs = regs[5];
			mins = regs[6];
			if (!isNaN(regs[8])){
				secs = regs[8];
				if (secs>59 || secs<0)
					return null;
			}
				 
			if (hrs>23 || hrs<0)
				return null;
			if (mins>59 || mins<0)
				return null; 
		}
		this.setHours(hrs, mins, secs);
		return this;			
	}else
		return null;
}

/**
 * Incrementa la fecha actual en tantos dias como se indique
 * @param int iDays Numero de dias a incrmentar
 * @return CDate Una referencia a la propia instancia
 * @access public
 */
Date.prototype.incDate = 
function(iDays){
	if (iDays==undefined)
		var iDays = 1;
	var ms = (parseInt(iDays)*24*3600*1000); /*se pasan los dias a milisegundos*/
	this.setTime(this.getTime()+ms);
	//alert(this);
	return this;
}

/**
 * Incrementa la fecha actual en tantos años como se indique
 * @param int iDays Numero de años a incrementar
 * @return CDate Una referencia a la propia instancia
 * @access public
 * @todo
 */
Date.prototype.incYear = 
function(inc){
	if (inc==undefined)
		var inc = 1;
	var ano = this.getFullYear()+parseInt(inc);
	this.setFullYear(ano);
	return this;
}

/**
 * Incrementa la fecha actual en tantos meses como se indique
 * @param int iDays Numero de meses a incrementar
 * @return CDate Una referencia a la propia instancia
 * @access public
 * @todo
 */
Date.prototype.incMonth = 
function(inc){
	if (inc==undefined)
		var inc = 1;
	var mes = this.getMonth()+parseInt(inc);
	this.setMonth(mes);
	return this;
}

Date.prototype.calculateAge = 
function(dNow){
	if (dNow==undefined)
		var dNow = new Date();
	else
		dNow = Date.makeDate(dNow); //fecha actual
		
	var anos = dNow.getFullYear() - this.getFullYear();
	
	var d1 = Date.makeDate("2006-"+(dNow.getMonth()+1)+"-"+dNow.getDate());
	var d2 = Date.makeDate("2006-"+(this.getMonth()+1)+"-"+this.getDate());
	
	if (d1.getTime()<d2.getTime()){
		anos--;
	}
	return anos;		
}

Date.FORMAT_EUROPE = 0;
Date.FORMAT_USA = 1;
Date.FORMAT_ISO = 2;

/**
 * Crea un objeto date y lo devuelve a partir de los parametros pasados
 * @param mixed fecha
 * @param int iFormato
 * @return Date 
 * @static
 * @access public
 */
Date.makeDate = 
function(fecha, iFormato){
	var d = null;
	
	if(fecha==null || fecha==undefined || fecha=="")
		return new Date();
	
	switch(typeof(fecha)){
	case "number": //numero de milesimas de segundo desde el 1 de enero de 1970
		d = new Date(fecha);
		break;
	case "object":
		if (!fecha.getFullYear)
			return false;
		d = fecha;
		break;
	case "string":
		var re = new RegExp("^([0-9]+)[^0-9]+([0-9]+)[^0-9]+([0-9]+)([ ]+([0-9]+)\\:([0-9]+)(\\:([0-9]+))?)?$");
		var v = re.exec(fecha);
		if (v == null)
			return null;
		h = v[5];
		if (typeof(h)=="undefined")		
			h = 0;
		m = v[6];
		if (typeof(m)=="undefined")
			m = 0;
		s = v[8];
		if (typeof(s)=="undefined")
			s = 0;
		if (parseInt(v[0])>31)
			iFormato = Date.FORMAT_ISO;
		else
		if (parseInt(v[3])>31)
			iFormato = Date.FORMAT_EUROPE;
		else
			iFormato = Date.FORMAT_USA;

		switch(iFormato){
		case Date.FORMAT_EUROPE:
			return new Date(v[3],new Number(v[2])-1,v[1],h,m,s); //los meses en Date se especifican de 0 a 11
		case Date.FORMAT_USA:
			return new Date(v[3],new Number(v[1])-1,v[2],h,m,s);
		case Date.FORMAT_ISO:
		default:
			return new Date(v[1],new Number(v[2])-1,v[3],h,m,s);
		}
		break;
	default:
		d = new Date();
	}	
	return d;
}

Date.monthName = 
function(iMes){
	switch(iMes){
	case 0: return "Enero";
	case 1: return "Febrero";
	case 2: return "Marzo";
	case 3: return "Abril";
	case 4: return "Mayo";
	case 5: return "Junio";
	case 6: return "Julio";
	case 7: return "Agosto";
	case 8: return "Septiembre";
	case 9: return "Octubre";
	case 10: return "Noviembre";
	case 11: return "Diciembre";
	}
	return "";
}

Date.dayName = 
function(dia){
	switch(dia){
	case 0: return "Domingo";
	case 1: return "Lunes";
	case 2: return "Martes";
	case 3: return "Miércoles";
	case 4: return "Jueves";
	case 5: return "Viernes";
	case 6: return "Sábado";
	}
	return "";
}


/* ------------------------------------------------------------
							Number
--------------------------------------------------------------- */
/**
 * Obtiene una cadena de texto con el valor del numero. Se pondrán tantos ceros a
 * la izquierda como sea necerasio para rellenar el numero de digitos de la parte entera indicados
 * @param int numdigitos Numero de digitos de la parte entera
 * 
 * @return string
 * @access public
 */
Number.prototype.zeroFill = 
function(numdigitos){
	var n = parseInt(this.valueOf());
	if (isNaN(n))
		return null;
	var sn = new String(n);
	var snum = new String(this.valueOf());
	for (i=sn.length; i<numdigitos; i++){
		snum="0"+snum;
	}
	return snum;
}
/* --------------------------------------------------------------
							navigator
----------------------------------------------------------------- */
/**
 * Dice si el navegador que esta utilizando el usuario se trata de Microsoft Internet Explorer
 * @return bool
 * @static
 * @access public
 */
navigator.isIExplorer = 
function(){
	return new RegExp("microsoft","i").test(navigator.appName);	
}