/**
 * <p>Title: calendar.js</p>
 * <p>Description: Javascript for calendar-related operations.</p>
 * <p>Copyright: Copyright (c) 2005</p>
 * <p>Company: Kreber Graphics, Inc.</p>
 * @author Charlie Reading
 */

// Includes
var calendar_js = 1;
var includes = ""; // ((typeof browser_js == 'undefined') ? " browser.js\n" : "");
if (includes != "")
{
	alert("calendar.js: you must first include:\n" + includes);
}

	// Years
	kYear_Sparse = -2;				// Allow missing elements (primarily for comparison)
	kYear_Any = -1;						// Any year
	kYear_Internal = 0;				// Use internally-specified year (not for repeating)
	kYear_Minimum = 1583;			// First full Gregorian calendar year

	// Special values for "cardinal"
	kCardinal_Last = 0;				// "last" <week>
	kCardinal_Minimum = 1;		// minimum value for cardinal
	kCardinal_Maximum = 5;		// maximum value for cardinal

	// Special values for "day-of-week"
	kDayOfWeek_Last = 0;			// "last" <day-of-week>

	// Observed
	kObserved_NotOnMask								= 0x0003;
	kObserved_MoveToMask							= 0x000C;
	kObserved_OnDayOnly								= 0x0000;
	kObserved_NotOnSaturday						= 0x0001;
	kObserved_NotOnSunday							= 0x0002;
	kObserved_NotOnSaturdayOrSunday		= 0x0003;
	kObserved_MoveToFridayOrMonday		= 0x0000;
	kObserved_MoveToFriday						= 0x0004;
	kObserved_MoveToMonday						= 0x0008;

	// Observed Every
	kObservedEvery_AllYears			= 1;

	// Day-of-week
	kDaysPerWeek = 7;
	kSunday = 1;
	kMonday = 2;
	kTuesday = 3;
	kWednesday = 4;
	kThursday = 5;
	kFriday = 6;
	kSaturday = 7;
	kDayOfWeek_ToIndex = [-1, 0, 1, 2, 3, 4, 5, 6];
	kDayOfWeek_FromIndex = [kSunday, kMonday, kTuesday, kWednesday,
			kThursday, kFriday, kSaturday];

	// Months
	kMonthsPerYear = 12;
	kJanuary = 1;
	kFebruary = 2;
	kMarch = 3;
	kApril = 4;
	kMay = 5;
	kJune = 6;
	kJuly = 7;
	kAugust = 8;
	kSeptember = 9;
	kOctober = 10;
	kNovember = 11;
	kDecember = 12;
	kMonth_ToIndex = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
	kMonth_FromIndex = [kJanuary, kFebruary, kMarch, kApril, kMay, kJune,
			kJuly, kAugust, kSeptember, kOctober, kNovember, kDecember];

	// Days
	kDaysInMonth_NormalYear = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	kDaysInMonth_LeapYear = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

	// Display Text
	kDayOfWeekNames = [ "Sunday", "Monday", "Tuesday", "Wednesday",
			"Thursday", "Friday", "Saturday"];
	kDayOfWeekNames_Short = ["Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat"];
	kDayOfWeekLetters = ["S", "M", "T", "W", "T", "F", "S"];
	kMonthNames = ["January", "February", "March", "April", "May", "June",
			"July", "August", "September", "October", "November", "December"];
	kMonthNames_Short = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
			"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];


	//
	// Is the given year a leap-year?
	//
	// @param year - calendar-year
	// @return TRUE if given year is leap year, FALSE if not.
	//
	function isLeapYear(year)
	{
		// Every 4 years,
		// EXCEPT every 100 years,
		// EXCEPT every 400 years
		var isLeap = ((year % 4 == 0)
				&& ((year % 100 != 0) || (year % 400 == 0)));
		return isLeap;
	}

	//
	// How many days in the given month/year?
	//
	// @param year - calendar-year
	// @param month (kJanuary-kDecember)
	// @return number of days
	//
	function daysInMonth(year, month)
	{
		var iMonth = kMonth_ToIndex[month];
		var days = ((isLeapYear(year))
				? kDaysInMonth_LeapYear[iMonth]
				: kDaysInMonth_NormalYear[iMonth]);
		return days;
	}

	//
	// Is the specified month/day valid? (valid if either normal or leap year)
	//
	// @param month - month (kJanuary-kDecember)
	// @param day - day
	// @return true if valid, false otherwise.
	//
	function isMonthDayValid(month, day)
	{
		var isValid = ((month >= kJanuary)
				&& (month <= kDecember)
				&& (day >= 1)
				&& (day <= Math.max(kDaysInMonth_NormalYear[kMonth_ToIndex[month]],
						kDaysInMonth_LeapYear[kMonth_ToIndex[month]])));
		return isValid;
	}

	//
	// Is the specified year/month/day valid?
	//
	// @param year - calendar-year (MUST be absolute)
	// @param month - month (kJanuary-kDecember)
	// @param day - day
	// @return true if valid, false otherwise.
	//
	function isYearMonthDayValid(year, month, day)
	{
		var isValid = ((year >= kYear_Minimum)
				&& (month >= kJanuary)
				&& (month <= kDecember)
				&& (day >= 1)
				&& (day <= daysInMonth(year, month)));
		return isValid;
	}
