	// Globals
	var selectedDates = new Array();
	var formFieldIds = new Array();
	var calActiveMonths = new Array();
	var calActiveYears = new Array();
	var today = new Date();
	var numDaysInWeek = 7;
	var daysInCalendar = 34; // Zero based, so one less than normal.
	var weekdayNames = new Array('Su','M','Tu','W','Th','F','Sa');
	var monthNames = new Array(
		'January',
		'February',
		'March',
		'April',
		'May',
		'June',
		'July',
		'August',
		'September',
		'October',
		'November',
		'December'
	);

	var abbrMonthNames = new Array(
		'Jan',
		'Feb',
		'Mar',
		'Apr',
		'May',
		'Jun',
		'Jul',
		'Aug',
		'Sep',
		'Oct',
		'Nov',
		'Dec'
	);


	// Used internally. Generates html code of a calendar, and returns it.
	function generateCalendarHTMLCode(year, month, calId, dateFieldId)
	{
		
		// Set some properties.
		formFieldIds[calId] = dateFieldId;
		calActiveMonths[calId] = month;
		calActiveYears[calId] = year;
		
		// Load the first day of the month.
		var cal_date = new Date(year, month, 1);
		var prev_date = new Date(year, cal_date.getMonth(), 1);
		var next_date = new Date(year, month + 1, 1);

		// Output header.
		htmlOutput = '<div class="row_title">';
		htmlOutput += '<div class="nav_box">';
		htmlOutput += '<a href="javascript:moveCalendarToPrevYear(' + "'" + calId + "'" + ')" title="Previous Year"><img src="includes/ISCalendar/arrow_dbl_left.gif" class="prev_year"></a>';
		htmlOutput += '<a href="javascript:moveCalendarToPrevMonth(' + "'" + calId + "'" + ')" title="Previous Month"><img src="includes/ISCalendar/arrow_sgl_left.gif" class="prev_mth"></a>';
		htmlOutput += '<a href="javascript:moveCalendarToNextYear(' + "'" + calId + "'" + ')" title="Next Year"><img src="includes/ISCalendar/arrow_dbl_right.gif" class="next_year"></a>';
		htmlOutput += '<a href="javascript:moveCalendarToNextMonth(' + "'" + calId + "'" + ')" title="Next Month"><img src="includes/ISCalendar/arrow_sgl_right.gif" class="next_mth"></a>';
		htmlOutput += monthNames[month] + " " + year;
		htmlOutput += '</div>';
		htmlOutput += '<a href="javascript:hideCalendar(\'' + calId + '\')" title="Close calendar"><img src="includes/ISCalendar/button_close.gif" class="button_close"></a>';
		htmlOutput += '</div>';
		
		// Output weekdays row.
		htmlOutput += '<div class="row_day_labels">';
		for ( i = 0; i < numDaysInWeek; i++ ) {
			htmlOutput += '<div class="day_label">' + weekdayNames[i] + '</div>';
		}
		htmlOutput += '</div>';
		
		// Output dates row
		htmlOutput += '<div class="row_dates">';
		
		// output date cells from end of prev month.
		prev_date.setDate( cal_date.getDate() - cal_date.getDay() );
		
		for ( i = 0; i < cal_date.getDay(); i++ ) {
			id = ' id="is_cal_day_' + calId + prev_date.getDate() + '"';
			js = 'selectDateInCalendar(\'' + calId + '\', new Date(' + prev_date.getFullYear() + ', ' + prev_date.getMonth() + ', ' + prev_date.getDate() + '))';
			label = prev_date.getDate();

			htmlOutput += '<a href="javascript:' + js + '" class="othermonth"' + id + '>';
			htmlOutput +=  label;
			htmlOutput += '</a>';
			
			// increment prev date
			prev_date.setDate(prev_date.getDate() + 1);
		}
		
		// Output days.
		for ( i = 0; i < daysInCalendar; i++ ) {
			
			if( cal_date.getDate() > i ) {
				
				// Prepare.
				id = ' id="is_cal_day_' + calId + cal_date.getDate() + '"';
				js = 'selectDateInCalendar(\'' + calId + '\', new Date(' + cal_date.getFullYear() + ', ' + cal_date.getMonth() + ', ' + cal_date.getDate() + '))';
				label = cal_date.getDate();

				className = "weekday";
				
				// Special CSS if it's weekend, today, or the selected date.
				if ( cal_date.getDay() == 0 || cal_date.getDay() == 6 ) className = "weekend";
				if ( isCalDatesAreIdentical(today, cal_date) ) className += " today";
				if ( isCalDatesAreIdentical(selectedDates[calId], cal_date) ) className += " currentday";
				
				htmlOutput += '<a href="javascript:' + js + '" class="' + className + '"' + id + '>';
				htmlOutput += label;
				htmlOutput += '</a>';
			}
			
			// Increment date.
			cal_date.setDate(cal_date.getDate() + 1);
		}
		
		if ( next_date.getDay() > 0 ) {
			// output date cells from start of next month.
			for ( i = next_date.getDay(); i < 7; i++ ) {
				id = ' id="is_cal_day_' + calId + next_date.getDate() + '"';
				js = 'selectDateInCalendar(\'' + calId + '\', new Date(' + next_date.getFullYear() + ', ' + next_date.getMonth() + ', ' + next_date.getDate() + '))';
				label = next_date.getDate();
	
				htmlOutput += '<a href="javascript:' + js + '" class="othermonth"' + id + '>';
				htmlOutput +=  label;
				htmlOutput += '</a>';
				
				next_date.setDate(next_date.getDate() + 1);
			}
		}
		
		
		
		// close out row_date tag.
		htmlOutput += '</div>';
		
		return htmlOutput;
	}
	
	// Used internaly, returns true if both dates are the same day
	function isCalDatesAreIdentical( dateOne, dateTwo ) {
		if ( dateOne.getYear() != dateTwo.getYear() ) return false;
		if ( dateOne.getMonth() != dateTwo.getMonth() ) return false;
		if ( dateOne.getDate() != dateTwo.getDate() ) return false;
		
		return true;
	}
	
	// Used internally. This is sent when a date cell is clicked on in the calendar.
	function selectDateInCalendar(calId, newDate)
	{
		// Get the elements we need to change.
		newSelectedEl = document.getElementById("is_cal_day_" + calId + newDate.getDate());
		oldSelectedEl = document.getElementById("is_cal_day_" + calId + selectedDates[calId].getDate());
		
		// Deselect old and select new elements in the calendar.
		if ( oldSelectedEl ) {
			oldSelectedEl.className = oldSelectedEl.className.replace(" currentday", "");
		}
		newSelectedEl.className = newSelectedEl.className + " currentday";
		
		// Change date.
		selectedDates[calId] = newDate;
		updateDateField(calId);
		
		// Hide calendar in a moment.
		setTimeout("hideCalendar('" + calId + "')", 500);
	}
	
	function updateDateField(calId)
	{
		newDate = selectedDates[calId];
		dateStr = newDate.getDate() + " " + abbrMonthNames[newDate.getMonth()] + " " + newDate.getFullYear();
		document.getElementById(formFieldIds[calId]).value = dateStr;
	}
	
	function moveCalendarToPrevYear(calId)
	{
		year = calActiveYears[calId] - 1;
		month = calActiveMonths[calId];

		html = generateCalendarHTMLCode(year, month, calId, formFieldIds[calId]);
		updateDateField(calId);
		
		theDiv = document.getElementById(calId).innerHTML = html;
	}
	
	function moveCalendarToNextYear(calId)
	{
		year = calActiveYears[calId] + 1;
		month = calActiveMonths[calId];

		html = generateCalendarHTMLCode(year, month, calId, formFieldIds[calId]);
		updateDateField(calId);
		
		theDiv = document.getElementById(calId).innerHTML = html;
	}
	
	function moveCalendarToPrevMonth(calId)
	{
		year = calActiveYears[calId];
		month = calActiveMonths[calId] - 1;
		if ( month < 0 ) {
			year = calActiveYears[calId] - 1;
			month = 11; // Zero based, so this is December.
		}
		
		html = generateCalendarHTMLCode(year, month, calId, formFieldIds[calId]);
		updateDateField(calId);
		
		theDiv = document.getElementById(calId).innerHTML = html;
	}
	
	function moveCalendarToNextMonth(calId)
	{
		year = calActiveYears[calId];
		month = calActiveMonths[calId] + 1;
		if ( month > 11 ) {
			year = calActiveYears[calId] + 1;
			month = 0; // Zero based, so this is January.
		}
		
		html = generateCalendarHTMLCode(year, month, calId, formFieldIds[calId]);
		updateDateField(calId);
		
		theDiv = document.getElementById(calId).innerHTML = html;
	}
	
	function showCalendar(calId)
	{
		calEl = document.getElementById(calId);
		
		if ( calEl.className.indexOf("visible") != -1 ) return;
		
		calEl.className = calEl.className + " visible";
	}
	
	function hideCalendar(calId)
	{
		calEl = document.getElementById(calId);
		calEl.className = calEl.className.replace(" visible", "");
	}