function SmartCalendarTag_isLeapYear(year) {
	var gregorianCutoverYear = -12219292800000;
	
	return year >= gregorianCutoverYear ?
		((year%4 == 0) && ((year%100 != 0) || (year%400 == 0))) : // Gregorian
		(year%4 == 0); // Julian
}


function SmartCalendarTag_get4DigitYear(param) {
	var tempYear = 0;
	
	if (typeof param == "number") {
		tempYear = param;
	} else {
		tempYear = param.getYear();
	}
				
	if (tempYear < 1900) {
		tempYear = tempYear + 1900;
	} 
				
	return tempYear;
}


function SmartCalendarTag_populateDayList( pDayField, monthIndex, year ) {
	var monthDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
	var daysInMonth = monthDays[monthIndex];
	var currentlySelectedIndex = pDayField.selectedIndex;

	if (monthIndex == 1 && SmartCalendarTag_isLeapYear(year) == true) {
		daysInMonth = 29;
	}
	
	var selectLen = pDayField.options.length;
	var oldSelectedIndex = pDayField.selectedIndex;
	
	// If the select list length matches days of the number of days in the month
	// than simply return.	No action is required.
	// Else if the length is greater than daysInMonth, we must remove extra elements.
	// Else we must add new ones.
	if (selectLen == daysInMonth) {
		return;
	} else if (selectLen > daysInMonth) {
		for (var i = (selectLen-1); i >= daysInMonth; i = i - 1) {
			pDayField.options[i] = null;
		}
		//daySelect.selectedIndex = daySelect.length - 1;
	} else {
		for (var i = selectLen + 1; i <= daysInMonth; i = i + 1) {
			pDayField.options[pDayField.length] = new Option(i, i, false, false);
		}
		//daySelect.selectedIndex = selectLen - 1;
	}

	if (oldSelectedIndex > (pDayField.length - 1)) {
		pDayField.selectedIndex = pDayField.length - 1;
	}
}


function SmartCalendarTag_monthOnChangeEvent( pOutputFormat, pResultField, pDayField, pMonthField, pYearField ) {
	SmartCalendarTag_populateDayList( pDayField, pMonthField.selectedIndex, pYearField.options[pYearField.selectedIndex].value );
	SmartCalendarTag_setResultFieldFromSelects( pOutputFormat, pResultField, pDayField, pMonthField, pYearField );
}


function SmartCalendarTag_dayOnChangeEvent( pOutputFormat, pResultField, pDayField, pMonthField, pYearField ) {
	SmartCalendarTag_setResultFieldFromSelects( pOutputFormat, pResultField, pDayField, pMonthField, pYearField );
}


function SmartCalendarTag_yearOnChangeEvent( pOutputFormat, pResultField, pDayField, pMonthField, pYearField ) {
	SmartCalendarTag_populateDayList( pDayField, pMonthField.selectedIndex, pYearField.options[pYearField.selectedIndex].value );
	SmartCalendarTag_setResultFieldFromSelects( pOutputFormat, pResultField, pDayField, pMonthField, pYearField );
}


function SmartCalendarTag_setResultFieldFromSelects( pOutputFormat, pResultField, pDayField, pMonthField, pYearField ) {
	var day		= new Number( pDayField.options[pDayField.selectedIndex].value );
	var month	= new Number( pMonthField.options[pMonthField.selectedIndex].value );
	var year	= new Number( pYearField.options[pYearField.selectedIndex].value );
	var result	= "";

	var resultDate = new Date( year, month, day );
	

	// Set the date in the window opener's form field as defined in the SmartCalendar object
	if (pResultField != null) {
		// If there's no format mask them simply set it in the opener's date field
		// associated with the SmartCalendar object.
		if (pOutputFormat == null || pOutputFormat.length == 0) {
			pResultField.value = resultDate;
		} else {
			var seperator = "/";
			var datePartTokens = ["yy", "yyyy", "m", "mm", "d", "dd"];

	
			// Extract the date format parts
			var dateParts = pOutputFormat.split( seperator );	
	
			// If the string isn't seperated by "/" then try "-"
			if (dateParts.length <= 1) {
				seperator = "-";
				dateParts = pOutputFormat.split( seperator );
		
				// It wasn't using "-" either then return error
				if (dateParts.length <= 1) {
					dateParts = null;
				}
			}

					
			if (dateParts == null) {
				pResultField.value = resultDate;
			}
						
			var formattedDate = "";
			for (var i = 0; i < dateParts.length; i++) {
				if (dateParts[i] == "yy") {
					
					var year = SmartCalendarTag_get4DigitYear( resultDate ) - 1900;
								
					if (year < 10) {
						formattedDate = formattedDate + "0";
					}
								
					formattedDate = formattedDate + year;
								
				} else if (dateParts[i] == "yyyy") {
							
					formattedDate = formattedDate + SmartCalendarTag_get4DigitYear( resultDate );
								
				} else if (dateParts[i] == "m") {
							
					formattedDate = formattedDate + (resultDate.getMonth() + 1);
								
				} else if (dateParts[i] == "mm") {
							
					if ((resultDate.getMonth() + 1) < 10) {
						formattedDate = formattedDate + "0";
					}
						
					formattedDate = formattedDate + (resultDate.getMonth() + 1);
								
				} else if (dateParts[i] == "d") {
							
					formattedDate = formattedDate + resultDate.getDate();
					
				} else if (dateParts[i] == "dd") {
							
					if (resultDate.getDate() < 10) {
						formattedDate = formattedDate + "0";
					}
								
					formattedDate = formattedDate + resultDate.getDate();
							
				}
							
				if (i != (dateParts.length - 1)) {
					formattedDate = formattedDate + seperator;
				}
			}
						
			pResultField.value = formattedDate;
		}
	}

} 


function SmartCalendarTag_setSelectsFromResultField( pOutputFormat, pResultField, pDayField, pMonthField, pYearField ) {
	var year	= null;
	var month	= null;
	var day		= null;
	var yearFound = false;
	var yearIndex = -1;
	var seperator = "/";
	var datePartTokens = ["yy", "yyyy", "m", "mm", "d", "dd"];


	
	// Extract the date format parts
	var maskParts = pOutputFormat.split( seperator );	
	
	// If the string isn't seperated by "/" then try "-"
	if (maskParts.length <= 1) {
		seperator = "-";
		maskParts = pOutputFormat.split( seperator );
		
		// It wasn't using "-" either then return error
		if (maskParts.length <= 1) {
			maskParts = null;
		}
	}


	if (maskParts == null) {
		alert( "SmartCalendarTag_setSelectsFromResultField():  Could not retrieve the mask parts." );
		return;
	}
	

	// Now that we know what the seperator for the output format is, split up the date result.
	var dateParts = pResultField.value.split( seperator );
	
	
	for (var i = 0; i < maskParts.length; i++) {

		if (maskParts[i] == "yy" || maskParts[i] == "yyyy") {
			var selectValueLength = pYearField.options[0].value.length;
					
			if ( (selectValueLength == 2 && dateParts[i].length == 2) ||
				 (selectValueLength == 4 && dateParts[i].length == 4) ) {
				 
				year = dateParts[i];
				
			} else if (selectValueLength == 2 && dateParts[i].length == 4) {
			
				year = new Number( dateParts[i] ) - 1900;
				
			} else if (selectValueLength == 4 && dateParts[i].length == 2) {
			
				year = new Number( dateParts[i] ) + 1900;
				
			} 

			
		} else if (maskParts[i] == "m" || maskParts[i] == "mm") {
							
			month = new Number( dateParts[i] );
								
		} else if (maskParts[i] == "d" || maskParts[i] == "dd") {

			day = new Number( dateParts[i] );
		}
	}
	
	
	
	if (year != null) {
		for (var i = 0; i < pYearField.options.length; i++) {
			if (pYearField.options[i].value == year) {
				yearIndex = i;
				yearFound = true;
				break;
			}
		}

		if (yearFound == true) {
			// Set the month select list selected index to whatever month was selected - 1 so it's zero based
			// This should in turn set-off the onchange event that will update the day select list.
			pMonthField.selectedIndex = (month - 1);

			// Upate the days list given the new month value
			SmartCalendarTag_populateDayList( pDayField, pMonthField.selectedIndex, pYearField.options[pYearField.selectedIndex].value );

			// Set the select list selected index to whatever day was return - 1 so it's zero based.
			pDayField.selectedIndex = (day - 1);

			pYearField.selectedIndex = yearIndex;
		}			
	}
}


function SmartCalendarTag_PreDisplayCallback(pSmartCalendar, pDayField, pMonthField, pYearField, pResultField ) {
	var outputFormat = pSmartCalendar.getOutputDateFormat();
	SmartCalendarTag_setResultFieldFromSelects( outputFormat, pResultField, pDayField, pMonthField, pYearField );
	
	// Set the SmartCalendar Initial Display date
	var year	= SmartCalendarTag_get4DigitYear( new Number( pYearField.options[pYearField.selectedIndex].value ).valueOf() );
	var month	= pMonthField.options[pMonthField.selectedIndex].value;
	var day		= pDayField.options[pDayField.selectedIndex].value;
	
	pSmartCalendar.setInitialDisplayDate( new Date( year, month, day ) );
}


function SmartCalendarTag_PostDisplayCallback(pSmartCalendar, pSelectedDate, pDayField, pMonthField, pYearField, pResultField ) {
	var outputFormat = pSmartCalendar.getOutputDateFormat();
	SmartCalendarTag_setSelectsFromResultField( outputFormat, pResultField, pDayField, pMonthField, pYearField );
}
