////////////////////////////////////////////////////////////////
//  DateObject.js
//
//	A generic HTML Date object.
//
//	Create a new DateObject and call the MakeDateEntryField()
//	or the MakeBlankDateEntryField().  The only difference in 
//	these functions is the initail date set for the object.  
//
//	GetDate and SetDate() get and set the date.
//
//	When passing this data from a form use the 
//		<DateName>Hide		(Hidden Input) 
//	field to get the date that has been set.  It is stored in 
//	the following format: MM/DD/YYYY
//
//  Ryan Carroll, 1998/05/20
//	William Brownlow 1999/06/18
////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////
//  DaysInMonth (Month, Year)
//
//  Returns the number of days in the specified month.
//  Month is a number in the range 0 to 11
//  Year is a number
//  Returns a number in the range 28 to 31
/////////////////////////////////////////////////////
function DaysInMonth (Month, Year)
{
	MonthDate = new Date()
	TestDate = new Date(Year,Month,28,12,0,0)

	do 
	{	MonthDate.setTime(TestDate.getTime())
		TestDate.setTime(TestDate.getTime()+86400000)
	} while (MonthDate.getMonth() == TestDate.getMonth())

	return MonthDate.getDate()
}

//////////////////////////////////////////////////////////////////////////////////
//  MakeDateEntryField (FormName, DateName, InitialDate, OnChangeExpr, Nullable)
//
//	Creates an HTML/javascript Date-entry object in the specified HTML form. The
//	Number of days in the month updates automatically depending on the month and
//	year selection.
//	Adds two SELECT options and a TEXT INPUT field to the specified form.
//	The objects created have the following names:
//	<DateName>Month - SELECT list for month
//	<DateName>Day   - SELECT list for day
//	<DateName>Year  - TEXT INPUT field year
//
//	The OnChangeExpr can be set to a javascript expression, and it will be
//	evaluated AFTER each change to the date. OnChangeExpr must not contain any
//	quote charatcers - either single or double.
//	An error will occur if this function is called more than once in the same HTML
//	page with the same DateName argument.
//	The fields default to the specified day, or the current date if none is given.
//	If the Nullable argument is non-zero, the date object will be able to be
//	set to an empty date.  Otherwise a valid date will be required.
//
//	Changed 6/16/1999 William Brownlow: brownlow@wgbv.com
//	'Null' Blank data fields added to give users the option of not setting a date.
//
//////////////////////////////////////////////////////////////////////////////////
function MakeDateEntryField (FormName, DateName, Today, OnChangeExpr)
{
	// createFlag ensures that only one DateEntryField can be
	// made from a single DateObject
	//		William Brownlow: brownlow@wgbv.com
	if (!(this.createFlag))
	{
		if (this.nullable && !Today) {
			strTemp = ""
		}
		else {
			if (!Today) Today = new Date()
			if (OnChangeExpr == null) OnChangeExpr = ""
			ThisDay = Today.getDate()
			ThisMonth = Today.getMonth()
			ThisYear = Today.getFullYear()

			strDay = new String(ThisDay)
			if (strDay.length == 1) strDay = '0' + strDay
			ThisMonth += 1
			strMonth = new String(ThisMonth)
			if (strMonth.length == 1) strMonth = '0' + strMonth
			ThisMonth -= 1

			strTemp = strMonth + '/' + strDay + '/' + ThisYear
		}

		//  Write the Hidden Field
		document.writeln('<INPUT TYPE="HIDDEN" NAME="' + DateName + 'Hide" VALUE="' + strTemp + '">')

		//	Write the Month selection list
		document.writeln('<SELECT NAME="' + DateName + 'Month" OnChange="UpdateDate(document.' + 
			FormName + '.' + DateName + 'Month,document.' + FormName + '.' + DateName + 'Day,' +
			'document.' + FormName + '.' + DateName + 'Year,document.' + FormName + '.' + 
			DateName + 'Hide,\'' + OnChangeExpr + '\',' + this.nullable + ')">')

		if (this.nullable)
		{	document.write('<OPTION VALUE="0"')
			document.writeln('>')
		}
		document.write('<OPTION VALUE="1"')
		if (ThisMonth == 0) document.write(' SELECTED')
		document.writeln('>January')
		document.write('<OPTION VALUE="2"')
		if (ThisMonth == 1) document.write(' SELECTED')
		document.writeln('>February')
		document.write('<OPTION VALUE="3"')
		if (ThisMonth == 2) document.write(' SELECTED')
		document.writeln('>March')
		document.write('<OPTION VALUE="4"')
		if (ThisMonth == 3) document.write(' SELECTED')
		document.writeln('>April')
		document.write('<OPTION VALUE="5"')
		if (ThisMonth == 4) document.write(' SELECTED')
		document.writeln('>May')
		document.write('<OPTION VALUE="6"')
		if (ThisMonth == 5) document.write(' SELECTED')
		document.writeln('>June')
		document.write('<OPTION VALUE="7"')
		if (ThisMonth == 6) document.write(' SELECTED')
		document.writeln('>July')
		document.write('<OPTION VALUE="8"')
		if (ThisMonth == 7) document.write(' SELECTED')
		document.writeln('>August')
		document.write('<OPTION VALUE="9"')
		if (ThisMonth == 8) document.write(' SELECTED')
		document.writeln('>September')
		document.write('<OPTION VALUE="10"')
		if (ThisMonth == 9) document.write(' SELECTED')
		document.writeln('>October')
		document.write('<OPTION VALUE="11"')
		if (ThisMonth == 10) document.write(' SELECTED')
		document.writeln('>November')
		document.write('<OPTION VALUE="12"')
		if (ThisMonth == 11) document.write(' SELECTED')
		document.writeln('>December')
		document.writeln('</SELECT>')

		//	Write the day selection list
		document.writeln('<SELECT NAME="' + DateName + 'Day" OnChange="UpdateDate(' +
			'document.' + FormName + '.' + DateName + 'Month,document.' + FormName + '.' +
			DateName + 'Day,document.' + FormName + '.' + DateName + 'Year,document.' + FormName + '.' + DateName + 'Hide,\'' +
			OnChangeExpr + '\',' + this.nullable + ')">')
		NumDays = DaysInMonth(ThisMonth,ThisYear)
		
		if (this.nullable) document.write('<OPTION>')
		for (i=1; i<=NumDays; i++)
		{
			document.write('<OPTION')
			if (ThisDay == (i)) document.write(' SELECTED')
			document.writeln('>' + i)
		}
		document.writeln('</SELECT>')

		//	Write the year type-in box
		document.writeln('<INPUT NAME="' + DateName + 'Year" TYPE="TEXT" Value="' +
			ThisYear + '" SIZE="4" MAXLENGTH="4" OnBlur="UpdateDate(' +
			'document.' + FormName + '.' + DateName + 'Month,document.' + FormName + '.' +
			DateName + 'Day,document.' + FormName + '.' + DateName + 'Year,document.' + FormName + '.' + DateName + 'Hide,\'' +
			OnChangeExpr + '\',' + this.nullable + ')">');
			
		this.createFlag = 1;
	}
	else
	{
		alert("Date Field may \nonly be created \nonce")
	}
}


////////////////////////////////////////////////////////////////////////
//	MakeBlankDateEntryField (FormName, DateName, OnChangeExpr)
//	Function facilitates making a blank DateEntry Field
//
//	Added 6/16/1999 William Brownlow: brownlow@wgbv.com
////////////////////////////////////////////////////////////////////////

function MakeBlankDateEntryField (FormName, DateName, OnChangeExpr)
{
	this.MakeDateEntryField(FormName, DateName, (new Date()), OnChangeExpr)
	if (this.nullable) this.SetDate(FormName, DateName)
}

////////////////////////////////////////////////////////////////////////
//	GoodFromNull(MonthSelect, DaySelect, YearBox)
//	This function provides the functionality to reset the values in the
//	DateEntryField to a valid date when it is set as Null
//
//	Added 6/16/1999 William Brownlow: brownlow@wgbv.com
////////////////////////////////////////////////////////////////////////
function GoodFromNull(MonthSelect, DaySelect, YearBox)
{
	Month = MonthSelect.selectedIndex - 1
	Day = DaySelect.selectedIndex
	Year = parseInt(YearBox.value)
	
	if (Day < 1) Day = 1

	if (Month < 0) Month = 0

	if (isNaN(Year)) Year = (new Date()).getFullYear()
	YearBox.value = Year

	//	Delete days 29 through 31 (if they exist)
	for (i=DaySelect.length; i>29; i--)
	{	DaySelect.options[i-1] = null
	}
	//	Add back the days that are needed
	NumDays = DaysInMonth(Month,Year)+1
	for (i=30; i<=NumDays; i++)
	{	DaySelect.options[i-1] = new Option((i-1),(i-1))
	}

	MonthSelect.selectedIndex = (Month + 1)

	//	Ensure that the correct day is selected
	if (Day <= DaySelect.length) 
		DaySelect.options[Day].selected = true
	else 
		DaySelect.options[DaySelect.length-1].selected = true
}


////////////////////////////////////////////////////////////////////////
//	NullFromGood(MonthSelect, DaySelect, YearBox)
//	This function blanks out the DateEntryField to Null
//	Setting the Hidden field is accomplished in the main UpdateDate 
//	Event Handler
//
//	Added 6/16/1999 William Brownlow: brownlow@wgbv.com
////////////////////////////////////////////////////////////////////////
function NullFromGood(MonthSelect, DaySelect, YearBox)
{
	// Null from Good

	//	Delete days 29 through 31 (if they exist)
	for (i=DaySelect.length; i>29; i--)
	{	DaySelect.options[i-1] = null
	}
	//	Add back days 29, 30, 31 
	for (i=30; i<=32; i++)
	{	DaySelect.options[i-1] = new Option((i-1),(i-1))
	}

	YearBox.value = ""
	MonthSelect.selectedIndex = 0
	DaySelect.selectedIndex = 0
}

////////////////////////////////////////////////////////////////////////
//	UpdateDate (MonthSelect, DaySelect, YearBox, OnChangeExpr)
//
//	Updates the number of days in the DaySelect object to reflect the
//	correct number of days for the month specified by the Month and Year
//	fields. This function is called automatically whenever the month or
//	year fields are altered. If OnChange Expr is present it is
//	interpreted as a javascript expression and evaluated AFTER the
//	update has been made. The expression must not contain any single or
//	double quote characters.
//
//	Changed 6/16/1999 William Brownlow: brownlow@wgbv.com
//	Function does several new things, but still maintains the same interface.
//	1)	Is now called when day field is altered, in addition to Month and Year
//	2)	Will adjust for a Blank Date field when it is set.
//	3)	Updates the hidden field to the date set.  If the date is blanked out
//			the hidden field is set to ""
//
////////////////////////////////////////////////////////////////////////
function UpdateDate (MonthSelect, DaySelect, YearBox, Hidden, OnChangeExpr, Nullable)
{
	if (Nullable)
		Month = MonthSelect.selectedIndex - 1
	else
		Month = MonthSelect.selectedIndex

	if (Nullable)
		Day = DaySelect.selectedIndex
	else
		Day = DaySelect.selectedIndex + 1

	Year = parseInt(YearBox.value, 10)

	if (Day < 0) Day = 1
	if (Month < 0) Month = 0
	MonthTemp = MonthSelect.selectedIndex
	DayTemp = DaySelect.selectedIndex
	YearTemp = YearBox.value

	if (Nullable)
	{	
		if ((MonthTemp) && (DayTemp) && (YearTemp == ""))
			NullFromGood(MonthSelect, DaySelect, YearBox)
		else 
		{
			if ((MonthTemp) && (!DayTemp) && (YearTemp != ""))
				NullFromGood(MonthSelect, DaySelect, YearBox)
			else
			{
				if ((!MonthTemp) && (DayTemp) && (YearTemp != ""))
					NullFromGood(MonthSelect, DaySelect, YearBox)
				else
				{
					if ((MonthTemp) && (!DayTemp) && (YearTemp == ""))
						GoodFromNull(MonthSelect, DaySelect, YearBox)
					else
					{
						if ((!MonthTemp) && (DayTemp) && (YearTemp == ""))
							GoodFromNull(MonthSelect, DaySelect, YearBox)
						else
						{
							if ((!MonthTemp) && (!DayTemp) && (YearTemp != ""))
								GoodFromNull(MonthSelect, DaySelect, YearBox)
							else
							{
								//	Delete days 29 through 31 (if they exist)
								for (i=DaySelect.length; i>29; i--)
								{	DaySelect.options[i-1] = null
								}
								//	Add back the days that are needed
								NumDays = DaysInMonth(Month,Year)+1
								for (i=30; i<=NumDays; i++)
								{	DaySelect.options[i-1] = new Option((i-1),(i-1))
								}
	
								//	Ensure that the correct day is selected
								if (Day <= DaySelect.length) DaySelect.options[Day].selected = true
								else DaySelect.options[DaySelect.length-1].selected = true
							}	
						}
					}
				}
			}
		}
		if (isNaN(YearBox.value) && YearBox.value != "")
		{
			Today = new Date()
			Year = Today.getFullYear()
			YearBox.value = Year
		}
	}
	else
	{
		NumDays = DaysInMonth(Month,Year)
		if(NumDays != DaySelect.length)
		{
			//	Delete days 29 through 31 (if they exist)
			for (i=DaySelect.length; i>27; i--)
			{	DaySelect.options[i] = null
			}

			//	Add back the days that are needed
			for (i=29; i<=NumDays; i++)
			{	DaySelect.options[i-1] = new Option((i),(i))
			}
		}
	
		//	Ensure that the correct day is selected
		if (Day <= DaySelect.length)
		{
			DaySelect.options[Day-1].selected = true
		}else{
			DaySelect.options[DaySelect.length-1].selected = true
		}

		if (isNaN(YearTemp) || YearTemp == "" || YearTemp < 1 || YearTemp > 9999)
		{
			Today = new Date()
			Year = Today.getFullYear()
		}
		
		YearBox.value = Year
	}

	Month = MonthSelect.selectedIndex
	Day = DaySelect.selectedIndex
	YearStr = YearBox.value
	if ((Month == 0) && (Day == 0) && (YearStr == ""))
	{
		Hidden.value = ""
	}
	else
	{
		if (!Nullable)
		{
			Day = DaySelect.selectedIndex + 1
			Month = MonthSelect.selectedIndex + 1
		}
		strDay = new String(Day)
		if (strDay.length == 1)
			strDay = '0' + strDay
		strMonth = new String(Month)
		if (strMonth.length == 1)
			strMonth = '0' + strMonth
		Year = parseInt(YearBox.value, 10)

		strTemp = strMonth + '/' + strDay + '/' + Year
		Hidden.value = strTemp
	}

	//	Now evaluate the user-supplied OnChange expression
	if (OnChangeExpr != null) eval(OnChangeExpr)
}

////////////////////////////////////////////////////////////////////////
//	SetDate (FormName, DateName, NewDate)
//
//	Sets the specified date object in the specified form to have the
//	specified date.
//
//	Changed 6/16/1999 William Brownlow: brownlow@wgbv.com
//	Now will accept only two arguments or an invalid date argument.  
//	This will cause the datefield to be set to Blank.
//	NOTE: Because UpdateDate() is called in both functions, the hidden 
//	field will be updated as well.
////////////////////////////////////////////////////////////////////////
function SetDate (FormName, DateName, NewDate)
{
	if (isNaN(NewDate))
	{
		//	Update the year
		updateYearCmd = "document." + FormName + "." + DateName + "Year.value = ''"
		eval(updateYearCmd)
		
		//	Update the month
		updateMonthCmd = "document." + FormName + "." + DateName + "Month.selectedIndex = 0"
		eval(updateMonthCmd)
		
		//	Update the day
		updateDayCmd = "document." + FormName + "." + DateName + "Day.selectedIndex = 0"
		eval(updateDayCmd)

		//	Update the day-select list so that it has the correct
		//	number of days for the new month
		updateDateCmd = "UpdateDate(document." + FormName + "." + DateName + "Month," +
			"document." + FormName + "." + DateName + "Day," +
			"document." + FormName + "." + DateName + "Year," +
			"document." + FormName + "." + DateName + "Hide, '', " + 
				this.nullable + ")"

		eval(updateDateCmd)
	}
	else
	{
		//	Update the month
		updateMonthCmd = "document." + FormName + "." + DateName + "Month.selectedIndex = " +
			(NewDate.getMonth())
		eval(updateMonthCmd)
		
		//	Update the year
		NewYear = NewDate.getFullYear()
		updateYearCmd = "document." + FormName + "." + DateName + "Year.value = '" +
			NewYear + "'"
		eval(updateYearCmd)

		//	Update the day-select list so that it has the correct
		//	number of days for the new month
		updateDateCmd = "UpdateDate(document." + FormName + "." + DateName + "Month," +
			"document." + FormName + "." + DateName + "Day," +
			"document." + FormName + "." + DateName + "Year, " +
			"document." + FormName + "." + DateName + "Hide, '', " + 
				this.nullable + ")"
		eval(updateDateCmd)

		//	Update the day
		updateDayCmd = "document." + FormName + "." + DateName + "Day.selectedIndex = " +
			((NewDate.getDate())-1)
		eval(updateDayCmd)
	}
}


////////////////////////////////////////////////////////////////////////
//	GetDate (FormName, DateName)
//
//	Returns a Date object representing the current setting of the
//	specified date object.
//
//	Changed 6/16/1999 William Brownlow: brownlow@wgbv.com
//	Will return the NaN (Not a Number) constant for a blank datefield entry
//	REM: NaN can only be checked with the isNaN() function.
//
////////////////////////////////////////////////////////////////////////
function GetDate (FormName, DateName)
{
	var arrStrSplit, strDate, strhide;
	
	strhide = eval("document." + FormName + "." + DateName + "Hide.value")
	if (strhide == null)
	{
		dtmTemp = new Date()
		dtmTemp = null
		return dtmTemp
	}
	else
	{
		
		var slash="/"
		arrStrSplit = strhide.split(slash)
		strDate = new Date(parseInt(arrStrSplit[2], 10),((parseInt(arrStrSplit[0], 10))-1), parseInt(arrStrSplit[1], 10));
		return strDate
	}
}

//**********************************************************************
//	Function Name:	MakeTimeEntryField                                 *
//	                                                                   *
//	Creates a SELECT list in the specified HTML form for the time of   *
//	of day, in hourly increments.                                      *
//                                                                     *
//	Arguments:                                                         *
//		FormName	-	The name of the HTML form                      *
//		TimeName	-	The name that the SELECT list will have        *
//		StartIndex	-	The first time displayed in the SELECT list,   *
//						in seconds                                     *
//		EndIndex	-	The last time displayed in t he SELECT list,   *
//		OnChangeExpr-	An appropriate javascript expression           *
//						(optional)                                     *
//**********************************************************************
function MakeTimeEntryField(FormName, TimeName, StartIndex, EndIndex, OnChangeExpr)
{
	var display_hour = 12

	if(StartIndex > 0) display_hour = 1

	//	create the selection list for the beginning time
	if(OnChangeExpr != null) 
	{	document.writeln('<SELECT Name="' + TimeName + 'Time" OnChange="' + OnChangeExpr+ '">')
	}
	else 
	{	document.writeln('<SELECT Name="' + TimeName + 'Time">')
	}
	for(i = StartIndex ; i < EndIndex ; i += 3600) 
	{	if(i < 43200 ) 
		{	document.writeln('<OPTION Value="' + i + '">' + display_hour + ':00 AM</OPTION>')
		}
		else if(i == 86399) 
		{	document.writeln('<OPTION Value="' + i + '">Midnight</OPTION>')
		}
		else 
		{	document.writeln('<OPTION Value="' + i + '">' + display_hour + ':00 PM</OPTION>')
		}

		if(display_hour == 12) 
		{	display_hour = 1
		}
		else 
		{	display_hour++
		}
	}

	document.writeln('</SELECT')

	return
}

//////////////////////////////////////////////////////////////////////////////////
//	Added 6/16/1999 William Brownlow: brownlow@wgbv.com
//
//  1999/10/13 13:40  -  Ryan Carroll
//		Added "nullable" property and removed "length" property.
//////////////////////////////////////////////////////////////////////////////////
function DateObject(Nullable)
{
	this.nullable = Nullable
	if (isNaN(Nullable)) this.nullable = 0
	this.createFlag = 0;
	this.MakeDateEntryField = MakeDateEntryField;
	this.MakeBlankDateEntryField = MakeBlankDateEntryField;
	this.SetDate = SetDate;
	this.GetDate = GetDate;
}

function TimeObject(Nullable)
{
	this.nullable = Nullable
	if (isNaN(Nullable)) this.nullable = 0
	this.createFlag = 0;
	this.MakeTimeEntryField = MakeTimeEntryField;
	this.MakeBlankDateEntryField = MakeBlankDateEntryField;
}
