Date.prototype.a_cero=function()
{
	this.setMilliseconds(0);
	this.setSeconds(0);
	this.setMinutes(0);
	this.setHours(0);
}


function Calendario_vf_extensible(v_className)
{
	this.mes=null;	//Se guarda internamente desde 0 a 11, por concordancia con el objeto Date. Se mete de 1 a 12.
	this.anho=null;

	this.primer_dia=null;	//Representan el primer y último dí­a a mostrar.
	this.ultimo_dia=null;
	this.dias=new Array();	//Será un array de dias...

	this.offset_dias=null; //Cantidad de dias que hay antes del primer lunes hábil.

	this.DOM_contenedor=null;	//Lo contiene todo...
	this.clase_DOM_contenedor=v_className;

	this.DOM_cabecera=null;	//Contenedor de la cabecera.
	this.DOM_calendario=null;	//Contenedor de los dí­as.

	this.dias_cabecera=Array('L', 'M', 'X', 'J', 'V', 'S', 'D');

	this.metodo_callback=null;
	this.metodo_recarga=null;

	this.crear_DOM();
}

Calendario_vf_extensible.prototype.configurar_calendario=function(v_mes, v_anho) 
{
	this.mes=v_mes;
	this.anho=v_anho;
}

Calendario_vf_extensible.prototype.configurar_callbacks=function(v_callback_dia, v_callback_recarga)
{
	this.metodo_callback=v_callback_dia;
	this.metodo_recarga=v_callback_recarga;
}

Calendario_vf_extensible.prototype.iniciar=function(){this.actualizar(this.v_mes, this.anho);}
Calendario_vf_extensible.prototype.adjuntar=function(v_elemento) {v_elemento.appendChild(this.DOM_contenedor);}
Calendario_vf_extensible.prototype.retirar=function() {if(this.DOM_contenedor.parentNode) this.DOM_contenedor.parentNode.removeChild(this.DOM_contenedor);}
Calendario_vf_extensible.prototype.crear_DOM=function()
{
	var i;

	this.DOM_contenedor=montar_elemento('div', this.clase_DOM_contenedor);

	//Rellenamos la cabecera...
	this.DOM_cabecera=montar_elemento('div', 'cabecera_calendario', null, this.DOM_contenedor);

	for(i=0; i<this.dias_cabecera.length; i++)
	{
		montar_elemento('div', 'dia', this.dias_cabecera[i], this.DOM_cabecera);
	}
	montar_elemento('div', 'clear', null, this.DOM_cabecera);

	//Rellenamos los dias..
	this.DOM_calendario=montar_elemento('div', 'contenedor_calendario', null, this.DOM_contenedor);
	montar_elemento('div', 'clear', null, this.DOM_contenedor); 	//Poner el clear...
}

Calendario_vf_extensible.prototype.actualizar=function(v_mes, v_anho) //v_mes entra como 0-11...
{
	this.inicializar_fechas(v_mes, v_anho);
	this.rellenar_dias_calendario();
}

Calendario_vf_extensible.prototype.dias_en_mes=function(v_mes, v_anho) //v_mes entra como 0-11...
{
	//Es año bisiesto?...
	var bisiesto=false;
	var dias_por_mes=Array(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

	if (v_anho % 400 == 0) bisiesto=true;
	else if(v_anho % 4 == 0 && v_anho % 100 != 0) bisiesto=true;

	if(bisiesto) dias_por_mes[1]=28;

	return dias_por_mes[v_mes];
}

Calendario_vf_extensible.prototype.inicializar_fechas=function(v_mes, v_anho)
{	
	//Inicializamos el mes y año...
	var temp=new Date();

	if(!v_mes || !v_anho)	//Por defecto es "Hoy".
	{
		this.mes=temp.getMonth();
		this.anho=temp.getFullYear();
	}
	else
	{
		this.mes=v_mes-1;
		this.anho=v_anho;
	}

	temp.setFullYear(this.anho, this.mes, 1);
	
	//Con el mes y año podemos calcular el primer lunes y el último domingo...
	//Básicamente desde "temp" (dí­a 1) vamos atrás hasta un Lunes y luego
	//hacia adelante desde el último dí­a del mes...	

	this.primer_dia=new Date();
	this.primer_dia.setFullYear(this.anho, this.mes, 1);	//No usamos =, parece que asigna referencias.

	this.ultimo_dia=new Date();
	this.ultimo_dia.setFullYear(this.anho, this.mes, this.dias_en_mes(this.mes, this.anho) );

	//El primer dí­a.
	var i=0;
	this.offset_dias=0;

	while(this.primer_dia.getDay() != 1)
	{
		this.primer_dia.setDate(this.primer_dia.getDate()-1);
		this.offset_dias++;
	}
	
	//El último dí­a.

	while(this.ultimo_dia.getDay() != 0)
	{
		this.ultimo_dia.setDate(this.ultimo_dia.getDate()+1);
	}

	this.primer_dia.a_cero();
	this.ultimo_dia.a_cero();
}

Calendario_vf_extensible.prototype.rellenar_dias_calendario=function()
{
	var aquello=this;
	var x=0;
	var l=this.dias.length;

	//Limpiar array de dias...

		
	//for(x in this.dias)
	for(x=0; x<l; x++)
	{
		this.dias[x].DOM_contenedor.onclick=null;
	}

	this.dias.splice(0, this.dias.length);

	//Limpiar los dias...
	eliminar_contenido(this.DOM_calendario);

	var temp=new Date();
	temp.setFullYear(this.primer_dia.getFullYear(),
	this.primer_dia.getMonth(), this.primer_dia.getDate());
	temp.a_cero();

	while(this.ultimo_dia >= temp)
	{
		//Si intentamos crear con temp pasamos una referencia de la fecha y TODAS se crean con la misma...
		var fecha_crear=new Date();

		fecha_crear.setFullYear(temp.getFullYear(), temp.getMonth(), temp.getDate());
		fecha_crear.a_cero();

		this.dias.push(this.crear_dia.call(this, fecha_crear));
		this.dias[this.dias.length-1].adjuntar(this.DOM_calendario);

		temp.setDate(temp.getDate()+1);
	}

	//Asignar los eventos...
	if(this.metodo_callback)
	{
		var l=this.dias.length;
		//for(x in this.dias)
		for(x=0; x<l; x++)
		{
			if(this.dias[x].fecha.getMonth() == this.mes)
			{
				this.asignar_metodo_dia(this.dias[x]);
			}
		}
	}

	if(this.metodo_recarga){this.metodo_recarga();}
}

Calendario_vf_extensible.prototype.obtener_dia_mes_actual=function(v_dia)
{
	var dia=parseInt(v_dia, 10);
	return this.dias[dia+this.offset_dias-1];
}

Calendario_vf_extensible.prototype.crear_dia=function(v_fecha_crear)
{
	return new this.Dia(v_fecha_crear, this);
}

Calendario_vf_extensible.prototype.asignar_metodo_dia=function(v_dia)
{
	var aquello=this;
	v_dia.DOM_dia.onclick=function(){aquello.metodo_callback.call(v_dia);}
}

/*
Se incluye una clase dí­a. Básicamente está aquí­ para poderla extender con más
funcionalidades. Cada uno de estos dí­as tiene el contenedor que se muestra en
en calendario y, por otro lado, los datos propios de la fecha.
*/

Calendario_vf_extensible.prototype.Dia=function(v_fecha, v_padre)
{
	this.padre=v_padre;
	this.fecha=v_fecha;

	this.DOM_contenedor=null;
	this.DOM_dia=null;
	this.crear();
}

Calendario_vf_extensible.prototype.Dia.prototype.extender=function(v_fecha, v_padre)
{
	this.padre=v_padre;
	this.fecha=v_fecha;

	this.DOM_contenedor=null;
	this.DOM_dia=null;

	this.adjuntar=Calendario_vf_extensible.prototype.Dia.prototype.adjuntar;
	this.crear=Calendario_vf_extensible.prototype.Dia.prototype.crear;
	this.clase_contenedor=Calendario_vf_extensible.prototype.Dia.prototype.clase_contenedor;
	this.clase_dia=Calendario_vf_extensible.prototype.Dia.prototype.clase_dia;
	this.contenido_dia=Calendario_vf_extensible.prototype.Dia.prototype.contenido_dia;
}

Calendario_vf_extensible.prototype.Dia.prototype.adjuntar=function(v_elemento) {v_elemento.appendChild(this.DOM_contenedor);}

Calendario_vf_extensible.prototype.Dia.prototype.crear=function()
{
	this.DOM_contenedor=montar_elemento('div', null, null, null);
	this.DOM_dia=montar_elemento('div', null, null, this.DOM_contenedor);

	this.clase_contenedor();
	this.clase_dia('dia');
	this.contenido_dia(this.fecha.getDate());
}

Calendario_vf_extensible.prototype.Dia.prototype.clase_contenedor=function(v_className)
{
	var extra_clase=v_className ? ' '+v_className : '';
	var clases='';
	var aquello=this;
	var hoy=new Date();
	hoy.a_cero();

	if(this.fecha.getDay()==1) clases+=' primero';
	else if(this.fecha.getDay()==0) clases+=' ultimo';

	if(this.fecha.getMonth()!=this.padre.mes) clases+=' otro_mes';
	if(this.fecha.getTime()==hoy.getTime()) clases+=' hoy';	//Milisegundos...

	this.DOM_contenedor.className='contenedor_dia '+clases+extra_clase;
}

Calendario_vf_extensible.prototype.Dia.prototype.clase_dia=function(v_className) {this.DOM_dia.className=v_className;}
Calendario_vf_extensible.prototype.Dia.prototype.contenido_dia=function(v_contenido) {this.DOM_dia.innerHTML=v_contenido;}

