/*
 *+------------------------------------------------------------------------+
 *| Licensed Materials - Property of IBM
 *| BI and PM: prmt
 *| (C) Copyright IBM Corp. 2002, 2016
 *|
 *| US Government Users Restricted Rights - Use, duplication or
 *| disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 *|
 *+------------------------------------------------------------------------+
*/


/*
	CTimePickerIE5.js

	This script is used to provide interactivity for the selectTime prompt control
*/

//Constructor to create a selectTime component
//	oSubmit: the field used to submit values to the server
//	oForm: the field used to store processed user input
//	oHours: hours form control
//	oMinutes: minutes form control
//	oSeconds: seconds form control
//	oMilliseconds: milliseconds form control
//	oAMPM: AM/PM form control
//	oImgTest: the image used for error checking
//	sRef: the name of this object
//	iType:	0 = 12 hour clock, right AM/PM,
//			1 = 12 hour clock, left AM/PM
//			2 = 24 hour clock, no AM/PM
//	iDisplay: determine the display
//		0 = h:m:s:ms
//		1 = h:m:s
//		2 = h:m
//	bInline:
//		false = edit box
//		true = inline control,  add clock
//	sTimeZone: string representing the timezones
//	sHourFormat: (hh = 01, h = 1)
//	sMinuteFormat: (mm = 01, m = 1)
//	sSecondFormat: (ss = 01, s = 1)
//	iMode: (0 = static, 1 = live clock)
//	sClock: the name of the inline clock
//	sTime: default time (e.g. "h:min:s.ms")
//	bRequired: boolean, specify if user input is required
//	sSubmitType: 'default' will submit as a standard form
//			'XML' will convert the submission to XML and submit

function CTimePicker(oSubmit, oForm, oHours, oMinutes, oSeconds, oMilliseconds, oAMPM, oImgTest, oClockBox, oEditBox, sRef, iType, iDisplay, bInline, sTimeZone, sHourFormat, sMinuteFormat, sSecondFormat, iMode, sClock, sTime, bRequired, sSubmitType, sCVId, sbaseId,
oTimeControl)
{
	this.setCVId(sCVId);
	//the name of the variable that is to be submitted
	this.m_oSubmit = oSubmit;

	this.m_oForm = oForm;
	this.id = sbaseId;
	//references to objects in the control
	this.m_oHours = oHours;
	this.m_oMinutes = oMinutes;
	this.m_oSeconds = oSeconds;
	this.m_oMilliseconds = oMilliseconds;
	this.m_oAMPM = oAMPM;

	//containers used to disable the control
	this.m_oClockBox = oClockBox;
	this.m_oEditBox = oEditBox;
	
	this.m_sRef = sRef;

	//specify whether the user must enter a date or not
	this.m_bRequired = bRequired;

	this.m_bDisabled = false;

	//indicate whether the control has valid data
	this.m_bValid = false;

	//submit as XML or as a standard html form
	this.m_sSubmitType = sSubmitType;

	//the type of clock
	//0 = 12 hour clock, right AM/PM
	//1 = 12 hour clock, left AM/PM
	//2 = 24 hour clock, no AM/PM
	if (iType == null)
	{
		if (g_24HourClock.toString().toLowerCase() == "true")
		{
			iType = 2;
		}
		else
		{
			if (g_AMPMLocation == 'left')
			{
				iType = 1;
			}
			else
			{
				iType = 0;
			}
		}
	}
	this.m_iType = iType;

	//what is being displayed
	//0 = h:m:s:ms
	//1 = h:m:s
	//2 = h:m
	this.m_iDisplay = iDisplay;
	
	// boolean flags for user input
	this.m_bCheckedHour = false;
	this.m_bCheckedMin = false;
	this.m_bCheckedSec = false;
	this.m_bCheckedMillis = false;

	//set the default time
	this.setValue(sTime);
	
	//get the names of the controls to be
	//used to determine the selected control
	//this is done once in the constructor, so that the
	//value does not need to be determined each time
	this.m_sHoursName = this.m_oHours.name;
	this.m_sMinutesName = this.m_oMinutes.name;

	if (this.m_iDisplay <= 1)
	{
		this.m_sSecondsName = this.m_oSeconds.name;
	}
	else
	{
		this.m_sSecondsName = "null";
	}

	if (this.m_iDisplay == 0)
	{
		this.m_sMillisecondsName = this.m_oMilliseconds.name;
	}
	else
	{
		this.m_sMillisecondsName = "null";
	}

	if ((this.m_iType == 0) || (this.m_iType == 1))
	{
		this.m_sAMPMName = this.m_oAMPM.name;
	}
	else
	{
		this.m_sAMPMName = "null";
	}

	//is this control being used with an inline calendar
	//or as an edit box
	//false = edit box
	//true = inline control (clock with edit box)
	this.m_bInline = bInline;
	if (this.m_bInline==true)
	{
		this.m_oClock = eval (sClock);
	}
	else
	{
		this.m_oClock = null;
	}

	//string representing the timezones
	this.m_sTimeZone = sTimeZone;

	//Hour Format
	//hh = 01
	//h = 1
	this.m_sHourFormat = g_hourFormatMedium;

	//Minute Format
	//mm = 01
	//m = 1
	this.m_sMinuteFormat = g_minuteFormatMedium;

	//Second Format
	//ss = 01
	//s = 1
	this.m_sSecondFormat = g_secondFormatMedium;

	//set the default control
	this.m_oCurrentFocus = this.m_oHours;

	//skin folder
	this.m_sSkin = (typeof getPromptSkin != K_PRMT_sUNDEFINED ? getPromptSkin() : K_PRMT_sDEFAULTSKIN);

	//images for handling errors
	this.m_oImgCheckDate = oImgTest;
	if (this.m_oImgCheckDate != null)
	{
		this.m_oImgErrorFalse = new Image();
		this.m_oImgErrorFalse.src = this.m_sSkin + "/prompting/images/error_timed_small_off.gif";
		this.m_oImgErrorTrue = new Image();
		this.m_oImgErrorTrue.src = this.m_sSkin + "/prompting/images/error_timed_small.gif";
	}

	//Mode
	//0 = static
	//1 = live
	this.m_iMode = iMode;

	if (this.m_iMode==1)
	{
		this.funcInt = setInterval( this.drawLiveTime.bind(this), 1000 );
	}

	//draw the current time
	this.refreshTime();

	//initialize the form control
	this.updateSubmitField();
	
	this.m_oTimeControl = oTimeControl;
}

CTimePicker.prototype = new CPromptControl();

//process the input and convert into the proper format
function CTimePicker_updateSubmitField()
{
	//return a valid time data type
	//00:00:00.000
	//hours
	var sHours = this.m_dTime.getHours().toString();
	if (sHours.length == 1)
	{
		sHours = '0' + sHours;
	}

	var sMinutes = this.m_dTime.getMinutes().toString();
	if (sMinutes.length == 1)
	{
		sMinutes = '0' + sMinutes;
	}

	var sSeconds = this.m_dTime.getSeconds().toString();
	if (sSeconds.length == 1)
	{
		sSeconds = '0' + sSeconds;
	}

	var sMilliseconds = this.m_dTime.getMilliseconds().toString();
	if (sMilliseconds.length == 2)
	{
		sMilliseconds = '0' + sMilliseconds;
	}
	else if (sMilliseconds.length == 1)
	{
		sMilliseconds = '00' + sMilliseconds;
	}

	this.m_oForm.value = sHours + K_PRMT_sCOLON + sMinutes + K_PRMT_sCOLON + sSeconds + K_PRMT_sDOT + sMilliseconds;
}

//render the values for the control based on display settings
function CTimePicker_refreshTime()
{
	this.checkData();
	if (this.m_bValid)
	{
		this.updateSubmitField();
	}
	//determine what needs to be displayed
	this.drawHours();
	this.drawMinutes();
	if (this.m_iDisplay <= 1)
	{
		this.drawSeconds();
	}
	if (this.m_iDisplay == 0)
	{
		this.drawMilliseconds();
	}
	if ((this.m_iType == 0) || (this.m_iType == 1))
	{
		this.drawAMPM();
	}
}

//render hours
function CTimePicker_drawHours()
{
	var inputHours = this.m_oHours.value;
	var iHours = this.iGetCurrentHours();

	var sHours = iHours.toString();
	if ((this.m_sHourFormat == 'hh') && (sHours.length == 1)) {
		sHours = '0' + sHours;
	}
	this.m_oHours.value = sHours;
	this.m_oHours.id = this.id + "_prmtTime_HOURS";
	this.m_oHours.className = "clsSelectTimeControl pcl";

	if (this.m_oClock!=null) {
		this.m_oClock.clockSetTime(this.m_dTime.getHours(), this.m_dTime.getMinutes(), this.m_dTime.getSeconds());
	}
	
	if (this.m_bCheckedHour && inputHours != iHours.toString()) {
		this.m_bCheckedHour = false;
		// console.log("dif in enter value, input Hours " + inputHours + ", iHours.toString()" + iHours.toString())
		var v_sMsg = PMT_UIM_INVALID_HOURS_CHANGED.replace(/\^1/, MIN_HOURS).replace(/\^2/,MAX_HOURS).replace(/\^3/, iHours);
		var oEditBox = this.m_oEditBox;
		PRMTUtils.f_showARIAMessageAlert(oEditBox, this.m_sRef, this.m_sSkin, v_sMsg);
	}
}

//render minutes
function CTimePicker_drawMinutes()
{
	var inputMinutes = this.m_oMinutes.value;
	
	var iMinutes = this.iGetCurrentMinutes();
	var sMinutes = iMinutes.toString();
	if ((this.m_sMinuteFormat == 'mm') && (sMinutes.length == 1)) {
		sMinutes = '0' + sMinutes;
	}
	this.m_oMinutes.value = sMinutes;
	this.m_oMinutes.id = this.id + "_prmtTime_MINUTES";
	this.m_oMinutes.className = "clsSelectTimeControl pcl";

	if (this.m_oClock!=null) {
		this.m_oClock.clockSetTime(this.m_dTime.getHours(), this.m_dTime.getMinutes(), this.m_dTime.getSeconds());
	}
	
	if (this.m_bCheckedMin && inputMinutes != iMinutes.toString()) {
		this.m_bCheckedMin =  false;
		// console.log("dif in enter value, input Minutes " + inputMinutes + ", iMinutes.toString()" + iMinutes.toString())
		var v_sMsg = PMT_UIM_INVALID_MINUTES_CHANGED.replace(/\^1/, MIN_MINUTES).replace(/\^2/,MAX_MINUTES).replace(/\^3/,iMinutes);
		var oEditBox = this.m_oEditBox;
		PRMTUtils.f_showARIAMessageAlert(oEditBox, this.m_sRef, this.m_sSkin, v_sMsg);
	}
}

//render seconds
function CTimePicker_drawSeconds()
{
	var inputSeconds = this.m_oSeconds.value;
	var iSeconds = this.iGetCurrentSeconds();
	var sSeconds = iSeconds.toString();
	if (this.m_sSecondFormat == 'ss' && (sSeconds.length == 1))	{
		sSeconds = '0' + sSeconds;
	}
	this.m_oSeconds.value = sSeconds;
	this.m_oSeconds.id = this.id + "_prmtTime_SECONDS";
	this.m_oSeconds.className = "clsSelectTimeControl pcl";

	if (this.m_oClock!=null) {
		this.m_oClock.clockSetTime(this.m_dTime.getHours(), this.m_dTime.getMinutes(), this.m_dTime.getSeconds());
	}
	
	if (this.m_bCheckedSec && inputSeconds != iSeconds.toString()) {
		this.m_bCheckedSec = false;
		// console.log("dif in enter value, inputSeconds " + inputSeconds + ", iSeconds.toString()" + iSeconds.toString())
		var v_sMsg = PMT_UIM_INVALID_SECONDS_CHANGED.replace(/\^1/, MIN_SECONDS).replace(/\^2/,MAX_SECONDS).replace(/\^3/,iSeconds);
		var oEditBox = this.m_oEditBox;
		PRMTUtils.f_showARIAMessageAlert(oEditBox, this.m_sRef, this.m_sSkin, v_sMsg);
	}
}

//render milliseconds
function CTimePicker_drawMilliseconds()
{
	var inputMilliseconds = this.m_oMilliseconds.value;
	var iMilliseconds = this.iGetCurrentMilliseconds();
	var sMilliseconds = iMilliseconds.toString();

	if (sMilliseconds.length == 2) {
		sMilliseconds = '0' + sMilliseconds;
	}
	else if (sMilliseconds.length == 1) {
		sMilliseconds = '00' + sMilliseconds;
	}
	this.m_oMilliseconds.value = sMilliseconds;
	this.m_oMilliseconds.id = this.id + "_prmtTime_MILLISECONDS";
	this.m_oMilliseconds.className = "clsSelectTimeControl pcl";

	if (this.m_bCheckedMillis && inputMilliseconds != iMilliseconds.toString()) {
		// console.log("dif in enter value, inputMilliseconds " + inputMilliseconds + ", iMilliseconds.toString()" + iMilliseconds.toString())
		this.m_bCheckedMillis = false;
		var v_sMsg = PMT_UIM_INVALID_MILLISECONDS_CHANGED.replace(/\^1/, MIN_MILLISECONDS).replace(/\^2/,MAX_MILLISECONDS).replace(/\^3/,iMilliseconds);
		var oEditBox = this.m_oEditBox;
		PRMTUtils.f_showARIAMessageAlert(oEditBox, this.m_sRef, this.m_sSkin, v_sMsg);
	}
}

//render AM/PM
function CTimePicker_drawAMPM()
{
	this.m_oAMPM.value = this.sGetCurrentAMPM();
	this.m_oAMPM.id = this.id + "_prmtTime_AMPM";
	this.m_oAMPM.className = "clsSelectTimeControl pcl";
}

//render live time
function CTimePicker_drawLiveTime()
{
	this.m_dTime = new Date();
	if (this.m_oClock !=null )
	{
		//this.m_oClock.drawLiveTime();
	}
	this.refreshTime();

}

//stop live time
function CTimePicker_stopLiveTime()
{
	if (this.m_iMode==1)
	{
		if (this.m_oClock !=null )
		{
			this.m_oClock.stopLiveTime();
		}

		if ( this.m_iDisplay > 1 )
		{
			// Can't change the seconds in the UI, so reset to 0.
			this.m_dTime.setSeconds(0);
		}
		if ( this.m_iDisplay > 0 )
		{
			// Can't change the milliseconds in the UI, so reset to 0.
			this.m_dTime.setMilliseconds(0);
		}
		this.m_iMode=0;
		clearInterval(this.funcInt);
	}
}

//change hours
function CTimePicker_setCurrentHours(iValue)
{
	this.stopLiveTime();
	if ((iValue >= MIN_HOURS) && (iValue <= MAX_HOURS))
	{
		this.m_dTime.setHours(iValue);
	}
}

//change minutes
function CTimePicker_setCurrentMinutes(iValue)
{
	this.stopLiveTime();
	if (iValue >= MIN_MINUTES && iValue <= MAX_MINUTES)
	{
		this.m_dTime.setMinutes(iValue);
	}
}

//change seconds
function CTimePicker_setCurrentSeconds(iValue)
{
	this.stopLiveTime();
	if (iValue >= MIN_SECONDS && iValue <= MAX_SECONDS)
	{
		this.m_dTime.setSeconds(iValue);
	}
}

//change milliseconds
function CTimePicker_setCurrentMilliseconds(iValue)
{
	this.stopLiveTime();
	if (iValue >= MIN_MILLISECONDS && iValue <= MAX_MILLISECONDS)
	{
		this.m_dTime.setMilliseconds(iValue);
	}
}

//change AM/PM
function CTimePicker_setCurrentAMPM(sValue)
{
	this.stopLiveTime();
	var sCurAMPM = this.sGetCurrentAMPM();
	//check to see if the current setting is the new setting
	if (sValue == sCurAMPM)
	{
		return;
	}
	else
	{
		var iHours = this.m_dTime.getHours();
		if (sValue == g_pmString)
		{
			if (iHours < 12)
			{
				iHours = iHours + 12;
				this.setCurrentHours(iHours);
			}
		}
		else if (sValue == g_amString)
		{
			if (iHours > 11)
			{
				iHours = iHours - 12;
				this.setCurrentHours(iHours);
			}
		}
	}
}

//return hours
function CTimePicker_iGetCurrentHours()
{
	//2 = 24 hour clock, no AM/PM
	if (this.m_iType == 2)
	{
		return this.m_dTime.getHours();
	} else
	{
		var iHours = this.m_dTime.getHours();
		if (iHours > 12)
		{
			iHours = iHours - 12;
		}
		if (iHours == 0)
		{
			iHours = 12;
		}
		return iHours;
	}
}

//return minutes
function CTimePicker_iGetCurrentMinutes()
{
	return this.m_dTime.getMinutes();
}

//return seconds
function CTimePicker_iGetCurrentSeconds()
{
	return this.m_dTime.getSeconds();
}

//return milliseconds
function CTimePicker_iGetCurrentMilliseconds()
{
	return this.m_dTime.getMilliseconds();
}

//return AM/PM
function CTimePicker_sGetCurrentAMPM()
{
	if (this.m_iType == 2)
	{
		return K_PRMT_sEMPTY;
	}
	else
	{
		if (this.m_dTime.getHours() > 11)
		{
			return g_pmString;
		}
		else
		{
			return g_amString;
		}
	}
}

function CTimePicker_bisValidHours(hours) {
	var iHours = parseInt(this.m_oHours.value,10);
	return (bNumbersOnly(hours) && iHours >= MIN_HOURS && iHours <= MAX_HOURS);
}

function CTimePicker_bisValidMinutes(min) {
	var iMinutes = parseInt(this.m_oMinutes.value,10);
	return ( bNumbersOnly(min) && iMinutes >= MIN_MINUTES && iMinutes <= MAX_MINUTES );
}

function CTimePicker_bisValidSeconds(min) {
	var iSeconds = parseInt(this.m_oSeconds.value,10);
	return ( bNumbersOnly(min) && iSeconds >= MIN_SECONDS && iSeconds <= MAX_SECONDS );
}

function CTimePicker_bisValidMilliseconds(milliseconds) {
	var iMilliseconds = parseInt(this.m_oMilliseconds.value,10);
	return ( bNumbersOnly(milliseconds) && iMilliseconds >= MIN_MILLISECONDS && iMilliseconds <= MAX_MILLISECONDS );
}

function CTimePicker_bCheckTime()
{
	//check hours
	if ( !this.bisValidHours(this.m_oHours.value) ) {
		return false;
	}

	if ( !this.bisValidMinutes(this.m_oMinutes.value) ) {
		return false;
	}

	if (this.m_iDisplay <= 1) {
		if ( !this.bisValidSeconds(this.m_oSeconds.value) ) {
			return false;
		}
	}

	if (this.m_iDisplay == 0) {
		if ( !this.bisValidMilliseconds(this.m_oSeconds.value) ) {
			return false;
		}
	}
	return true;
}

//handle focus to the particular field
function CTimePicker_setCurrentFocus(obj)
{
	this.m_oCurrentFocus = obj;
	this.m_oCurrentFocus.select();
}

//determine which field currently has focus
function CTimePicker_oGetCurrentFocus()
{
	return this.m_oCurrentFocus;
}

//increment the time up by one for the field with focus
function CTimePicker_timeUp()
{
	var sCurrentFocus = this.m_oCurrentFocus.name;
	switch (sCurrentFocus)
	{

		case this.m_sHoursName:
			var iCurHours = this.m_dTime.getHours();

			if ( iCurHours == MAX_HOURS)
			{
				this.setCurrentHours(MIN_HOURS);
			}
			else
			{
				this.setCurrentHours(this.m_dTime.getHours() + 1);
			}
			if (this.m_iType != 2)
			{
				this.drawAMPM();
			}

			this.drawHours();
			break;
		case this.m_sMinutesName:
			if (this.iGetCurrentMinutes() == MAX_MINUTES)
			{
				this.setCurrentMinutes(MIN_MINUTES);
			}
			else
			{
				this.setCurrentMinutes(this.iGetCurrentMinutes() + 1);
			}
			this.drawMinutes();
			break;
		case this.m_sSecondsName:
			if (this.iGetCurrentSeconds() == MAX_SECONDS)
			{
				this.setCurrentSeconds(MIN_SECONDS);
			}
			else
			{
				this.setCurrentSeconds(this.iGetCurrentSeconds() + 1);
			}
			this.drawSeconds();
			break;
		case this.m_sMillisecondsName:
			if (this.iGetCurrentMilliseconds() == MAX_MILLISECONDS)
			{
				this.setCurrentMilliseconds(MIN_MILLISECONDS);
			}
			else
			{
				this.setCurrentMilliseconds(this.iGetCurrentMilliseconds() + 1);
			}
			this.drawMilliseconds();
			break;
		case this.m_sAMPMName:
			if (this.sGetCurrentAMPM() == g_amString)
			{
				this.setCurrentAMPM(g_pmString);
			}
			else
			{
				this.setCurrentAMPM(g_amString);
			}

			this.drawAMPM();
			break;
		default:
			alert ('problem with CTimePicker_timeUp()');
			break;
	}

	this.updateSubmitField();
	if (!PRMTUtils.f_isMobileDevice()) {
		this.m_oCurrentFocus.select();
	}
}

//decrement the time down by one for the field with focus
function CTimePicker_timeDown()
{
	var sCurrentFocus = this.m_oCurrentFocus.name;

	switch (sCurrentFocus)
	{

		case this.m_sHoursName:
			var iCurHours = this.m_dTime.getHours();

			if ( iCurHours == MIN_HOURS)
			{
				this.setCurrentHours(MAX_HOURS);
			}
			else
			{
				this.setCurrentHours(this.m_dTime.getHours() - 1);
			}

			if (this.m_iType != 2)
			{
				this.drawAMPM();
			}
			this.drawHours();
			break;
		case this.m_sMinutesName:
			if (this.iGetCurrentMinutes() == MIN_MINUTES)
			{
				this.setCurrentMinutes(MAX_MINUTES);
			}
			else
			{
				this.setCurrentMinutes(this.iGetCurrentMinutes() - 1);
			}
			this.drawMinutes();
			break;
		case this.m_sSecondsName:
			if (this.iGetCurrentSeconds() == MIN_SECONDS)
			{
				this.setCurrentSeconds(MAX_SECONDS);
			}
			else
			{
				this.setCurrentSeconds(this.iGetCurrentSeconds() - 1);
			}
			this.drawSeconds();
			break;
		case this.m_sMillisecondsName:
			if (this.iGetCurrentMilliseconds() == MIN_MILLISECONDS)
			{
				this.setCurrentMilliseconds(MAX_MILLISECONDS);
			}
			else
			{
				this.setCurrentMilliseconds(this.iGetCurrentMilliseconds() - 1);
			}
			this.drawMilliseconds();
			break;

		case this.m_sAMPMName:

			if (this.sGetCurrentAMPM() == g_amString)
			{
				this.setCurrentAMPM(g_pmString);
			}
			else
			{
				this.setCurrentAMPM(g_amString);
			}
			this.drawAMPM();
			break;
		default:
			alert ('problem with CTimePicker_timeUp()');
			break;
	}

	this.updateSubmitField();
	if (!PRMTUtils.f_isMobileDevice()) {
		this.m_oCurrentFocus.select();
	}
}

/* key event handling */
function CTimePicker_keyPress(evt,obj)
{
	//trap event
	evt = (evt) ? evt : ((event) ? event : null);
	if (evt)
	{
		var keyCode = parseInt(((evt.keyCode) ? evt.keyCode : evt.which),10);

		switch (keyCode)
		{
			//up
			case 38:
				this.timeUp();
				this.setCurrentFocus(obj);
				break;

			//down
			case 40:
				this.timeDown();
				this.setCurrentFocus(obj);
				break;

			default:
				break;
		}

		if (this.bCheckTime() == false)
		{
			this.checkTimeFail();
		}
		else
		{
			this.checkTimePass();
			this.updateSubmitField();
		}
	}

	return true;
}

//render control in validated state
function CTimePicker_checkTimePass()
{
	if ((this.m_oImgCheckDate != null) && (this.m_oImgCheckDate.src != this.m_oImgErrorFalse.src))
	{
		this.m_oImgCheckDate.src = this.m_oImgErrorFalse.src;
	}
	this.notify(gPASS, this);
}

//render control in error state
function CTimePicker_checkTimeFail()
{
	if (this.m_oImgCheckDate != null)
	{
		this.m_oImgCheckDate.src = this.m_oImgErrorTrue.src + '?' + Math.random();
	}
	this.notify(gFAIL, this);
}

//test the hour
function CTimePicker_bCheckHour()
{
	this.m_bCheckedHour = true;
	if ( this.bisValidHours(this.m_oHours.value) ) 	{
		var iValue = parseInt(this.m_oHours.value,10);
		this.m_oHours.className = "clsSelectTimeControl pcl";
		this.checkTimePass();

		//2 = 24 hour clock, no AM/PM
		if (this.m_iType == 2)
		{
			this.setCurrentHours(iValue);
		}
		else
		{
			if	((iValue > 0) && (iValue < 12) && (this.sGetCurrentAMPM() == g_pmString))
			{
				iValue = iValue + 12;
				this.setCurrentHours(iValue);
			}
			else if	((iValue > 0) && (iValue < 12) && (this.sGetCurrentAMPM() == g_amString))
			{
				this.setCurrentHours(iValue);
			}
			else if (iValue > 12)
			{
				this.setCurrentHours(iValue);
			}
			else if ((iValue == 12) && (this.sGetCurrentAMPM() == g_amString))
			{
				this.setCurrentHours(0);
			}
			else if ((iValue == 12) && (this.sGetCurrentAMPM() == g_pmString))
			{
				this.setCurrentHours(12);
			}
		}

		return true;
	}
	else
	{
		this.m_oHours.className = "clsSelectTimeControlParseError";
		this.checkTimeFail();
		return false;
	}
}

//test the minute
function CTimePicker_bCheckMinute()
{
	this.m_bCheckedMin = true;
	if ( this.bisValidMinutes(this.m_oMinutes.value) ) 	{
		var iValue = parseInt(this.m_oMinutes.value,10);
		this.m_oMinutes.className = "clsSelectTimeControl pcl";
		this.setCurrentMinutes(iValue);
		this.checkTimePass();
		return true;
	}
	else
	{
		this.m_oMinutes.className = "clsSelectTimeControlParseError";
		this.checkTimeFail();
		return false;
	}
}

//test the second
function CTimePicker_bCheckSecond()
{
	this.m_bCheckedSec = true;
	if ( this.bisValidSeconds(this.m_oSeconds.value) ) 	{
		var iValue = parseInt(this.m_oSeconds.value,10);
		this.m_oSeconds.className = "clsSelectTimeControl pcl";
		this.setCurrentSeconds(iValue);
		this.checkTimePass();
		return true;
	}
	else
	{
		this.m_oSeconds.className = "clsSelectTimeControlParseError";
		this.checkTimeFail();
		return false;
	}
}

//test the millisecond
function CTimePicker_bCheckMillisecond()
{
	this.m_bCheckedMillis = true;
	if ( this.bisValidMilliseconds(this.m_oMilliseconds.value) ) 	{
		var iValue = parseInt(this.m_oMilliseconds.value,10);
		this.m_oMilliseconds.className = "clsSelectTimeControl pcl";
		this.setCurrentMilliseconds(iValue);
		this.checkTimePass();
		return true;
	}
	else
	{
		this.m_oMilliseconds.className = "clsSelectTimeControlParseError";
		this.checkTimeFail();
		return false;
	}
}

//check AM/PM
function CTimePicker_bCheckAMPM()
{
	var sValue = this.m_oAMPM.value;

	var myAMPattern = new RegExp("^" + g_amString.substring(0,1), "i"); //ignore case
	var myPMPattern = new RegExp("^" + g_pmString.substring(0,1), "i"); //ignore case

	//is there a match?
	if (sValue.match(myAMPattern))
	{
		this.m_oAMPM.className = "clsSelectTimeControl pcl";
		this.setCurrentAMPM(g_amString);
		this.checkTimePass();
		return true;
	}
	else if (sValue.match(myPMPattern))
	{
		this.m_oAMPM.className = "clsSelectTimeControl pcl";
		this.setCurrentAMPM(g_pmString);
		this.checkTimePass();
		return true;
	}
	else
	{
		this.m_oAMPM.className = "clsSelectTimeControlParseError";
		this.checkTimeFail();
		return false;
	}
}

//return a formatted string of the time
//	iDisplay: determine the display
//		0 = h:m:s:ms
//		1 = h:m:s
//		2 = h:m
function CTimePicker_sGetFormatTime()
{
	return getFormatTime(this.m_dTime, this.m_iDisplay);
}

//return the time in SQL format
function CTimePicker_sGetSQLTime()
{
	var sValue = K_PRMT_sEMPTY;
	sValue = this.m_oForm.value;
	return sValue;
}

//validate the input into the control
function CTimePicker_checkData()
{
	if ((this.m_bRequired == true) && ((this.m_oForm.value==K_PRMT_sEMPTY)||(this.bCheckTime() ==false)))
	{
		this.m_bValid = false;
		this.checkTimeFail();
		return false;
	}

	if ((this.m_bDisabled == false) && (this.bCheckTime() == false))
	{
		this.m_bValid = false;
		this.checkTimeFail();
		return false;
	}
	else
	{
		this.m_bValid = true;
		this.checkTimePass();
		// because the checkData of control is not notified
		if (SYSTEMPROPERTY_TREE_CACHE_ENABLED)
		{
			if (this.m_oTimeControl)
			{
				this.m_oTimeControl.cacheControlValue(this.m_oTimeControl._type_);
			}
		}
		return true;
	}
}

//perform any special processing for the server.
function CTimePicker_preProcess()
{
	if (this.m_sSubmitType == K_PRMT_sXML)
	{
		var sURLValues = K_PRMT_sEMPTY;
		if (this.m_bDisabled!=true)
		{
			sURLValues += '<selectOption';
			sURLValues += ' displayValue="' + this.sGetFormatTime() +'"';
			sURLValues += ' useValue="' + this.sGetSQLTime() +'"';
			sURLValues += ' selected="true" />';
		}
		addSelectChoices(this.m_oSubmit, sURLValues);
	}
	else
	{
		if (this.m_bDisabled != true)
		{
			this.m_oSubmit.value = this.sGetSQLTime();
		}
		else
		{
			//this control is disabled
			this.m_oSubmit.value = K_PRMT_sEMPTY;
		}
	}
}

function CTimePicker_enable()
{
	this.m_bDisabled = false;
	if ( this.m_oClockBox )
	{
		PRMTUtils.f_removeClass( this.m_oClockBox.parentNode, "clsClockDisabled" );
	}
	PRMTUtils.f_removeClass( this.m_oClockBox, "clsClockDisabled" );
	PRMTUtils.f_removeClass( this.m_oEditBox, "clsClockDisabled" );
	PRMTUtils.f_removeClass( this.m_oHours, "clsClockDisabled" );
	PRMTUtils.f_removeClass( this.m_oMinutes, "clsClockDisabled" );
	PRMTUtils.f_removeClass( this.m_oSeconds, "clsClockDisabled" );
	PRMTUtils.f_removeClass( this.m_oMilliseconds, "clsClockDisabled" );
	PRMTUtils.f_removeClass( this.m_oAMPM, "clsClockDisabled" );
}

function CTimePicker_disable()
{
	this.m_bDisabled = true;
	this.stopLiveTime();
	if ( this.m_oClockBox )
	{
		PRMTUtils.f_addClass( this.m_oClockBox.parentNode, "clsClockDisabled" );
	}
	PRMTUtils.f_addClass( this.m_oClockBox, "clsClockDisabled" );
	PRMTUtils.f_addClass( this.m_oEditBox, "clsClockDisabled" );
	PRMTUtils.f_addClass( this.m_oHours, "clsClockDisabled" );
	PRMTUtils.f_addClass( this.m_oMinutes, "clsClockDisabled" );
	PRMTUtils.f_addClass( this.m_oSeconds, "clsClockDisabled" );
	PRMTUtils.f_addClass( this.m_oMilliseconds, "clsClockDisabled" );
	PRMTUtils.f_addClass( this.m_oAMPM, "clsClockDisabled" );
}

function CTimePicker_toggleDisable(bState)
{
	if (this.isRequired() == false)
	{
		if (bState == false)
		{
			this.disable();
		}
		else
		{
			this.enable();
		}
	}
}

//return interval data type
function CTimePicker_sGetValue()
{
	return this.sGetSQLTime();
}

//return locale formatted value
function CTimePicker_sGetFormatValue()
{
	return this.sGetFormatTime();
}

//set the value of the control
function CTimePicker_setValue(sTime)
{
	if (sTime != null)
	{
		this.m_dTime = dParseTime (sTime);
	}
	else
	{
		//default to 12:00am
		this.resetTime();
	}
	//draw the current time
	this.refreshTime();

	//initialize the form control
	this.updateSubmitField();
}

//set the time to 12:00am
function CTimePicker_resetTime()
{
	this.m_dTime = new Date();
	this.m_dTime.setHours(0);
	this.m_dTime.setMinutes(0);
	this.m_dTime.setSeconds(0);
	this.m_dTime.setMilliseconds(0);
}

function CTimePicker_hasValue()
{
	if (this.m_oForm.value == K_PRMT_sEMPTY)
	{
		return false;
	}
	else
	{
		return true;
	}
}
function CTimePicker_checkFail()
{
	this.checkTimeFail();
}

//Prototypes to assign methods to new instances of the object
CTimePicker.prototype.updateSubmitField = CTimePicker_updateSubmitField;
CTimePicker.prototype.refreshTime = CTimePicker_refreshTime;
CTimePicker.prototype.drawHours = CTimePicker_drawHours;
CTimePicker.prototype.drawMinutes = CTimePicker_drawMinutes;
CTimePicker.prototype.drawSeconds = CTimePicker_drawSeconds;
CTimePicker.prototype.drawMilliseconds = CTimePicker_drawMilliseconds;
CTimePicker.prototype.drawAMPM = CTimePicker_drawAMPM;
CTimePicker.prototype.drawLiveTime = CTimePicker_drawLiveTime;
CTimePicker.prototype.stopLiveTime = CTimePicker_stopLiveTime;
CTimePicker.prototype.setCurrentHours = CTimePicker_setCurrentHours;
CTimePicker.prototype.setCurrentMinutes = CTimePicker_setCurrentMinutes;
CTimePicker.prototype.setCurrentSeconds = CTimePicker_setCurrentSeconds;
CTimePicker.prototype.setCurrentMilliseconds = CTimePicker_setCurrentMilliseconds;
CTimePicker.prototype.setCurrentAMPM = CTimePicker_setCurrentAMPM;
CTimePicker.prototype.iGetCurrentHours = CTimePicker_iGetCurrentHours;
CTimePicker.prototype.iGetCurrentMinutes = CTimePicker_iGetCurrentMinutes;
CTimePicker.prototype.iGetCurrentSeconds = CTimePicker_iGetCurrentSeconds;
CTimePicker.prototype.iGetCurrentMilliseconds = CTimePicker_iGetCurrentMilliseconds;
CTimePicker.prototype.sGetCurrentAMPM = CTimePicker_sGetCurrentAMPM;
CTimePicker.prototype.bCheckTime = CTimePicker_bCheckTime;
CTimePicker.prototype.bisValidHours = CTimePicker_bisValidHours;
CTimePicker.prototype.bisValidMinutes = CTimePicker_bisValidMinutes;
CTimePicker.prototype.bisValidSeconds = CTimePicker_bisValidSeconds;
CTimePicker.prototype.bisValidMilliseconds = CTimePicker_bisValidMilliseconds;
CTimePicker.prototype.setCurrentFocus = CTimePicker_setCurrentFocus;
CTimePicker.prototype.oGetCurrentFocus = CTimePicker_oGetCurrentFocus;
CTimePicker.prototype.timeUp = CTimePicker_timeUp;
CTimePicker.prototype.timeDown = CTimePicker_timeDown;
CTimePicker.prototype.keyPress = CTimePicker_keyPress;
CTimePicker.prototype.bCheckHour = CTimePicker_bCheckHour;
CTimePicker.prototype.bCheckMinute = CTimePicker_bCheckMinute;
CTimePicker.prototype.bCheckSecond = CTimePicker_bCheckSecond;
CTimePicker.prototype.bCheckMillisecond = CTimePicker_bCheckMillisecond;
CTimePicker.prototype.bCheckAMPM = CTimePicker_bCheckAMPM;
CTimePicker.prototype.checkTimePass = CTimePicker_checkTimePass;
CTimePicker.prototype.checkTimeFail = CTimePicker_checkTimeFail;
CTimePicker.prototype.sGetFormatTime = CTimePicker_sGetFormatTime;
CTimePicker.prototype.sGetSQLTime = CTimePicker_sGetSQLTime;
CTimePicker.prototype.checkData= CTimePicker_checkData;
CTimePicker.prototype.preProcess = CTimePicker_preProcess;
CTimePicker.prototype.enable = CTimePicker_enable;
CTimePicker.prototype.disable = CTimePicker_disable;
CTimePicker.prototype.toggleDisable = CTimePicker_toggleDisable;
CTimePicker.prototype.sGetFormatValue = CTimePicker_sGetFormatValue;
CTimePicker.prototype.sGetValue = CTimePicker_sGetValue;
CTimePicker.prototype.setValue = CTimePicker_setValue;
CTimePicker.prototype.resetTime = CTimePicker_resetTime;
CTimePicker.prototype.hasValue = CTimePicker_hasValue;
CTimePicker.prototype.checkFail = CTimePicker_checkFail;

/* utility functions */

//returns a date object for a given time
function dParseTime(sTime)
{
	var dTime = new Date(1970,0,1,0,0,0,0);

	//set a default time if a default has been specified
	var sDefaultTime = (sTime) ? sTime : K_PRMT_sEMPTY;

	//convert from a valid date time format (XSD format and SQL)
	var arDateTime = sDefaultTime.split(/[T\s]/g);
	if (arDateTime.length == 2)
	{
		sDefaultTime = arDateTime[1];
	}

	var arDefaultTime = sDefaultTime.split(/[:\.\,]/g);

	//do we have a valid date?
	if ((arDefaultTime.length == 4) || (arDefaultTime.length == 3))
	{
		var sHours = parseInt(arDefaultTime[0],10);
		if (sHours != NaN && sHours <= 23 && sHours >= 0)
		{
			dTime.setHours(sHours);
		}
		else
		{
			// going to default to 12
			dTime.setHours(0);
		}
		var sMinutes = parseInt(arDefaultTime[1],10);
		if (sMinutes != NaN && sMinutes <= 59 && sMinutes >= 0)
		{
			dTime.setMinutes(sMinutes);
		}
		else
		{
			// going to default to 0 minutes
			dTime.setMinutes(0);
		}
		var sSeconds = parseInt(arDefaultTime[2],10);
		if (sSeconds != NaN && sSeconds <= 59 && sSeconds >= 0)
		{
			dTime.setSeconds(sSeconds);
		}
		else
		{
			// going to default to 0 seconds
			dTime.setSeconds(0);
		}
		//milliseconds are optional
		if (arDefaultTime.length == 4)
		{
			var sMilliseconds = parseInt(arDefaultTime[3],10);
			if (sMilliseconds != NaN && sMilliseconds <= 999 && sMilliseconds >= 0)
			{
				dTime.setMilliseconds(sMilliseconds);
			}
			else
			{
				// going to default to 0 milliseconds
				dTime.setMilliseconds(0);
			}
		}
	}
	return dTime;
}

//returns a locale formatted time for a given date
//
//	iDisplay: determine the display
//		0 = h:m:s:ms
//		1 = h:m:s
//		2 = h:m
function getFormatTime(dTime, iDisplay)
{
	var sValue = K_PRMT_sEMPTY;

	//format hours
	var iHours = dTime.getHours();

	if (g_24HourClock == 'false')
	{
		if (iHours == 0)
		{
			iHours = 12;
		}
		else if (iHours > 12)
		{
			iHours = iHours - 12;
		}
	}
	var sHours = iHours.toString();
	if ((sHours.length == 1) && (g_hourFormatMedium == 'hh'))
	{
		sHours = '0' + sHours;
	}
	sValue += sHours;

	//format minutes
	var sMinutes = dTime.getMinutes().toString();
	if ((sMinutes.length == 1) && (g_minuteFormatMedium == 'mm'))
	{
		sMinutes = '0' + sMinutes;
	}
	sValue += g_timeSeparator + sMinutes;

	//format seconds
	if (iDisplay <= 1)
	{
		var sSeconds = dTime.getSeconds().toString();
		if ((sSeconds.length == 1) && (g_secondFormatMedium == 'ss'))
		{
			sSeconds = '0' + sSeconds;
		}

		sValue += g_timeSeparator + sSeconds;
	}
	//format milliseconds
	if (iDisplay == 0)
	{
		var sMilliseconds = dTime.getMilliseconds().toString();
		if (sMilliseconds.length == 2)
		{
			sMilliseconds = '0' + sMilliseconds;
		}
		else if (sMilliseconds.length == 1)
		{
			sMilliseconds = '00' + sMilliseconds;
		}

		sValue += K_PRMT_sDOT + sMilliseconds;
	}

	if ((g_24HourClock == 'false') && (g_AMPMLocation == 'right'))
	{
		if (dTime.getHours() >= 12)
		{
			sValue = sValue + K_PRMT_sSP + g_pmString;
		}
		else
		{
			sValue = sValue + K_PRMT_sSP + g_amString;
		}
	}
	else if ((g_24HourClock == "false") && (g_AMPMLocation == "left"))
	{
		if (dTime.getHours() >= 12)
		{
			sValue = g_pmString + K_PRMT_sSP + sValue;
		}
		else
		{
			sValue = g_amString + K_PRMT_sSP + sValue;
		}
	}

	return sValue;
}


/* Messages */
// declare message strings
var g_amString = "AM";
var g_pmString = "PM";
var g_mediumFormat = "MMM d, yyyy h:mm:ss a";
var g_shortFormat = "M/d/yy h:mm a";
var g_hourFormatMedium = "h";
var g_minuteFormatMedium = "mm";
var g_secondFormatMedium = "ss";
var g_hourFormatShort = "h";
var g_minuteFormatShort = "mm";
var g_secondFormatShort = K_PRMT_sEMPTY;
var g_timeSeparator = K_PRMT_sCOLON;
var g_AMPMLocation = "right";
var g_24HourClock = "false";

/* Constants */
var MAX_HOURS = 23;
var MAX_MINUTES = 59;
var MAX_SECONDS = 59;
var MAX_MILLISECONDS = 999;

var MIN_HOURS = 0;
var MIN_MINUTES = 0;
var MIN_SECONDS = 0;
var MIN_MILLISECONDS = 0;