
    function Calendario ( fecha, fechaFin, panelCalendario, callBack , multiple )
    {


		this.DiasMes    = new Array ( 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 );
		this.Meses      = new Array ( "Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre" );
		this.DiasSemana = new Array ( "lun","mar","mie","jue","vie","sab","dom" );
		
		this.INCR_MAX_ANO = 5;

		this.calEstilo = new Array ( );
		this.calEstilo['txtDiasSemana'] = "calendario";
		this.calEstilo['txtDiaPasado']  = "calendarioDiaPasado";
		this.calEstilo['txtDia'] 		= "calendario";
		this.calEstilo['txtDiaOn'] 		= "calendarioDiaOn";
		this.calEstilo['DiaHueco'] 		= "calendario";
		this.calEstilo['txtMes'] 		= "calendario";
		this.calEstilo['diaMarcado'] 	= "calendarioDiaMarcado";
		this.calEstilo['diasWidth'] 	= "20";

		this.Imagen = new Array ( );

		this.Imagen['cambioFecha'] 	   = "";
		this.Imagen['mesSiguiente']    = "";
		this.Imagen['mesAnterior']     = "";
		this.Imagen['seleccionOK']     = "";
		this.Imagen['borrarSeleccion'] = "";


		this.diaMarcado      = new Array ( );
		this.fecha 	     	 = fecha.substring ( 0 , 8 );
		this.fechaInicio     = fecha.substring ( 0 , 8 );
		this.fechaFin 		 = this.fechaInicio;

		this.panelCalendario = panelCalendario;
		this.fnCallBack      = callBack;
		this.multiple        = multiple;
		this.diasVisibles    = true;
		this.diasActivos     = new Array ( );
		this.diasNoHabiles   = new Array ( );

		this.objCalendario = "calendario"; // por defecto, aunque se puede cambiar con SetObjetoCalendario

		this.selectAno = "calMesesAno";  // por defecto, aunque se puede cambiar con SetSelectCalendario
		this.selectMes = "calAnos";

		this.INICIAL_ID_DIA = "c_";

		this.fnCallBackCambioFecha = "";


    }

    Calendario.prototype.SetObjetoCalendario = function ( obj )
    {       
		this.objCalendario = obj;
    };

    Calendario.prototype.SetSelectCalendario = function ( selectAno, selectMes )
    {       
		this.selectAno = selectAno;
		this.selectMes = selectMes;
    };
    Calendario.prototype.DefineFechaInicio = function ( fecha )
    {       
		this.fechaInicio = fecha;

    };

    Calendario.prototype.SetMeses = function ( meses )
	{
		this.Meses = meses;
	}
    Calendario.prototype.SetDiasSemana = function ( dias )
	{
		this.DiasSemana = dias;
	}
	

    Calendario.prototype.DefineFechaFin = function ( fecha )
    {       
		if ( fecha == "" )
		{
			var aa  = this.fechaFin.substring ( 0 , 4 );
			var mes = this.fechaFin.substring ( 4 , 6 );
			var dd  = this.fechaFin.substring ( 6 , 8 );

			this.fechaFin = ( parseInt ( aa , 10 ) + this.INCR_MAX_ANO ) + "" + mes + dd;
		}else
		{
			this.fechaFin  = fecha.substring ( 0 , 8 );
		}

    };
    Calendario.prototype.SetDiasActivos = function ( lista )
    {       
		this.diasActivos = lista;
		if ( this.diasActivos.length > 0 )
		{
			this.diasVisibles = false;
		}else
		{
			this.diasVisibles = true;
		}
    };

    Calendario.prototype.CreateCalendario = function ( )
    {       

		var dd = this.fechaInicio.substring ( 6 , 8 );

		var mm = this.fecha.substring ( 4 , 6 );
		var aa = this.fecha.substring ( 0 , 4 );

		var ultimoDia = this.CalcularUltimoDiaMes ( mm , aa );
		var posDia1   = this.CalcularPosicionDia ( aa , mm , 1 );

		var salida = '<table border="0" cellspacing="0" cellpadding="2" >';
		salida +=  this.CabeceraMes ( mm , aa );

		salida += '<tr>';
		for ( var i=0; i < this.DiasSemana.length; i++ )
		{
			salida += '<td class="' + this.calEstilo['txtDiasSemana'] + '" align="center"><b>' + this.DiasSemana[i] + '</b></td>';
		}
		salida += '</tr>';

		var dia = 1;


		for ( var j=0; j < 6; j++ )
		{
			salida += '<tr >';
			for ( i = 1; i <= 7 ; i++ )
			{
				if ( ( i >= posDia1 ) && ( dia <= ultimoDia ))
				{
					if ( dia <= 9 )
					{
						var fechaVariable = aa + "" + mm + "0" + dia;
					}else
					{
						var fechaVariable = aa + "" + mm + "" + dia;
					}


					if ( ( parseInt ( fechaVariable , 10 ) < parseInt ( this.fechaInicio , 10 ) ) || ( parseInt ( fechaVariable , 10 ) > parseInt ( this.fechaFin , 10 ) ) )
					{
						var diaPasado = true;
					}else
					{
						var diaPasado = false;
					}
					salida += this.PintarDia ( dia, mm , aa , diaPasado );
					dia ++;
					posDia1 = 1;
				}else
				{
					salida += this.PintarDia ( "", "", "",  true );
				}
			}

			salida += "</tr>";
		}
		salida += "</table>";


		var cadena = '<table><tr><td>' + salida + '</td><td valign="bottom">' + this.ContenidoMultiple() + '</td></tr></table>';
		this.panelCalendario.innerHTML = cadena;
    };


    Calendario.prototype.Bisiesto = function ( Year )
    {
        if (((Year % 4)==0) && ((Year % 100)!=0) || ((Year % 400)==0))
		{
			return true;
		}else
		{
			return false;
		}
    };

    Calendario.prototype.CalcularUltimoDiaMes = function ( mes , ano )
    {
		var a = ( parseInt ( mes , 10 ) - 1 );
		var ultimoDia = this.DiasMes[a];
		if ( ( parseInt ( mes , 10 ) == 2 ) && ( this.Bisiesto ( ano ) ) )
		{
			ultimoDia = 29;
		}
		return ultimoDia;
    };

    Calendario.prototype.CalcularPosicionDia = function ( aa, mm, dd )
    {
		var fecha = new Date ( aa, ( mm - 1 ), dd );
		var pos = fecha.getDay();
		if ( pos == 0 )
		{	
			pos = 7;
		}
		return pos;
    };


    Calendario.prototype.CabeceraMes = function ( mm , aa )
    {
		var cadena = '<select class="select" name="' + this.selectMes + '" onChange="' + this.objCalendario + '.CambioFecha()">';
		for ( var i=0; i < this.Meses.length; i++ )
		{
			if ( ( i + 1 ) == parseInt ( mm , 10 ) )
			{
				var select = "selected";
			}else
			{
				var select = "";
			}
			if ( i < 9 ) // < 9 porque empezamos por 0
			{
				var valor = "0" + ( i + 1 );
			}else
			{
				var valor = ( i + 1 );
			}

			cadena += '<option value="' + valor + '" ' + select + '>' + this.Meses[i] + '</option>';
		}
		cadena += '</select>';

		cadena += '&nbsp;';

		cadena += '<select class="select" name="' + this.selectAno + '" onChange="' + this.objCalendario + '.CambioFecha()">';


		var i = this.fechaInicio.substring ( 0 , 4 );
		i = parseInt ( i , 10 );

		var maximo = this.fechaFin.substring ( 0 , 4 );
		maximo = parseInt ( maximo , 10 );

		for ( ; i <= maximo; i++ )
		{
			if ( i == aa )
			{
				cadena += '<option value="' + i + '" selected>' + i + '</option>';
			}else
			{
				cadena += '<option value="' + i + '">' + i + '</option>';
			}
		}
		cadena += '</select>';

		var cadena = '<tr class="' + this.calEstilo['txtMes'] + '">\
					<td colspan="7">\
					<table align="center">\
						<tr>\
						<td align="right" >' + this.PaginarMes("Anterior") + '</td>\
						<td align="center" nowrap >' + cadena + '</td>\
						<td align="left">'+ this.PaginarMes("Siguiente") +'</td>\
						</tr>\
					</table>\
					</td>\
					</tr>';
		return cadena;
    };

    Calendario.prototype.PintarDia = function ( dia, mes, ano, diaPasado )
    {

		var cadena = "";
		if  ( dia != "" )
		{
			if ( parseInt ( dia , 10 ) < 10 )
			{
				dia = new String ( "0" + dia );
			}

			var mFecha = ano + mes + dia;
			if ( diaPasado )
			{
				var tdEstilo = this.calEstilo['txtDiaPasado'];
				var idCelda = "";
				var callB = '';
			}else
			{
				var idCelda = 'id="' + this.INICIAL_ID_DIA + mFecha + '"';
				var callB = 'style="cursor:pointer" onMouseEnter="' + this.objCalendario + '.EstiloOnDia(\'' + mFecha + '\' , true)" onMouseLeave="' + this.objCalendario + '.EstiloOnDia(\'' + mFecha + '\' , false)" onClick="' + this.objCalendario + '.SelectDia(\''+mFecha+'\')" style="cursor:hand"';

				if ( this.IsDiaMarcado ( mFecha ) >= 0 )
				{
					var tdEstilo = this.calEstilo['diaMarcado'];
				}else
				{

		
					var tdEstilo = this.calEstilo['txtDia'];

					if ( this.IsDiaNoHabil ( mFecha ) )
					{
						var tdEstilo = this.calEstilo['txtDiaPasado'];
						callB = "";
					}else if ( ! this.IsDiaActivo ( mFecha ) )
					{
						tdEstilo = this.calEstilo['txtDiaPasado'];
						callB = "";
					}
		

				}
			}

			cadena = '<td ' + idCelda + ' align="center" class="' + tdEstilo + '" ' + callB + '>'+parseInt(dia,10)+'</td>';
		}else
		{
			cadena = '<td class="' + this.calEstilo['DiaHueco'] + '" >&nbsp;</td>';
		}
		return cadena;
    };

    Calendario.prototype.IsDiaMarcado = function ( dia  )
    {
		var rc = -1
		if ( this.multiple )
		{
			var total = this.diaMarcado.length;
		}else
		{
			var total = 1;
		}
	
		for ( var i=0; i < total; i++ )
		{
			if ( dia == this.diaMarcado[i] )
			{
				rc = i;
				break;
			}
		}
		return rc;
    };

    Calendario.prototype.IsDiaActivo = function ( dia  )
    {

		var rc = true;
		if ( ! this.diasVisibles )
		{
			rc = false;
			for ( var i=0; i < this.diasActivos.length; i++ )
			{
				if ( dia == this.diasActivos[i] )
				{
					rc = true;
					break;
				}
			}
		}
		return rc;
    };
    Calendario.prototype.IsDiaNoHabil = function ( dia  )
    {

		var rc = false;
		for ( var i=0; i < this.diasNoHabiles.length; i++ )
		{
			if ( dia == this.diasNoHabiles[i] )
			{
				rc = true;
				break;
			}
		}
		return rc;
    };



    Calendario.prototype.EstiloOnDia = function ( dia , opc )
    {


	    if ( this.IsDiaMarcado ( dia ) == -1 )
	    {
			try {
				var objCal = eval ( "document.all." + this.INICIAL_ID_DIA + dia );
				if ( opc )
				{
					objCal.className = this.calEstilo['txtDiaOn'];
				}else
				{
					objCal.className = this.calEstilo['txtDia'];
				}
			}catch ( e )
			{
			}
	    }
    };
    Calendario.prototype.EstiloDiaMarcado = function ( dia )
    {
		eval ( "document.all." + this.INICIAL_ID_DIA + dia + ".className = \"" + this.calEstilo['diaMarcado'] + "\" " );
    };


    Calendario.prototype.PaginarMes = function ( opc )
    {
		var cadena = "";
		if ( opc == "Siguiente" )
		{
			cadena = '<a href="#" onClick="' + this.objCalendario + '.AvMes()"><img src="' + this.Imagen['mesSiguiente'] + '" border="0" alt="Mes Siguiente"></a>';
		}
		if ( opc == "Anterior" )
		{
			cadena = '<a href="#" onClick="' + this.objCalendario + '.ReMes()"><img src="' + this.Imagen['mesAnterior'] + '" border="0" alt="Mes Anterior"></a>';
		}

		return cadena;
    };

    Calendario.prototype.CambioFecha = function ( )
	{

		var obj = eval ( "document.all." + this.selectMes );
		var mm = obj.value;

		obj = eval ( "document.all." + this.selectAno );
		var aa = obj.value;

		if ( typeof ( this.fnCallBackCambioFecha ) == "function" )
		{
			this.fnCallBackCambioFecha ( aa + "" + mm );
		}else
		{
			this.fecha = new String ( aa + "" + mm + "01" );
			eval ( this.objCalendario + ".CreateCalendario ( )" );
		}
	};

    Calendario.prototype.AvMes = function ( )
    {
		var mm = parseInt ( this.fecha.substring ( 4 , 6 ) , 10 );
		var aa = parseInt ( this.fecha.substring ( 0 , 4 ) , 10 );

		if ( mm == 12 )
		{
			aa ++;
			mm = 1;
		}else
		{
			mm++;
		}

		if ( parseInt ( mm , 10 ) < 10 )
		{
			mm = "0"+mm;
		}



		if ( typeof ( this.fnCallBackCambioFecha ) == "function" )
		{
			this.fnCallBackCambioFecha ( aa + "" + mm );
		}else
		{
			this.fecha = new String ( aa + "" + mm + "01" );
			eval ( this.objCalendario + ".CreateCalendario ( )" );
		}

    };
    Calendario.prototype.ReMes = function ( )
    {
		var mm = parseInt ( this.fecha.substring ( 4 , 6 ) , 10 );
		var aa = parseInt ( this.fecha.substring ( 0 , 4 ) , 10 );
		var dd = "01";

		if ( mm == 1 )
		{
			aa --;
			mm = 12;
		}else
		{
			mm--;
		}

		if ( mm < 10 )
		{
			mm = "0"+mm;
		}
		if ( ( mm == this.fechaInicio.substring ( 4 , 6 ) ) && ( aa == this.fechaInicio.substring( 0 , 4 ) ) )
		{
			dd = this.fechaInicio.substring ( 6 , 8 );
		}

		if ( typeof ( this.fnCallBackCambioFecha ) == "function" )
		{
			this.fnCallBackCambioFecha ( aa + "" + mm );
		}else
		{
			this.fecha = new String ( aa + "" + mm + "" + dd );
			eval ( this.objCalendario + ".CreateCalendario ( )" );
		}

    };
    Calendario.prototype.SelectDia = function ( mfecha )
    {

		var dia;
		var pos = this.IsDiaMarcado ( mfecha );


		if ( pos >= 0 )
		{
			if ( ! this.multiple )
			{
				// Desmarcamos 

				dia = this.diaMarcado[pos];
				this.diaMarcado.splice ( pos , 1 );
				this.EstiloOnDia ( dia , false );
			}

		}else
		{
			// Marcamos


			if ( ! this.multiple )
			{
				if ( this.diaMarcado.length > 0 )
				{
					if ( ( this.diaMarcado[0].substring ( 0 , 6 ) == this.fecha.substring ( 0 , 6 ) ) )
					{
						dia = this.diaMarcado[0];
						this.diaMarcado = new Array ( );
						this.EstiloOnDia ( dia , false );
					}
					this.diaMarcado = new Array ( );
				}
			}

			this.EstiloDiaMarcado ( mfecha );
			this.diaMarcado[this.diaMarcado.length] = mfecha;
		}

		if ( ! this.multiple )
		{
			this.EndProceso ( );
		}
    };

    Calendario.prototype.EndProceso = function ( )
    {
		if ( this.multiple )
		{
			this.diaMarcado.sort ( this.OrdenarDias );
			var lista = this.diaMarcado;
		}else
		{
			var lista = new Array ( );
			if ( this.diaMarcado.length > 0 )
			{
				lista[0] = this.diaMarcado[0];
			}
		}
		this.fnCallBack ( lista );
    };
    Calendario.prototype.MarcarMes = function ( )
    {


		var ddInicio = this.fechaInicio.substring ( 6 , 8 );
		var mmInicio = this.fechaInicio.substring ( 4 , 6 );
		var aaInicio = this.fechaInicio.substring ( 0 , 4 );

		var mm = this.fecha.substring ( 4 ,6 );
		var aa = this.fecha.substring ( 0 ,4 );


		var dia = 1;

		if ( ( mm == mmInicio ) && ( aa == aaInicio ) )
		{
			dia = ddInicio;
		}

		var ultimoDia = this.CalcularUltimoDiaMes ( mm , aa );

		for ( ; dia <= ultimoDia; dia++ )
		{
			if ( parseInt ( dia , 10 ) < 10 )
			{
				var mFecha = aa + mm + "0" + dia;
			}else
			{
				var mFecha = "" + aa + mm + dia;
			}
		
			this.SelectDia ( mFecha );
		}
    };
    Calendario.prototype.ResetMarcados = function ( )
    {

		this.diaMarcado = new Array ( );
		eval ( this.objCalendario + ".CreateCalendario ( )" );
    };

    Calendario.prototype.OrdenarDias = function ( arg0 , arg1 )
    {
	    if ( arg0 > arg1 )
	    {
			return 1;
	    }else
	    {
			return -1;
	    }

    }

	Calendario.prototype.ContenidoMultiple = function ( )
    {
		var cadena = '';
		if ( this.multiple )
		{
			cadena += '<table >';
			cadena += '<tr>';
			cadena += '<td align="center">&nbsp;<a href="#" onClick="' + this.objCalendario + '.ResetMarcados()"><img src="' + this.Imagen['borrarSeleccion'] + '" border="0" alt="Eliminar seleccion"></a></td>';
			cadena += '</tr>';
			cadena += '<tr>';
			cadena += '<td align="center">&nbsp;<a href="#" onClick="' + this.objCalendario + '.EndProceso()"><img src="' + this.Imagen['seleccionOK'] + '" border="0" alt="Aceptar seleccion"></a></td>';
			cadena += '</tr>';
			cadena += '</table>';
		}
		return cadena;
    };



