	var debug = false;
	
	var months = new Array( "January",
							"February",
							"March",
							"April",
							"May",
							"June",
							"July",
							"August",
							"September",
							"October",
							"November",
							"December");
		

	function GenerateDateControl (name, datevalue, startyear, endyear)
	{
		m_GenerateDateTimeControl (name, datevalue, startyear, endyear, false, false, "");
	}


	function GenerateDateTimeControl (name, datevalue, startyear, endyear, defTime)
	{
		m_GenerateDateTimeControl (name, datevalue, startyear, endyear, false, true, defTime);
	}


	function GenerateShortDateControl (name, datevalue, startyear, endyear)
	{
		m_GenerateDateTimeControl (name,datevalue, startyear, endyear, true);
	}


	function GenerateShortDateTimeControl (name, datevalue, startyear, endyear, defTime)
	{
		m_GenerateDateTimeControl (name, datevalue, startyear, endyear, true, true, defTime);
	}


	
	function FormatDateObjForSQL2000(dateObj)
	{
		strMon = String(dateObj.getMonth() + 1) ;
		strDay = String(dateObj.getDate());
		strHr = String(dateObj.getHours());
		strMin = String(dateObj.getMinutes());
		strMon =  ( strMon.length < 2 ? "0" + strMon : strMon);
		strDay =  ( strDay.length < 2 ? "0" + strDay : strDay);
		strHr = (strHr.length < 2 ? "0" + strHr : strHr);
		strMin = (strMin.length < 2 ? "0" + strMin : strMin);
		
		return dateObj.getFullYear() + "-" + strMon + "-" + strDay + " " + strHr + ":" + strMin;
	}

						
	function FormatDate(dateStr)
	{
		// Assumes SQL Server 2000 format string yyyy-mm-ddThh:mm:ss.ddd
		if (dateStr.length < 10)
		{	// Not long enough to be valid
			return "";
		}
		else
		{
			dateStr = dateStr.substr(0,10);	// Remove time component
			
			arr = dateStr.split('-');
			
			intMonth = Number(arr[1]) - 1;
			
			return arr[2] + " " + months[intMonth] + " " + arr[0];
		}
	}
	
										
	function FormatDateTime(dateStr, use24HrTime)
	{
		var timeStr;
		var dateArr;
		var hrStr = "";
		var hrInt;
		var minStr = "";

		// Assumes SQL Server 2000 format string yyyy-mm-ddThh:mm:ss.ddd
		
		if (dateStr.length < 10)
		{	// Not long enough to be valid date
			return "";
		}
		else
		{
			timeStr = trim(dateStr.substr(10));	// Extract time component
			dateStr = FormatDate(dateStr);		// Format date component
			
			if (timeStr.length > 4)
			{	// Long enough to be a valid time
				hrStr = timeStr.substr(0,2);
				minStr = timeStr.substr(3,2);

				// Default is 12 hour time
				if (use24HrTime)
				{
					timeStr = hrStr + ":" +	minStr;
				}
				else
				{
					hrInt = Number(hrStr);

					if (hrInt == 0)
					{
						hrInt = 12;
						timeSuffix = "AM";
					}
					else
					{
						if (hrInt > 11)
						{
							hrInt = hrInt - 12;
							timeSuffix = " PM";
						}
						else
						{
							timeSuffix = " AM";
						}
					}
					timeStr = hrInt + ":" + minStr + timeSuffix;
				}
			}

			return dateStr + " " + timeStr;
		}
	}
	

	function ValidateDate (name, desc, warn)
	{
		var dateStr;
		var dateObj;
		var dayObj;
		var monthObj;
		var yearObj;
		var formObj;

		if (warn == null)
			{warnon = true;}
		else {warnon = warn;}

		formObj = m_GetParentForm (name);
		if (formObj)
		{
			dateObj = formObj.elements[name];
			dayObj = formObj.elements[name + "_day"];
			monthObj = formObj.elements[name + "_month"];
			yearObj = formObj.elements[name + "_year"];

			intDay = Number(dayObj.options[dayObj.selectedIndex].value);
			intMonth = Number(monthObj.options[monthObj.selectedIndex].value);
			intYear = Number(yearObj.options[yearObj.selectedIndex].value);
			
			if ( (intDay == 0) || (intMonth == 0) || (intYear == 0) )
			{
				dateObj.value = "";

				// Mandatory Date Check
				if (warnon)
				{
					if (confirm("A value has not been entered for " + desc + ".\n"
								+ "No value will be recorded for " + desc + ".\n\n"
								+ "Is this correct?"))
					{
						return true;
					}
					else
					{
						return false;
					}
				}
				else
				{	// Warn if part dates have been entered
					if  ((intDay + intMonth + intYear) > 0)
					{
						if (! confirm("A value has only been partly entered for " + desc + ".\n"
									+ "No value will be recorded for " + desc + ".\n\n"
									+ "Is this correct?"))
						{
							return false;
						}
					}
				}
				return true;
			}
			else
			{
				dateStr = String(intYear);
				dateStr = dateStr.concat("-", (intMonth < 10 ? "0" : ""),intMonth);
				dateStr = dateStr.concat("-", (intDay < 10 ? "0" : ""),intDay);
				dateObj.value = dateStr;

				var isLeapYear = ( ( intYear % 4 == 0) && ( ( intYear % 100 != 0) || (intYear % 400 == 0) ) )
			
				switch (Number(intMonth))
				{
					case 1:
					case 3:
					case 5:
					case 7:
					case 8:
					case 10:
					case 12:
						return true;
						break;
					case 4:
					case 6:
					case 9:
					case 11:
						if (intDay > 30)
						{
							alert (desc + " Error: " + months[intMonth - 1] + " has only 30 days!");
							return false;
						}
						return true;
						break;
					case 2:
						if ( (intDay <= 28) || ( (intDay <= 29) && isLeapYear) )
						{
							return true;
						}
						else
						{
							alert (desc + " Error: February has only " 
								+ (isLeapYear ? "29" : "28") + " days in a "
								+ (isLeapYear ? "leap" : "non-leap") + " year!");
							return false;
						}
					default:
						alert (desc + " RECOGNITION ERROR: The month value entered could"
						+ " not be recognised as a legitimate month!");
						return false;
				}	
			}
		}
		return false;	
	}


	function ValidateMandatoryDateTime (name, desc)
	{
		var dateObj;
		var hourObj;
		var minObj;
		var hourStr;
		var minStr;
		var formObj;

		formObj = m_GetParentForm (name);
		if ( formObj )
		{
			if (ValidateMandatoryDate (name, desc, formObj))
			{
				dateObj = formObj.elements[name];
				hourObj = formObj.elements[name + "_hour"];
				minObj = formObj.elements[name + "_minute"];

				hourStr = hourObj.options[hourObj.selectedIndex].value;
				minStr = minObj.options[minObj.selectedIndex].value;

				// Retrieve existing value but throw away existing time component and add time values
				dateObj.value = dateObj.value.substr(0,10) + " " + hourStr + ":" + minStr;  
				
				return true;
			}
			else
			{
				return false;
			}
		}
		else
		{
			return false;
		}
	}
	

	function ValidateMandatoryDate (name, desc, form)
	{
		var dateStr;
		var dateObj;
		var dayObj;
		var monthObj;
		var yearObj;
		var formObj;

		formObj = form || m_GetParentForm(name) ;
		if ( formObj )
		{		
			dateObj = formObj.elements[name];
			dayObj = formObj.elements[name + "_day"];
			monthObj = formObj.elements[name + "_month"];
			yearObj = formObj.elements[name + "_year"];

			intDay = Number(dayObj.options[dayObj.selectedIndex].value);
			intMonth = Number(monthObj.options[monthObj.selectedIndex].value);
			intYear = Number(yearObj.options[yearObj.selectedIndex].value);
			
			if ( (intDay == 0) || (intMonth == 0) || (intYear == 0) )
			{
				dateObj.value = "";

				// Mandatory Date Check
				alert("A complete date has not been entered for " + desc + ".\n"
								+ "Please enter the date.");
						return false;
			}
			else
			{
				dateStr = String(intYear);
				dateStr = dateStr.concat("-", (intMonth < 10 ? "0" : ""),intMonth);
				dateStr = dateStr.concat("-", (intDay < 10 ? "0" : ""),intDay);
				dateObj.value = dateStr;

				var isLeapYear = ( ( intYear % 4 == 0) && ( ( intYear % 100 != 0) || (intYear % 400 == 0) ) )
			
				switch (Number(intMonth))
				{
					case 1:
					case 3:
					case 5:
					case 7:
					case 8:
					case 10:
					case 12:
						return true;
						break;
					case 4:
					case 6:
					case 9:
					case 11:
						if (intDay > 30)
						{
							alert (desc + " Error: " + months[intMonth - 1] + " has only 30 days!");
							return false;
						}
						return true;
						break;
					case 2:
						if ( (intDay <= 28) || ((intDay == 29) && isLeapYear) )
						{
							return true;
						}
						else
						{
							alert (desc + " Error: February has only " 
								+ (isLeapYear ? "29" : "28") + " days in a "
								+ (isLeapYear ? "leap" : "non-leap") + " year!");
							return false;
						}
					default:
						alert (desc + " RECOGNITION ERROR: The month value entered could"
						+ " not be recognised as a legitimate month!");
						return false;
				}	
			}
		}
		return false;	
	}


	function CheckDate (name, desc, form)
	{
		var dateStr;
		var dateObj;
		var dayObj;
		var monthObj;
		var yearObj;
		var formObj;

		var errMsg = "";

		formObj = form || m_GetParentForm(name) ;
		if ( formObj )
		{		
			dateObj = formObj.elements[name];
			dayObj = formObj.elements[name + "_day"];
			monthObj = formObj.elements[name + "_month"];
			yearObj = formObj.elements[name + "_year"];

			intDay = Number(dayObj.options[dayObj.selectedIndex].value);
			intMonth = Number(monthObj.options[monthObj.selectedIndex].value);
			intYear = Number(yearObj.options[yearObj.selectedIndex].value);
			
			if ( (intDay == 0) || (intMonth == 0) || (intYear == 0) )
			{
				dateObj.value = "";
				return " ";
			}
			else
			{
				dateStr = String(intYear);
				dateStr = dateStr.concat("-", (intMonth < 10 ? "0" : ""),intMonth);
				dateStr = dateStr.concat("-", (intDay < 10 ? "0" : ""),intDay);
				dateObj.value = dateStr;

				var isLeapYear = ( ( intYear % 4 == 0) && ( ( intYear % 100 != 0) || (intYear % 400 == 0) ) )
			
				switch (Number(intMonth))
				{
					case 1:
					case 3:
					case 5:
					case 7:
					case 8:
					case 10:
					case 12:
						return errMsg;
						break;
					case 4:
					case 6:
					case 9:
					case 11:
						if (intDay > 30)
						{
							errMsg += desc + " Error: " + months[intMonth - 1] + " has only 30 days!";
							return errMsg;
						}
						return "";
						break;
					case 2:
						if ( (intDay <= 28) || ((intDay == 29) && isLeapYear) )
						{
							return errMsg;
						}
						else
						{
							errMsg += desc + " Error: February has only " 
								+ (isLeapYear ? "29" : "28") + " days in a "
								+ (isLeapYear ? "leap" : "non-leap") + " year!";
							return errMsg;
						}
					default:
						errMsg += desc + " RECOGNITION ERROR: The month value entered could"
						+ " not be recognised as a legitimate month!";
						return errMsg;
				}	
			}
		}
		errMsg += "Internal coding error: CheckDate\n";	
		return errMsg;
	}


	function m_GetParentForm(childName)
	{
		var formObj;

		for (var i = 0; i < document.forms.length; i++)
		{

			if (document.forms[i].elements[childName])
			{
				formObj = document.forms[i];
				break;
			}
		}
		if (!formObj)
		{
			alert ("Unable to determine form containing specified object: " + childName);
		}
		return formObj;
	}


	function m_GenerateHiddenControl (name, datevalue)
	{
		// Although SQL Server returns datetimes in yyyy-mm-ddThh:mm format it
		// throws an error if it receives a datetime with a 'T' in it so it is replaced with a ' '.
		re = new RegExp ("T","g");
		document.write("<INPUT TYPE='Hidden' Name='" + name + "' Value='" + datevalue.replace (re," ") + "'>");
	}


	function m_GenerateDayControl (name, intDay)
	{
		var i;

		document.write("<SELECT NAME='" + name + "_day'>");
		
		document.write("<OPTION VALUE='0'" + (0 == intDay ? " SELECTED " : "") + ">Day</OPTION>");
		for (i = 1; i <=31; i++)
		{
			selStr = (i == intDay ? " SELECTED " : "");
			document.write("<OPTION VALUE='" + i + "'" + selStr + ">" + i + "</OPTION>");
		}
		document.write("</SELECT>");
	}		


	function m_GenerateMonthControl (name, intMonth, useShortMonth)
	{
		var i;
		var optionText = "";

		document.write("<SELECT NAME='" + name + "_month'>");
				
		document.write("<OPTION VALUE='0'" + (0 == intMonth ? " SELECTED " : "") + ">Month</OPTION>");
		for (i = 1; i <= 12; i++)
		{
			selStr = (i == intMonth ? " SELECTED " : "");
			optionText = months[i-1];
			if (useShortMonth)
			{
				optionText = optionText.substr(0,3);
			}
			document.write("<OPTION VALUE='" + i + "'" + selStr + ">" + optionText + "</OPTION>"); 
		}
		document.write("</SELECT>");
	}	
		

	function m_GenerateYearControl (name, intYear, startyr, endyr)
	{
		var i;

		document.write("<SELECT NAME='" + name + "_year'>");
		document.write("<OPTION VALUE='0'" + (0 == intYear ? " SELECTED " : "") + ">Year</OPTION>");
		for (i = startyr; i <= endyr; i++)
		{
			selStr = (i == intYear ? " SELECTED " : "");
			document.write("<OPTION VALUE='" + i + "'" + selStr + ">" + i + "</OPTION>");
		}
		document.write("</SELECT>");
	}


	function m_GenerateHourControl (name, intHour)
	{
		var i;
		var optionStr;

		document.write("<SELECT NAME='" + name + "_hour'>");
		for (i = 0; i <= 23; i++)
		{
			selStr = (i == intHour ? " SELECTED " : "");
			optionStr = m_FormatTimeComponent(i);
			document.write("<OPTION VALUE='" + optionStr + "'" + selStr + ">" + optionStr + "</OPTION>");
		}
		document.write("</SELECT>");
	}


	function m_GenerateMinuteControl (name, intMin)
	{
		var optionStr;

		document.write("<SELECT NAME='" + name + "_minute'>");
		for (var i = 0; i <= 59; i++)
		{
			selStr = (i == intMin ? " SELECTED " : "");
			optionStr = m_FormatTimeComponent(i);
			document.write("<OPTION VALUE='" + optionStr + "'" + selStr + ">" + optionStr + "</OPTION>");
		}
		document.write("</SELECT>");
	}
	

	function m_FormatTimeComponent(value)
	{
		var strReturnValue = String(value);
		
		if (strReturnValue.length < 2)
		{
			strReturnValue = "0" + strReturnValue;
		}
		return strReturnValue;
	}


	function m_GenerateDateControl (name, datevalue, startyear, endyear, useShortMonth)
	{
		// datevalue assumed to be in MS SQL Server format
		// yyyy-mm-ddThh:mm:ss.ddd

		var yearStr;
		var monthStr;
		var dayStr;
		
		var intDay  = 0;
		var intMonth = 0;
		var intYear = 0;

		var startyr;
		var endyr;
		var today = new Date();
		
		startyr = startyear || 1900;
		if ( !(endyear) || (endyear.length < 1) )
		{
			endyr = today.getFullYear()+ 15;
		}
		else
		{
			endyr = endyear;
		}

		if (datevalue)
		{
			if (datevalue.toUpperCase() == "TODAY")
			{
				datevalue = new Date();
						
				intDay = datevalue.getDate();
				intMonth = datevalue.getMonth()+1;
				intYear = datevalue.getFullYear();
				
				datevalue = FormatDateObjForSQL2000(datevalue);
			}
			else		
			{
				if (datevalue.length >= 10) // Minimum length required for valid date
				{
					yearStr = datevalue.substr(0,4);
					monthStr = datevalue.substr(5,2);
					dayStr = datevalue.substr(8,2);
			
					intDay = Number(dayStr);
					intMonth = Number(monthStr);
					intYear = Number(yearStr);
				}
			}
		}
		else
		{
			datevalue = "";
		}

		m_GenerateHiddenControl(name, datevalue);

		m_GenerateDayControl(name, intDay);
		
		m_GenerateMonthControl(name, intMonth, useShortMonth);

		m_GenerateYearControl (name, intYear, startyr, endyr);
	}


	function m_GenerateDateTimeControl (name, datevalue, startyear, endyear, useShortMonth, showTime, defTime)
	{
		// datevalue assumed to be in MS SQL Server format
		// yyyy-mm-ddThh:mm:ss.ddd

		var formObj;
		var dateObj;

		m_GenerateDateControl (name, datevalue, startyear, endyear, useShortMonth);
		
		if (showTime)
		{
			formObj = m_GetParentForm(name);
			dateObj = formObj.elements[name];
			m_GenerateTimeControls(name, formObj, dateObj, defTime);
		}
	}


	function m_GenerateTimeControls(name, formObj, dateObj, defTime)
	{
		var hrStr;
		var minStr;
		var datevalue;
		
 		datevalue = dateObj.value;

		if (defTime && (defTime.length > 4) )
		{
			hrStr = defTime.substr(0,2);
			minStr = defTime.substr(3,2);
			dateObj.value = datevalue.substr(0,10) + hrStr + ":" + minStr;
		}
		else
		{
			hrStr = datevalue.substr(11,2);
			minStr = datevalue.substr(14,2);
		}
		var intHour = Number (hrStr);
		var intMin = Number (minStr);
		document.write ("&#160;&#160;Time:&#160;");
		m_GenerateHourControl (name, intHour);
		document.write (" : ");
		m_GenerateMinuteControl (name, intMin);
	}


	function GenerateDateControlHTML (name, datevalue, startyear, endyear)
	{
		var startyr;
		var endyr;
		var today = new Date();
		
		startyr = startyear || 1900;
		endyr = endyear || today.getFullYear()+ 15;
		
		var yearStr = datevalue.substr(0,4);
		var monthStr = datevalue.substr(5,2);
		var dayStr = datevalue.substr(8,2);
		
		var intDay = Number(dayStr);
		var intMonth = Number(monthStr);
		var intYear = Number(yearStr);
		
		var i;

		var strHTML;
		
		strHTML =	 "<INPUT TYPE='Hidden' Name='" + name + "' Value='" + datevalue + "'>"
				+	"<SELECT NAME='" + name + "_day'>"
				+	"<OPTION VALUE='0' SELECTED>Day</OPTION>";
		for (i = 1; i <=31; i++)
		{
			selStr = (i == intDay ? " SELECTED " : "");
			strHTML += "<OPTION VALUE='" + i + "'" + selStr + ">" + i + "</OPTION>";
		}
		strHTML += "</SELECT>";
		
		strHTML += "<SELECT NAME='" + name + "_month'>"
				+	"<OPTION VALUE='0' SELECTED>Month</OPTION>";
		for (i = 1; i <= 12; i++)
		{
			selStr = (i == intMonth ? " SELECTED " : "");
			strHTML += "<OPTION VALUE='" + i + "'" + selStr + ">" + months[i-1] + "</OPTION>"; 
		}
		strHTML += "</SELECT>";
		
		strHTML +=	 "<SELECT NAME='" + name + "_year'>"
				+	"<OPTION VALUE='0' SELECTED>Year</OPTION>";
		for (i = startyr; i <= endyr; i++)
		{
			selStr = (i == intYear ? " SELECTED " : "");
			strHTML += "<OPTION VALUE='" + i + "'" + selStr + ">" + i + "</OPTION>";
		}
		strHTML += "</SELECT>";
			
		return strHTML;
	}


	function trim(str)
	{
		var re_start = /^ +/;
		var re_end = / +$/;	
			
		return (str.replace(re_start,"")).replace(re_end,"");
	}


	function GenerateDurationControl (name, value, interval, maxValue)
	{
		// name 	-	is the name of the control
		// value 	-	is the current value (a number with the integer component representing hrs and the decimal mins)
		// interval -	is the interval to be used between displayed values
		// maxValue -	maximum value to be displayed

		var no_of_intervals = maxValue/interval;
		document.write ("<SELECT NAME='" + name + "'>");

		for (i = 1; i <=no_of_intervals; i++)
		{
			var optValue = i * interval;
			if ( ( i * interval) == value)
			{
				selStr = " SELECTED";
			}
			else
			{
				selStr = "";
			}
			document.write ("<OPTION VALUE='" + optValue + "'" + selStr + ">" + formatTimeFromDecimal(optValue) + "</OPTION>");
		}

		document.write("</SELECT>");
	}

	function formatTimeFromDecimal(decimalTimeValue)
	{
		// Input is assumed to a decimal time value in which the integer is hours and decimal is minutes
		var hrs = parseInt(String(decimalTimeValue));
		var mins = 60 * (decimalTimeValue - hrs);
		var returnStr = String(hrs) + ":" + (mins < 10 ? "0": "") + String(mins) + " hrs";

		return returnStr;
	}
