// TimeInput(TimeName, Required*, TimeFormat(12/24)*, DefaultTime*, ChildTime*, ParentTime*, Date*, ChildDate*, ParentDate*)

// Customizable variables
var DefaultTimeFormat = 12; // If no time format is supplied, this will be used instead
var DefaultHour = 9; // If no default time is supplied, this hour will be used instead
var DefaultMinute = 00; // If no default time is supplied, this minute will be used instead
var DefaultAMPM = 'am'; // If no default time is supplied, this am/pm will be used instead - not used if DefaultTimeFormat = 24
var MinuteIncrement = 5; // Increment of available minutes
var UnselectedHourText = 'None'; // Text to display in the 1st hour list item when the time isn't required
var FontSize = 10; // In pixels
var FontFamily = 'Arial';
var SpacerURL = '/template/admin/images/spacer.gif';
var SpacerWidth = 4;

// Global variables
var Spacer = '<td valign="middle"><img src="'+ SpacerURL +'" width="' + SpacerWidth + '" height="' + SpacerWidth + '" border="0"></td>';

// Write out the stylesheet definition for the TimeInput
with (document) {
writeln('<style>');
writeln('td.timeInput {letter-spacing:normal;line-height:normal;font-family:' + FontFamily + ',Sans-Serif;font-size:' + FontSize + 'px;}');
writeln('select.timeInput {width:68px;letter-spacing:.06em;font-family:'+ FontFamily +',Sans-Serif;font-size:11px;}');
writeln('select.ampmInput {width:56px;letter-spacing:.06em;font-family:'+ FontFamily +',Sans-Serif;font-size:11px;}');
writeln('input.timeInput {width:50px;letter-spacing:.06em;font-family:'+ FontFamily +',Sans-Serif;font-size:11px;}');
writeln('</style>');
}

function getTimeArray(format,hour,minute,ampm) {
var returnArray = new Object();
var format = (isNaN(Number(format))) ? DefaultTimeFormat : Number(format);
var hour = (isNaN(Number(hour))) ? DefaultHour : Number(hour);
var minute = (isNaN(Number(minute))) ? DefaultMinute : Number(minute);
var ampm = ampm || false;
if (ampm) {
ampm = ampm.toLowerCase(ampm.replace(' ',''));
} else {
ampm = false;
}
// hour
if (hour > 23 || hour < 0) {
hour = 0;
}
// minute
minute = Math.round(parseInt(minute)/MinuteIncrement)*MinuteIncrement; // round to increment
if (minute > 59 || minute < 0) {
minute = 0;
}
if (!ampm) {
if (hour >= 12) {
ampm = 'pm';
} else {
ampm = 'am';
}
}
// format
if (format == 24) { // 24
if (hour < 12 && hour > 0 && ampm == 'pm') {
hour += 12;
}
if (hour == 12 && ampm == 'am') {
hour = 0;
}
ampm = '';
} else { // 12
if (hour == 0) {
hour = 12;
ampm = 'am';
}
if (hour > 12) {
hour -= 12;
ampm = 'pm';
}
} // end 12
returnArray['hour'] = hour;
returnArray['minute'] = minute;
returnArray['ampm'] = ampm;
return returnArray;
}

function parseTime(format,timeStr) {
var format = Number(format);
var timeStr = timeStr.replace(' ','');
timeStr = timeStr.toLowerCase();
if (/^(\d{1,2})(:)(\d{1,2})($|am|pm)$/.test(timeStr)) { // passed regex test
// ampm
var ampm = false;
var amPos = timeStr.indexOf('am');
var pmPos = timeStr.indexOf('pm');
if (amPos > -1 || pmPos > -1) {
var ampmStart = (pmPos > -1) ? pmPos : amPos;
ampm = timeStr.substr(ampmStart);
timeStr = timeStr.substr(0,ampmStart);
}
var splitTime = timeStr.split(':');
for (var i = 0; i < splitTime.length; i++) { // trim values
if (splitTime[i].length > 2) { // too long
splitTime[i] = splitTime[i].substr(0,2);
} // end too long
} // end trim values
var timeArray = getTimeArray(format,splitTime[0],splitTime[1],ampm);
} else { // failed regex test
var timeArray = getTimeArray(format,DefaultHour,DefaultMinute,DefaultAMPM);
} // end failed regex test
return timeArray;
}

function formatTime(format,hour,minute,ampm) {
var timeArray = getTimeArray(format,hour,minute,ampm);
hour = timeArray['hour'].toString();
minute = timeArray['minute'].toString();
ampm = timeArray['ampm'];
if (format == 24 && hour.length < 2) { // leading zero
hour = '0'+ hour;
} // end leading zero
if (minute.length < 2) { // leading zero
minute = '0'+ minute;
} // end leading zero
return hour +':'+ minute + ampm;
}

// Hides the input elements when the "blank" hour is selected
function SetTimeStatus(Hide) {
this.getMinuteList().style.visibility = (Hide) ? 'hidden' : 'visible';
var AMPMList = this.getAMPMList();
if (AMPMList) {
AMPMList.style.visibility = (Hide) ? 'hidden' : 'visible';
}
}

// sets the time, based on the hour selected
function CheckHourChange(HourList) {
var MinuteList = this.getMinuteList();
var AMPMList = this.getAMPMList();
if (HourList.options[HourList.selectedIndex].value == '') {
MinuteList.selectedIndex = 0;
if (AMPMList) {
AMPMList.selectedIndex = 0;
}
this.hideElements(true);
this.setHidden('');
} else {
this.hideElements(false);
AMPMValue = (AMPMList) ? AMPMList.options[AMPMList.selectedIndex].value : false;
this.setPicked(HourList.options[HourList.selectedIndex].value, MinuteList.options[MinuteList.selectedIndex].value, AMPMValue);
}
}

// sets the time, based on the minute selected
function CheckMinuteChange(MinuteList) {
var HourList = this.getHourList();
var AMPMList = this.getAMPMList();
AMPMValue = (AMPMList) ? AMPMList.options[AMPMList.selectedIndex].value : false;
this.setPicked(HourList.options[HourList.selectedIndex].value, MinuteList.options[MinuteList.selectedIndex].value, AMPMValue);
}

// sets the time, based on the ampm selected
function CheckAMPMChange(AMPMList) {
var HourList = this.getHourList();
var MinuteList = this.getMinuteList();
AMPMValue = (AMPMList) ? AMPMList.options[AMPMList.selectedIndex].value : false;
this.setPicked(HourList.options[HourList.selectedIndex].value, MinuteList.options[MinuteList.selectedIndex].value, AMPMValue);
}

// Keeps track of the time that goes into the hidden field
function storedTimeObject(TimeFormat, TimeHour, TimeMinute, TimeAMPM) {
this.format = TimeFormat;
this.formatted = formatTime(TimeFormat, TimeHour, TimeMinute, TimeAMPM);
this.military = formatTime(24, TimeHour, TimeMinute, TimeAMPM).replace(':','');
this.timeArray = parseTime(this.format, this.formatted);
this.hour = this.timeArray['hour'];
this.minute = this.timeArray['minute'];
this.ampm = this.timeArray['ampm'];
}

// Sets the current selected time
function SetPickedTime(PickedHour, PickedMinute, PickedAMPM) {
this.picked = new storedTimeObject(this.format, PickedHour, PickedMinute, PickedAMPM);
this.setHidden(this.picked.formatted);
}

// The time object
function timeObject(TimeName, TimeFormat, DefaultTime, ChildInputStr, ParentInputStr, DateStr, ChildDateStr, ParentDateStr) {

/* Properties */
this.hiddenFieldName = TimeName;
this.hourListID = TimeName + '_Hour_ID';
this.minuteListID = TimeName + '_Minute_ID';
this.ampmListID = TimeName + '_AMPM_ID';
this.objName = TimeName + '_Object';
this.formNumber = -1;
this.format = TimeFormat;
this.timeArray = null;
this.picked = null;
this.childInput = ChildInputStr;
this.parentInput = ParentInputStr;
this.dateInput = DateStr;
this.childDate = ChildDateStr;
this.parentDate = ParentDateStr;

/* Methods */
this.setPicked = SetPickedTime;
this.changeHour = CheckHourChange;
this.changeMinute = CheckMinuteChange;
this.changeAMPM = CheckAMPMChange;
this.hideElements = SetTimeStatus;
this.setHidden = new Function('D','if (this.formNumber >= 0) this.getHiddenField().value=D');
// Returns a reference to these elements
this.getHiddenField = new Function('return document.forms[this.formNumber].elements[this.hiddenFieldName]');
this.getHourList = new Function('return document.getElementById(this.hourListID)');
this.getMinuteList = new Function('return document.getElementById(this.minuteListID)');
this.getAMPMList = new Function('return document.getElementById(this.ampmListID)');

/* Constructor */
function SetGoodTime(TimeObj, Notify) { // Notifies the user about their bad default time, and sets the default time
TimeObj.setPicked(DefaultHour, DefaultMinute, DefaultAMPM);
if (Notify) alert('WARNING: The supplied time is not in valid \'' + TimeFormat + '\' format: ' + DefaultTime + '.\nThe default time will be used instead: ' + TimeObj.picked.formatted);
}
// Main part of the constructor
if (DefaultTime != '') {
if (/^(\d{1,2})(:)(\d{1,2})($|am|pm)$/.test(DefaultTime)) { // passed regex test
this.timeArray = parseTime(this.format,DefaultTime);
this.setPicked(this.timeArray['hour'], this.timeArray['minute'], this.timeArray['ampm']);
} else {
SetGoodTime(this, true);
}
}

}

// Main function that creates the form elements
function TimeInput(TimeName, Required, TimeFormat, DefaultTime, ChildInputStr, ParentInputStr, DateStr, ChildDateStr, ParentDateStr) {
if (arguments.length == 0) document.writeln('<span style="color:red;font-size:' + FontSize + 'px;font-family:' + FontFamily + ';">ERROR: Missing required parameter in call to \'TimeInput\': [name of hidden date field].</span>');
else {

var Required = Required || false;
var TimeFormat = TimeFormat || '';
var DefaultTime = DefaultTime || '';
var ChildInputStr = ChildInputStr || '';
var ParentInputStr = ParentInputStr || '';
var DateStr = DateStr || '';
var ChildDateStr = ChildDateStr || '';
var ParentDateStr = ParentDateStr || '';

// Handle TimeFormat
if (!TimeFormat) { // The format wasn't passed in, so use default
TimeFormat = DefaultTimeFormat;
}
else if (Number(TimeFormat) == 12 || Number(TimeFormat) == 24) TimeFormat = Number(TimeFormat);
else { // Passed-in TimeFormat was invalid, use default format instead
var AlertMessage = 'WARNING: The supplied time format for the \'' + TimeName + '\' field is not valid: ' + TimeFormat + '\nThe default time format will be used instead: ' + DefaultTimeFormat;
TimeFormat = DefaultTimeFormat;
if (DefaultTime) { // DefaultTime was passed in with an invalid time format
var UseTime = new storedTimeObject(TimeFormat, DefaultHour, DefaultMinute, DefaultAMPM);
AlertMessage += '\n\nThe supplied time (' + DefaultTime + ') cannot be interpreted with the invalid format.\nThe default time will be used instead: ' + UseTime.formatted;
DefaultTime = UseTime.formatted;
}
alert(AlertMessage);
}
// Define the default time if it wasn't set already
if (!UseTime) var UseTime = new storedTimeObject(TimeFormat, DefaultHour, DefaultMinute, DefaultAMPM);
// Handle DefaultTime
if (!DefaultTime) { // The time wasn't passed in
DefaultTime = (Required) ? UseTime.formatted : ''; // If required, use default time
}
// Creates the time object!
eval(TimeName + '_Object=new timeObject(\''+ TimeName +'\',\''+ TimeFormat +'\',\''+ DefaultTime +'\',\''+ ChildInputStr +'\',\''+ ParentInputStr +'\',\''+ DateStr +'\',\''+ ChildDateStr +'\',\''+ ParentDateStr +'\')');
// Determine initial viewable state of minute and ampm
if (Required || DefaultTime) {
var InitialStatus = '';
var InitialTime = eval(TimeName + '_Object.picked.formatted');
}
else {
var InitialStatus = ' style="visibility:hidden"';
var InitialTime = '';
eval(TimeName + '_Object.setPicked(' + DefaultHour + ',' + DefaultMinute + ',\'' + DefaultAMPM + '\')');
}
ParentChange = '';
if (ParentInputStr) {
ParentChange = ';DependentTime(\''+ ParentInputStr +'\',\''+ TimeName +'\',\''+ ParentDateStr +'\',\''+ DateStr +'\')';
}
ChildChange = '';
if (ChildInputStr) {
ChildChange = ';DependentTime(\''+ TimeName +'\',\''+ ChildInputStr +'\',\''+ DateStr +'\',\''+ ChildDateStr +'\')';
}
// Create the form elements
with (document) {
writeln('<input type="hidden" name="' + TimeName + '" id="' + TimeName + '" value="' + InitialTime + '" />');
// Find this form number
for (var f=0;f<forms.length;f++) {
for (var e=0;e<forms[f].elements.length;e++) {
if (typeof forms[f].elements[e].type == 'string') {
if ((forms[f].elements[e].type == 'hidden') && (forms[f].elements[e].name == TimeName)) {
eval(TimeName + '_Object.formNumber='+f);
break;
}
}
}
}
writeln('<table cellpadding="0" cellspacing="0" border="0" style="margin:0px"><tr>' + String.fromCharCode(13) + '<td valign="middle">');
writeln('<select class="timeInput" id="' + TimeName + '_Hour_ID" onchange="' + TimeName + '_Object.changeHour(this)'+ ChildChange + ParentChange +'">');
if (!Required) {
var NoneSelected = (DefaultTime == '') ? ' selected' : '';
writeln('<option value=""' + NoneSelected + '>' + UnselectedHourText + '</option>');
}
if (TimeFormat == 24) { // 24
var hourStart = 0;
var hourEnd = 23;
var leadZero = true;
} else { // 12
var hourStart = 1;
var hourEnd = 12;
var leadZero = false;
} // end 12
for (var i = hourStart;i <= hourEnd; i++) {
HourSelected = ((DefaultTime != '') && (eval(TimeName + '_Object.picked.hour') == i)) ? ' selected' : '';
var displayHour = i.toString();
if (displayHour.length < 2 && leadZero) {
displayHour = '0'+ displayHour;	
}
writeln('<option value="' + i + '"' + HourSelected + '>' + displayHour + '</option>');
}
writeln('</select>' + String.fromCharCode(13) + '</td>' + String.fromCharCode(13) + Spacer + '<td valign="middle">');
writeln('<select' + InitialStatus + ' class="timeInput" id="' + TimeName + '_Minute_ID" onChange="' + TimeName + '_Object.changeMinute(this)'+ ChildChange + ParentChange +'">');
for (var j = 0; j <= 59; j += MinuteIncrement) {
var displayMinute = j.toString();
if (displayMinute.length < 2) {
displayMinute = '0'+ displayMinute;	
}
MinuteSelected = ((DefaultTime != '') && (eval(TimeName + '_Object.picked.minute') == j)) ? ' selected' : '';
writeln('<option value="'+ j +'"' + MinuteSelected + '>' + displayMinute + '</option>');
}
writeln('</select>' + String.fromCharCode(13) + '</td>' + String.fromCharCode(13));
if (TimeFormat != 24) { // 12
writeln(Spacer + '<td valign="middle"><select' + InitialStatus + ' class="ampmInput" id="' + TimeName + '_AMPM_ID" onChange="' + TimeName + '_Object.changeAMPM(this)'+ ChildChange + ParentChange +'">');
PMSelected = ((DefaultTime != '') && (eval(TimeName + '_Object.picked.ampm') == 'pm')) ? ' selected' : '';
writeln('<option value="am">am</option>');
writeln('<option value="pm"' + PMSelected + '>pm</option>');
writeln('</select>' + String.fromCharCode(13) + '</td>' + String.fromCharCode(13));
} // end 12
writeln('</tr>' + String.fromCharCode(13) + '</table>');
}
}
}

function compareDependentTime(parentObject,childObject) {
var parentMilitary = parentObject.picked.military;
var childMilitary = childObject.picked.military;
if (parentMilitary > childMilitary) {
return true;
} else {
return false;
}
}

function setTimeListToValue(timeList,setValue) {
if (timeList) {
for (var i = 0; i < timeList.options.length; i++) {
var thisOptionValue = timeList.options[i].value;
if (thisOptionValue == setValue) {
timeList.options[i].selected = true;
break;
}
}
}
}

function childTimeToParentTime(parentObject,childObject) {
var timeArray = parseTime(childObject.format, parentObject.picked.formatted);
var childTime = childObject.getHiddenField();
var childHourList = childObject.getHourList();
var childMinuteList = childObject.getMinuteList();
var childAMPMList = childObject.getAMPMList();
setTimeListToValue(childHourList,timeArray['hour']);
setTimeListToValue(childMinuteList,timeArray['minute']);
setTimeListToValue(childAMPMList,timeArray['ampm']);
childObject.setPicked(timeArray['hour'], timeArray['minute'], timeArray['ampm']);
childTime.value = childObject.picked.formatted;
}

function DependentTime(parentObjectStr,childObjectStr,parentDateStr,childDateStr) {
if (document.getElementById(parentObjectStr) && document.getElementById(childObjectStr)) {
var parentObject = eval(parentObjectStr +'_Object');
var childObject = eval(childObjectStr +'_Object');
var compare = true;
var parentHourList = parentObject.getHourList();
var childHourList = childObject.getHourList();
if (parentHourList.options[parentHourList.selectedIndex].value == '' || childHourList.options[childHourList.selectedIndex].value == '') {
compare = false;
}
if (document.getElementById(parentObjectStr + 'Check') && document.getElementById(childObjectStr + 'Check')) {
var parentObjectCheck = document.getElementById(parentObjectStr  + 'Check');
var childObjectCheck = document.getElementById(childObjectStr + 'Check');
if (!parentObjectCheck.checked || !childObjectCheck.checked) {
compare = false;
}
}
if (document.getElementById(parentDateStr) && document.getElementById(childDateStr)) {
var parentDate = eval(parentDateStr +'_Object');
var childDate = eval(childDateStr +'_Object');
var parentDateField = parentDate.getHiddenField();
var childDateField = childDate.getHiddenField();
if (parentDateField.value != childDateField.value) {
compare = false;
}
}
if (compare) {
if (compareDependentTime(parentObject,childObject)) {
childTimeToParentTime(parentObject,childObject);
}
}
}
}