// some settings
var _FC_defaultCalendarSettings = {
	'months' 			: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
	'weekdays' 			: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
	'imagePath' 		: '/images/cal/',	// directory that has the images in.
	'calendarImage'		: 'cal.png',		// image to use as the calendar Icon.
	'nextImage'			: 'right.png',		// image for the next button to use.
	'previousImage'		: 'left.png',		// image for the previous button to use.
	'calendarId' 		: 'calendar', 		// best to set an id when creating the calendar otherwise this may not work as expected.
	'elementPrefix' 	: '_FCE_', 			// prefix for elements in the calendar to keep them unique.
	'highlightToday' 	: true, 			// highlight the today entry, this can be overridden in the stylesheet as well.
	'displayIcon' 		: true, 			// set to false, no calendar icon will be generated.
	'attachToOutput' 	: false,				// set to false will prevent attachment to the output text element.
	'returnFormat' 		: 'D/M/Y' 			// format of the return string.
}

// return format
// d = day with leading zeroes
// D = day without leading zeroes
// m = month with leading zeroes
// M = month without leading zeroes
// n = month from the above array
// y = 2 character year
// Y = 4 character year
// t = th, st, nd which ever is appropriate.

// set up the calendar
function calendar(passedSettings) {

	var imagePath;
	var calendarId;

	// sort out the values to use.
	var useSettings=_FC_defaultCalendarSettings;

	useSettings.textOutput = passedSettings.textOutput;

	// the calendar id
	calendarId=useSettings.elementPrefix + useSettings.textOutput;

	// see if this calendar is supposed to have an icon.
	if ( passedSettings.displayIcon ) {
		useSettings.displayIcon=passedSettings.displayIcon;
	}	

	// create the icon on the page if required.
	if ( useSettings.displayIcon ) {
		document.write('<img src="' + useSettings.imagePath + useSettings.calendarImage + '" alt="Open Calendar" class="_FC_CalendarIcon" id="' + calendarId + '" />');
		$(calendarId).observe('click', _FC_CalendarClickResponder);
	} 
	
	// attach to the output element if required.
	if ( useSettings.attachToOutput ) {
		$(useSettings.textOutput).observe('click', _FC_CalendarClickResponder);
	}
	document.write('<div id="' + calendarId + 'Calendar" class="_FC_Calendar _FC_CalendarBody" style=" display: none;"></div>');

	_FC_buildCalendar(calendarId + 'Calendar', new Date());

}

function _FC_CalendarClickResponder(event) {

	var useSettings=_FC_defaultCalendarSettings;

	var element=Event.element(event);
	var calendarId
	
	if ( element.tagName == 'IMG' ) {
		calendarId=element.identify();
	} else {
		calendarId=useSettings.elementPrefix + element.identify();
	}
	var workingCalendar=calendarId + 'Calendar';

	if ( $(workingCalendar).visible() ) {
		$(workingCalendar).hide();
		return true;
	}

	// work out where the calendar should appear.
	var calendarPosition =({
					'top' :0,
					'left' :0
					});

	var useSettings=_FC_defaultCalendarSettings;

	textOutputElement=calendarId.substring(useSettings.elementPrefix.length);

	calendarPosition.top = $(textOutputElement).cumulativeOffset().top + $(textOutputElement).getDimensions().height + 4;
	calendarPosition.left = $(textOutputElement).cumulativeOffset().left;

	// check that the calendar does not appear off the bottom of the page. 
	
	// get the maximum drop the calendar can have.
	maxSize=document.viewport.getHeight() + parseInt(document.viewport.getScrollOffsets().top);
	calendarBottom=calendarPosition.top+parseInt($(workingCalendar).getHeight());
	if ( calendarBottom > maxSize ) {
		var newTop=$(textOutputElement).cumulativeOffset().top - ( parseInt($(workingCalendar).getHeight()) + 12 );
		// as long as the new top is onscreen allow it to be set. 
		// this is to prevent calendars appearing off the top of the screen if the calendar is very large or the viewport very small.
		if ( newTop > 0 ) {
			calendarPosition.top = newTop;
		}
	}	

	// move it to location and show it.
	$(workingCalendar).setStyle({top: calendarPosition.top + 'px', left: calendarPosition.left + 'px'});
	$(workingCalendar).show();

}

function _FC_buildCalendar(divisionId, date) {

	var html='';
	var dateObject = date;

	var useSettings=_FC_defaultCalendarSettings;

	var textOutputElement=divisionId.substring(useSettings.elementPrefix.length, divisionId.length-8);

	if ( parseInt(dateObject.getDate()) != 1 ) {

		dateObject.setFullYear(dateObject.getFullYear(), dateObject.getMonth(), 01);

	}

	var currentMonth=parseInt(dateObject.getMonth());

	html += '<div class="_FC_CalendarHeader">';
	html += '<div class="_FC_CalendarPreviousMonth"><a href="#" onClick="return _FC_ChangeMonth(\'' + textOutputElement + '\', -1);"><img src="' + useSettings.imagePath + useSettings.previousImage + '" alt="<" /></a></div>';
	html += '<div class="_FC_CalendarHeaderText" id="' + divisionId + 'HeaderText">' + useSettings.months[dateObject.getMonth()] + ' ' + dateObject.getFullYear() + '</div>';
	html += '<div class="_FC_CalendarNextMonth"><a href="#" onClick="return _FC_ChangeMonth(\'' + textOutputElement + '\', 1);"><img src="' + useSettings.imagePath + useSettings.nextImage + '" alt=">" /></a></div>';
	html += '</div>';

	// hidden layers to hold the month and year.
	html += '<input type="hidden" id="' + divisionId + 'Month" value="' + dateObject.getMonth() + '" />';
	html += '<input type="hidden" id="' + divisionId + 'Year" value="' + dateObject.getFullYear() + '" />';

	// weekday headers.
	for ( looper=0; looper<7; looper++ ) {
		if ( looper == 0 || looper == 6 ) {
			html += '<div class="_FC_CalendarCellDayHeader _FC_CalendarCellWeekEnd">' + useSettings.weekdays[looper] + '</div>';
		} else {
			html += '<div class="_FC_CalendarCellDayHeader">' + useSettings.weekdays[looper] + '</div>';
		}
	}

	var totalCells=0;

	// pad the start of the run.
	var weekPad=parseInt(dateObject.getDay());
	for ( looper=1; looper<=weekPad; looper++ ) {
		totalCells++;
		if ( looper == 1 ) {
			html += '<div class="_FC_CalendarCellPad _FC_CalendarCellWeekEnd"></div>';
		} else {
			html += '<div class="_FC_CalendarCellPad"></div>';
		}
	}

	// work out the month length by asking for day 0 of the next month.
	nextMonth=new Date();
	nextMonth.setFullYear(dateObject.getFullYear(), currentMonth+1, 00);

	var testerDate=new Date();
	var today=new Date();
	for ( looper=1; looper<=parseInt(nextMonth.getDate()); looper++ ) {
		totalCells++;
		$weekendStyle='';
		testerDate.setFullYear(dateObject.getFullYear(), dateObject.getMonth(), looper);
		if ( testerDate.getDay() == 0 || testerDate.getDay() == 6 ) {
			$weekendStyle=' _FC_CalendarCellWeekEnd';
		}
		todayStyle='';
		if ( useSettings.highlightToday && today.getFullYear() == dateObject.getFullYear() && today.getMonth() == dateObject.getMonth() && today.getDate() == looper ) {
			todayStyle=' _FC_CalendarCellToday';
		}
		html += '<a href="#" onClick="return _FC_SetDate(\'' + textOutputElement + '\', ' + looper + ');"><div class="_FC_CalendarCell' + $weekendStyle + todayStyle + '">' + looper + '</div></a>';
	}

	var endPad=7-((weekPad+parseInt(nextMonth.getDate())) % 7);
    // end pad.
    if ( endPad < 7 ) {
		for ( looper=0; looper<endPad; looper++ ) {
			totalCells++;
			if ( looper == (endPad-1) ) {
				html += '<div class="_FC_CalendarCellPad _FC_CalendarCellWeekEnd"></div>';
			} else {
				html += '<div class="_FC_CalendarCellPad"></div>';
			}
		}
	}

	if ( totalCells == 35 ) {
		for ( looper=0; looper<7; looper++ ) {
			if ( looper == 0 || looper == 6 ) {
				html += '<div class="_FC_CalendarCellPad _FC_CalendarCellWeekEnd"></div>';
			} else {
				html += '<div class="_FC_CalendarCellPad"></div>';
			}
		}
	}

	$(divisionId).innerHTML=html;

}

function _FC_SetDate(outputElementName, daySupplied) {

	var useSettings=_FC_defaultCalendarSettings;
	var	calendarId=useSettings.elementPrefix + outputElementName;
	var divisionId=calendarId + 'Calendar';

	var outputText='';

	var monthElement=divisionId + 'Month';
	var month=1+parseInt($(monthElement).value);

	var yearElement=divisionId + 'Year';
	var year=$(yearElement).value;

	var day=parseInt(daySupplied);

	// the format set above is now broken down and processed character by character to 
	// format the date back into the return text element.
	format=useSettings.returnFormat.toArray();
	for ( looper=0; looper<format.length; looper++ ) {
		switch(format[looper]) {
			case 'd':
				outputText += day;
				break;    
			case 'D':
				if ( day < 10 ) {
					outputText += '0' + day;
				} else {
					outputText += day;
				}
				break;    
			case 'm':
				outputText += month;
				break;    
			case 'M':
				if ( month < 10 ) {
					outputText += '0' + month;
				} else {
					outputText += month;
				}
				break;    
			case 'n':
				outputText += useSettings.months[(month-1)];
				break;    
			case 't':
				if ( day == 1 ) {
					outputText += 'st';
				} else if ( day == 2 ) {
					outputText += 'nd';
				} else if ( day == 3 ) {
					outputText += 'rd';
				} else {
					outputText += 'th';
				}
				break;    
			case 'y':
				outputText += year.substring(2);
				break;    
			case 'Y':
				outputText += year;
				break;    
			default:
				// everything else is treated as a character to just carry across into the output.
				outputText += format[looper];
				break;
		}
	}
	
	$(outputElementName).value=outputText;

	$(divisionId).hide();

	return false;
}

function _FC_ChangeMonth(outputElementName, direction) {

	var useSettings=_FC_defaultCalendarSettings;
	var	calendarId=useSettings.elementPrefix + outputElementName;
	var divisionId=calendarId + 'Calendar';

	var monthElement=divisionId + 'Month';
	var month=parseInt($(monthElement).value);

	var yearElement=divisionId + 'Year';
	var year=$(yearElement).value;

	dateObject=new Date();
	dateObject.setFullYear(year, (month+parseInt(direction)), 01);

	_FC_buildCalendar(divisionId, dateObject);

	return false;

}

