// Módulo principal calendario.

//////////////////////////////////////////////////////////////////////////
// Objeto calendario.	v1.2											//
//																		//
// Creado:		04/11/2002												//
// Modificado:															//
//																		//
// Descripción:															//
//	v1:	Calendario para selección de fechas.							//
//			- Permite la presentación de un calendario de forma gráfica	//
//				para la selección de fechas.							//
//	v1.1:																//
//			- Personalización de imágenes y adición de imagen para		//
//				cerrar el calendario.									//
//			- Adición de propiedad para el color de fondo del			//
//				calendario (Una cadena vacía en la propiedad color,		//
//				deja el	fondo transparente).							//
//	v1.2:	- Adición de propiedad para el color del borde del			//
//				calendario (Una cadena vacía en la propiedad, hará		//
//				que el calendario no tenga borde.						//
//	v1.3:	- Solucionado el bug, que al avanzar el año colocaba el		//
//				mes como estaba la primera vez que se mostró.			//
//																		//
// Bugs:																//
//			- Debido al pésimo navegador que es el Netscape 4.x, los	//
//				textos que indican el día de la semana (L,M,...) y los	//
//				numeritos, no aparecen centrados. Esto no afecta a las	//
//				recientes versiones de Netscape 6.x y 7.x.				//
//																		//
//			- Debido al pésimo navegador que es el Netscape 4.x, el		//
//				color de fondo en este navegador siempre es				//
//				transparente, ya que sólo pinta el color de fondo allí	//
//				donde hay texto. Esto no afecta a las recientes			//
//				versiones de Netscape 6.x y 7.x.						//
//																		//
// Necesita:															//
//	common.js															//
//	utils.js															//
//																		//
// Autor:	Moisés García Cogolludo.									//
//				Tecnología, Información y Finanzas.						//
//////////////////////////////////////////////////////////////////////////

// Constantes
var ALTO_FILA = 15;		// Alto de las filas de numeritos. (Incluye L M X J V S D)
var ANCHO_COL = 17;		// Ancho de las columnas de numeritos. (Incluye L M X J V S D)
var HSPACE = 6;			// Espacio entre columnas.
var VSPACE = 0;			// Espacio entre filas.
var HMARGEN = 0;		// Margen inicial a la izquierda.
var VMARGEN = 20;		// Margen inicial arriba.

var isShow=true;

/****************************************************************
 * Constructor del calendario.									*
 *																*
 * Parámetros:													*
 *	fechaSeleccionada:	fecha que aparece marcada y que 		*
 *						indica cual va a ser la fecha a			*
 *						mostrar inicialmente.					*
 *	nombre:				Nombre del calendario (debe coincidir 	*
 *						con la variable a la que se asigna el	*
 *						calendario).							*
 *	objName:			Nombre del objeto donde irá la fecha.	*
 *	dirImagenes:		Directorio relativo para localizar las	*
 *						imágenes.								*
 ****************************************************************/
function Calendario (fechaSeleccionada,nombre,objName,dirImagenes) {
	// Constantes
	this.ALTO_FILA = ALTO_FILA;
	this.ANCHO_COL = ANCHO_COL;
	this.HSPACE = HSPACE;
	this.VSPACE = VSPACE;
	this.HMARGEN = HMARGEN;
	
	if (ie)		
		this.VMARGEN = VMARGEN;
	else if (n6)
		this.VMARGEN = VMARGEN + 5;
	else if (n)
		this.VMARGEN = VMARGEN + 10;
	
	
	this.fechaSeleccionada = string2fecha(fechaSeleccionada);
	this.nombre = nombre;
	this.objName = objName;
	this.dirImagenes = (dirImagenes) ? dirImagenes : './';
	
	this.anioMostrado = this.fechaSeleccionada.getFullYear();
	this.mesMostrado = this.fechaSeleccionada.getMonth()+1;
	
	// z-Index por defecto
	this.zIndex = 100;
	
	// Color de fondo
	this.colorFondo = '#FFFFFF';
	
	// Color de borde
	this.colorBorde = '#00CCFF';
	
	// Imágenes
	this.imgFechaatras = 'retroceder.gif';
	this.imgFechaadelante = 'avanzar.gif';
	this.imgCerrar = 'boton_eliminarN.gif';
	this.imgSeleccionada = 'selec.gif';
	
	
	// Clases para las cositas.
	this.claseInput = 'input';
	this.claseSelect = 'select';
	this.claseNumerito = 'numerito';
	this.claseCabecera = 'cabecera';
	
	// Métodos
	this.pintaCalendario = PintaCalendario;
	this.pintaNumeritos = PintaNumeritos;
	this.colocaImagen = ColocaImagen;
	this.changeSelect = ChangeSelect;
	this.inicializa = Inicializa;
	this.mostrar = Mostrar;
	this.ocultar = Ocultar;
	this.setFechaSeleccionada = FechaSeleccionada;
	this.repaint = Repaint;
	this.minDate = null;
	this.maxDate = null;
}

/************************************************************
 * Método que inicializa el control, creándolo en la página	*
 * y pintando el mes y año inicial.							*
 *															*
 * Parámetros												*
 *															*
 * Valor de retorno											*
 ************************************************************/
function Inicializa() {
	this.pintaCalendario();
	this.ocultar();
}

function comparaFechas (date1, date2) {
	if (date1 < date2) {
		return -1;
	} else if (date1 > date2) {
		return 1;
	} else {
		return 0;
	}
}
function overlay(curobj, subobjstr, opt_position) {
    if (document.getElementById) {
        var subobj = document.getElementById(subobjstr);
        var xpos = getposOffset(curobj, "left") + ((typeof opt_position != "undefined" && opt_position.indexOf("right") != -1)? - (subobj.offsetWidth-curobj.offsetWidth) : 0);
        var ypos = getposOffset(curobj, "top") + ((typeof opt_position != "undefined" && opt_position.indexOf("bottom") != -1)? curobj.offsetHeight : 0);
        subobj.style.left = xpos + "px";
        subobj.style.top = ypos + "px";
        return false
    } else
        return true
}

/************************************************************
 * Método que muestra y coloca el calendario.				*
 *															*
 * Parámetros												*
 *	top:	Posición vertical del calendario.				*
 *	left:	Posición horizontal del calendario.				*
 *															*
 * Valor de retorno											*
 ************************************************************/
function Mostrar(top,left,objName) {
	if (isShow){
		if (top == null)
			top = 0;
			
		if (left == null)
			left = 0;
			
		if (objName)
			this.objName = objName;
		
		//moverCapaA(left,top,'calendario');
		//moverCapaA(left,top,'calendarioTapa');
		
		setVisibility('calendario',true);
		setVisibility('calendarioTapa',true);
		this.pintaNumeritos(this.mesMostrado,this.anioMostrado);
		overlay(document.getElementById(this.objName),'calendario',"leftbottom");
		overlay(document.getElementById(this.objName),'calendarioTapa',"leftbottom");
	}else{
		isShow=true;
	}
}

/************************************************************
 * Método que oculta el calendario.							*
 *															*
 * Parámetros												*
 *															*
 * Valor de retorno											*
 ************************************************************/
function Ocultar() {
	setVisibility('calendario',false);
	setVisibility('calendarioTapa',false);
}

/************************************************************
 * Método que asigna la fecha a mostrar.					*
 *															*
 * Parámetros												*
 *															*
 * Valor de retorno											*
 ************************************************************/
function FechaSeleccionada(fecha) {
	this.fechaSeleccionada = string2fecha(fecha);
	/*if (this.minDate != null) {
		if (comparaFechas(this.fechaSeleccionada,this.minDate)==-1) {
			this.fechaSeleccionada = this.minDate;
		}
	}
	if (this.maxDate != null) {
		if (comparaFechas(this.fechaSeleccionada,this.maxDate)==1) {
			this.fechaSeleccionada = this.maxDate;
		}
	}
	*/
	//alert(this.minDate);
	//alert(this.fechaSeleccionada)
	this.mesMostrado = this.fechaSeleccionada.getMonth()+1;
	this.anioMostrado = this.fechaSeleccionada.getFullYear();
	
}

/************************************************************
 * Método que crea el calendario en la página con todos	sus	*
 * elementos.												*
 *															*
 * Parámetros												*
 *															*
 * Valor de retorno											*
 ************************************************************/
function PintaCalendario (top,left) {

	var doc = "";

	var cabecera = Array('L','M','X','J','V','S','D');
	var meses = Array('Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre');
	
	if (top == null)
		top = 0;
		
	if (left == null)
		left = 0;
		
	var altoCalendario = this.VMARGEN + this.ALTO_FILA * 7 + this.VSPACE * 6 + 5;
	var anchoCalendario = this.HMARGEN + this.ANCHO_COL * 7 + this.HSPACE * 6 + 5;
	
	// Estilo de la capa que contiene el calendario (sólo para Explorer y Netscape 6 o superior)
	var estilo100 = "position:absolute;top:"+top+";left:"+left+";height:"+altoCalendario+"px;background-color:"+this.colorFondo+";z-index:" + this.zIndex+";";
	var estilo101 = "position:absolute;top:"+top+";left:"+left+";height:"+altoCalendario+"px;background-color:"+this.colorFondo+";z-index:" + (this.zIndex+1) + ";";
	var estilo = "position:absolute;top:"+top+";left:"+left+";height:"+altoCalendario+"px;background-color:"+this.colorFondo+";z-index:" + (this.zIndex+1) + ";";
	if (this.colorBorde != "") {
		estilo += "border-style:solid;border-width:1;border-color:"+this.colorBorde+";";
	}
	if (ie || n6) {
		doc += "<div id='calendarioTapa' style='" + estilo100 + "'>";
		doc += "<iframe src='javascript:void(0)'  id='tapa' NAME='tapa' WIDTH='" + anchoCalendario + "' HEIGHT='" + altoCalendario + "' frameborder='0' style='" + estilo100 + "'>";
		doc += "</iframe>";
		doc += "</div>";
		doc += "<div id='calendario' style='" + estilo + "'>";
	}
	else {
		doc += "<layer id='calendario' top="+top+" left="+left+" height=" + altoCalendario + " >";
	}
	
	// Tabla para información de mes y año.
	doc += "<table cellpadding='1' cellspacing='0' border='0' width='" + (7*this.ANCHO_COL+6*this.HSPACE) + "'>"
	doc += "<tr align='center'>"
	doc += "<td>"
		doc += "<select name='calMesesS' class='"+this.claseSelect+"' onChange='"+this.nombre+".repaint(this.selectedIndex+1,"+'""'+")'>";
		for (var i = 0; i < meses.length; i++)
			doc += "<option value='"+(i+1)+"'>"+meses[i]+"</option>";

		doc += "</select>";
	doc += "</td>"
	
	doc += "<td>"
		doc += "<a href='javascript:"+this.nombre+".repaint("+'""'+","+this.nombre+".anioMostrado-1)'><img src='"+this.dirImagenes+this.imgFechaatras+"' border='0'></a>";	
	doc += "</td>"
	doc += "<td>"
		doc += "<input class='"+this.claseInput+"' type='text' name='calAnioL' value='"+this.anioMostrado+"' size='4' disabled>";	
	doc += "</td>"
	doc += "<td>"
		doc += "<a href='javascript:"+this.nombre+".repaint("+'""'+","+this.nombre+".anioMostrado+1)'><img src='"+this.dirImagenes+this.imgFechaadelante+"' border='0'></a>";	
	doc += "</td>"
	doc += "</tr>"
	doc += "</table>"
	
	
	// Cabecera				
	for (var i = 1; i <= cabecera.length; i++)
		if (ie || n6) {
			doc += "<div id='c0,"+i+"c' style='top:"+this.VMARGEN+"px;left:"+(this.HMARGEN+(i-1)*(this.ANCHO_COL+this.HSPACE))+"px;visibility:inherit' class='celdaCalendario'><font class='"+this.claseCabecera+"'>"+cabecera[i-1]+"</font></div>";
		}
		else {			
			doc += "<LAYER name='c0,"+i+"c' TOP='"+this.VMARGEN+"' LEFT='"+(this.HMARGEN+(i-1)*(this.ANCHO_COL+this.HSPACE))+"' class='celdaCalendario' visibility=inherit><font class='"+this.claseCabecera+"'>"+cabecera[i-1]+"</font></LAYER>";
		}

	// Los numeritos.
	for (var i = 1; i <= 6; i++)
		for (var j = 1; j <= 7; j++) {
			if (ie || n6) {				
				doc += "<div id='n"+i+","+j+"n' style='top:"+(this.VMARGEN+i*(this.ALTO_FILA+this.VSPACE))+"px;left:"+(this.HMARGEN+(j-1)*(this.ANCHO_COL+this.HSPACE))+"px;z-index:0' class='celdaCalendario'></div>";
			}
			else {
				doc += "<layer id='n"+i+","+j+"n' TOP='"+(this.VMARGEN+i*(this.ALTO_FILA+this.VSPACE))+"' LEFT='"+(this.HMARGEN+(j-1)*(this.ANCHO_COL+this.HSPACE))+"' z-index='0' class='celdaCalendario'></LAYER>";
			}
		}
		
	// La imagen.
	if (ie || n6)
		doc += "<div id='imagenSel' style='top:0px;left:0px;visibility:hidden;z-index:1' class='celdaCalendario'><a href='javascript:"+this.nombre+".changeSelect(fecha2string("+this.nombre+".fechaSeleccionada))'><img src='" + this.dirImagenes + this.imgSeleccionada + "' border='0'></a></div>";
	else
		doc += "<layer id='imagenSel' top=0 left=0 visibility='hide' z-index=1 class='celdaCalendario'><a href='javascript:"+this.nombre+".changeSelect(fecha2string("+this.nombre+".fechaSeleccionada))'><img src='" + this.dirImagenes + this.imgSeleccionada + "' border='0'></a></layer>";
		
	// Botón de cerrar
	if (ie || n6)
		doc += "<div id='botonCerrar' style='top:"+(this.VMARGEN+6*(this.ALTO_FILA+this.VSPACE))+"px;left:"+(this.HMARGEN+6*(this.ANCHO_COL+this.HSPACE))+"px;visibility:inherit;z-index:1' class='celdaCalendario'><a href='javascript:"+this.nombre+".ocultar()'><img src='" + this.dirImagenes + this.imgCerrar + "' border='0'></a></div>";
	else
		doc += "<layer id='botonCerrar' top="+(this.VMARGEN+6*(this.ALTO_FILA+this.VSPACE))+" left="+(this.HMARGEN+6*(this.ANCHO_COL+this.HSPACE))+" visibility='inherit' z-index=1 class='celdaCalendario'><a href='javascript:"+this.nombre+".ocultar()'><img src='" + this.dirImagenes + this.imgCerrar + "' border='0'></a></layer>";
	
	
	
	if (ie || n6)
		doc += "</div>";
	else
		doc += "</layer>";

	
	document.write (doc);
	
	
}

/************************************************************
 * Repinta el calendario, de forma que no se pierda el mes	*
 * visualizado al cambiar de año.							*
 *															*
 * Parámetros												*
 *	mes:		Mes del año que se está visualizando.		*
 *	anio:		Año que se visualiza.						*
 *															*
 * Valor de retorno											*
 ************************************************************/
function Repaint(mes,anio) {
	if (mes == "")
		this.pintaNumeritos(this.mesMostrado,anio);
	else
		this.pintaNumeritos(mes,this.anioMostrado);
}

/************************************************************
 * Método que pinta en el calendario la disposición de los	*
 * números dependiendo del mes y año indicado.				*
 * y pintando el mes y año inicial.							*
 *															*
 * Parámetros												*
 *	mes:		Mes del año que se está visualizando.		*
 *	anio:		Año que se visualiza.						*
 *															*
 * Valor de retorno											*
 ************************************************************/
function PintaNumeritos(mes,anio) {
	var diaSemana;

	// Vamos a ver el día de la semana que es el 1 del mes que nos dan.
	var fechaTemp = new Date(anio,mes-1,1);
	
	diaSemana = fechaTemp.getDay();
	
	fila = 1;
	columna = (diaSemana == 0) ? 7 : diaSemana;
	tempMes = fechaTemp.getMonth()+1;
	var texto;
	
	// Enseñamos la imagen si estamos en el mes y anio de la fecha seleccionada.
	var mostrarImagen = (this.fechaSeleccionada.getMonth()+1) == mes && this.fechaSeleccionada.getFullYear() == anio
	setVisibility('imagenSel',mostrarImagen,mostrarImagen);
	
	// Ocultamos los numeritos antes del día 1.
	for (var i = 1; i < columna; i++)
		setVisibility("n1,"+i+"n",false);
		
	// Pintamos los numeritos	
	for (var i = 1; tempMes == mes; i++) {
		texto = "<a href='javascript:"+this.nombre+".changeSelect("+'"'+fecha2string(fechaTemp)+'"'+")' class='" + this.claseNumerito + "'>" + i + "</a>"		
		escribeEnCapa("n"+fila+","+columna+"n",texto);
		
		// Ponemos visibles los numeritos.
		setVisibility("n"+fila+","+columna+"n",true,true);
		
		if (this.fechaSeleccionada.getDate() == i)
			this.colocaImagen(fila,columna);
		
		if (columna == 7) {
			columna = 1;
			fila++;
		}
		else
			columna++;
			
		fechaTemp.setDate(fechaTemp.getDate()+1);
		tempMes = fechaTemp.getMonth()+1;
			
	}
	
	// Ocultamos los que quedan.
	while (fila < 7) {
		setVisibility("n"+fila+","+columna+"n",false);
		
		if (columna == 7) {
			columna = 1;
			fila++;
		}
		else
			columna++;
	}
	
	var objAnio = findObj("calAnioL");
	var objMeses = findObj("calMesesS");
	objAnio.value = anio;
	objMeses.selectedIndex = mes - 1;
	
	this.mesMostrado = mes;
	this.anioMostrado = anio;
	
}

/************************************************************
 * Método que coloca la imagen de seleccionado en el día	*
 * que corresponde, localizado por las coordenadas fila,	*
 * columna.													*
 *															*
 * Parámetros												*
 *	fila:		Indica la posición del día con respecto a	*
 *				la semana.									*
 *	columna:	Indica la posición del día con respecto al	*
 *				día de la semana.							*
 *															*
 * Valor de retorno											*
 ************************************************************/
function ColocaImagen(fila,columna) {
	var posx;
	var posy;
	
	posx = this.HMARGEN+(columna-1)*(this.ANCHO_COL+this.HSPACE);
	posy = this.VMARGEN+fila*(this.ALTO_FILA+this.VSPACE)
	
	moverCapaA(posx,posy,'imagenSel');
}

/************************************************************
 * Método que cambia la fecha seleccionada del calendario,	*
 * moviendo la imagen de seleccionado a la fecha indicada.	*
 *															*
 * Parámetros												*
 *	fecha:	Nueva fecha seleccionada.						*
 *															*
 * Valor de retorno											*
 ************************************************************/
function ChangeSelect(fecha) {
	var fila = 0;
	var columna;
	var obj = findObj(this.objName);
	
	var fechaTemp = string2fecha(fecha);
	
	columna = fechaTemp.getDay();	
	
	if (columna == 0)
		columna = 7;

	var dia = fechaTemp.getDate();

	// Hay que restar, primero la columna, y luego 7 cada vez.
	var resta = columna;


	while (dia >= 1) {
		fila++;			// Cada vez que restamos, aumentamos una fila.
		dia -= resta;
		resta = 7;
	}

	this.colocaImagen(fila,columna);
	this.fechaSeleccionada = fechaTemp;
	if (this.minDate != null) {
		if (comparaFechas(this.fechaSeleccionada,this.minDate)==-1) {
			this.fechaSeleccionada = this.minDate;
		}
	}
	if (this.maxDate != null) {
		if (comparaFechas(this.fechaSeleccionada,this.maxDate)==1) {
			this.fechaSeleccionada = this.maxDate;
		}
	}
	
	if (obj)
		obj.value = fecha2string(this.fechaSeleccionada);
		
	this.ocultar();
	// We gain the focus without calling the calendar.
	isShow=false;
	obj.focus();
}