function DateChooser( targetElement, callback, year, month, day )
{
	this.render = function( year, month )
	{
		var nextMonthMonth = ( month % 12 ) + 1;
		var nextMonthYear = month == 12 ? year + 1 : year;

		var previousMonthMonth = ( ( month + 10 ) % 12 ) + 1;
		var previousMonthYear = month == 1 ? year - 1 : year;

		var dateChooserHead = "<div class=\"datechooser\"><div class=\"datechoosertop\"><div class=\"datechoosertopcorner\"></div><div class=\"datechoosermain\"><table cellpadding=\"0\" cellspacing=\"1\"><thead><tr>";
		dateChooserHead += "<td width=\"25\"><a href=\"#\" onclick=\"DateChooser.getById(" + id + ").render( " + ( year - 1 ) + ", " + month + " ); return false;\">&lt;&lt;</a></td>";
		dateChooserHead += "<td width=\"25\"><a href=\"#\" onclick=\"DateChooser.getById(" + id + ").render( " + previousMonthYear + ", " + previousMonthMonth + " ); return false;\">&lt;</a></td>";
		dateChooserHead += "<td style=\"text-align: center;\" colspan=\"3\" width=\"75\" class=\"monthandyear\"><div style=\"text-align: center; width: 75px;\">${month} ${year}</div></td>";
		dateChooserHead += "<td width=\"25\"><a href=\"#\" onclick=\"DateChooser.getById(" + id + ").render( " + nextMonthYear + ", " + nextMonthMonth + " ); return false;\">&gt;</a></td>";
		dateChooserHead += "<td width=\"25\"><a href=\"#\" onclick=\"DateChooser.getById(" + id + ").render( " + ( year + 1 ) + ", " + month + " ); return false;\">&gt;&gt;</a></td></tr></thead>";

		var monthNames = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
		var daysInMonth = new Array( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
		var daysInThisMonth = daysInMonth[month-1];
		var today = new Date();
		var todayDay = today.getFullYear() == year && today.getMonth()+1 == month ? today.getDate() : -1;
		var date = new Date( year, month-1, 1 );
		var startDay = (date.getDay()+6)%7;

		if( month == 2 && year % 4 == 0 && ( year % 100 != 0 || year % 400 == 0 ) )
		{
			daysInThisMonth++;
		}

		dateChooserHead = dateChooserHead.replace( "${year}", year ).replace( "${month}", monthNames[month-1] );

		var html = dateChooserHead;

		html += "<tbody><tr>";

    var pos;
    for( pos = 0; pos < startDay; pos++ ) {
			html += "<td width=\"25\" class=\"noday\">&nbsp;</td>";
    }

		for( day=0; day<daysInThisMonth; day++ ) {
			if( pos % 7 == 0 && pos != 0 ) {
				html += "</tr><tr>";
			}

      elementClass = ( ( pos % 7 ) < 5 ? "weekday" : "weekend" );
            if( this.selectedYear == year && this.selectedMonth == month && this.selectedDay == (day+1) ) {
                elementClass = "selectedday";
            } else if( todayDay == (day+1) ) {
                elementClass = "today";
            }
			html += "<td width=\"25\" class=\"" + elementClass + "\"><a href=\"#\" onclick=\"DateChooser.getById(" + id + ").choose( " + year + ", " + month + ", " + ( day + 1 ) + " ); return false;\">" + ( day + 1 ) + "</a></td>";

			pos++;
		}

		for( ; pos <= 42; pos++ ) {
			if( pos % 7 == 0 ) {
				html += "</tr>";
				break;
			}
			html += "<td width=\"25\" class=\"noday\">&nbsp;</td>";
		}

		html += "</tbody><tfoot><tr><td colspan=\"7\"><div style=\"text-align: center; width: 181px;\"><a href=\"#\" onclick=\"DateChooser.getById(" + id + ").close(); return false;\">Close</a></div></td></tr></tfoot></table></div></div></div>";

		targetElement.innerHTML = html;
	};

    this.getId = function()
    {
        return id;
    };

    this.setDate = function( year, month, day )
    {
        this.selectedYear = year;
        this.selectedMonth = month;
        this.selectedDay = day;
    };

	this.open = function()
	{
		this.render( this.selectedYear, this.selectedMonth );
        this.isOpen = true;
	};

	this.close = function()
	{
		targetElement.innerHTML = "";
        this.isOpen = false;
	};

	this.toggle = function()
	{
		if( this.isOpen )
        {
            this.close();
        }
        else
        {
            this.open();
        }
	};

	this.choose = function( year, month, day )
	{
        this.selectedYear = year;
        this.selectedMonth = month;
        this.selectedDay = day;

		this.callback( year, month, day );
	};


	{
        if( year == null || year == undefined || month == null || month == undefined || day == null || day == undefined )
        {
            var today = new Date();
            year = today.getFullYear();
            month = today.getMonth() + 1;
            day = today.getDate();
        }

        this.selectedYear = year;
        this.selectedMonth = month;
        this.selectedDay = day;

        this.isOpen = false;

		if( DateChooser.elements == undefined || DateChooser.elements == null )
		{
			DateChooser.elements = [];
		}
		if( DateChooser.elementsById == undefined || DateChooser.elementsById == null )
		{
			DateChooser.elementsById = {};
		}

		id = DateChooser.elements.length;

		if( typeof( targetElement ) == "string" )
		{
			targetElement = document.getElementById( targetElement );
		}

		this.targetElement = targetElement;

		this.callback = callback;

		DateChooser.elements.push( this );
        DateChooser.elementsById[targetElement.id] = this;
	}
}

DateChooser.getById = function( id )
{
	return DateChooser.elements[id];
};

DateChooser.getByElementId = function( id )
{
	return DateChooser.elementsById[id];
};

