
//Constants
var TWODIGITYEAR	= 30;
var TIMEINPUT		= false;
var YEARSCROLLING	= true;
var calendars		= [];
var NUMPATTERN		= /^\-?\d+$/;

function cts_calendar(targetObject,calendarHtmlFileURL) 
{
	this.genDate				= calendarGenDate;
	this.genTime				= calendarGenTime;
	this.genTimestamp			= calendarGenTimestamp;
	this.parseDate				= calendarParseDate;
	this.parseTime				= calendarParseTime;
	this.parseTimestamp			= calendarParseTimestamp;
	this.calendarHtmlFileURL	= calendarHtmlFileURL;
	this.popup					= calendarPopup;

	if (!targetObject) return displayError("Error calling the calendar: no target object specified");
	if (targetObject.value == null) return displayError("Error calling the calendar: parameter specified is not a valid target object");
	this.target			= targetObject;
	this.timeInput		= TIMEINPUT;
	this.yearScroll		= YEARSCROLLING;
	this.id				= calendars.length;
	calendars[this.id]	= this;
}

function calendarPopup (dateTimeString,calendarHtmlFileURL) 
{
	this.dtCurrent = this.parseTimestamp(dateTimeString ? dateTimeString : this.target.value);
	if (!this.dtCurrent) return;
	var calendarObjectWindow = window.open(this.calendarHtmlFileURL+'/calendar.php?datetime=' + this.dtCurrent.valueOf()+ '&id=' + this.id, 'Calendar', 'width=200,height='+(this.timeInput ? 215 : 190) + ',status=no,resizable=no,top=200,left=200,dependent=yes,alwaysRaised=yes');
	calendarObjectWindow.opener = window;
	calendarObjectWindow.focus();
}

function calendarGenTimestamp (dtDateTime) 
{
	return(this.genDate(dtDateTime) + ' ' + this.genTime(dtDateTime));
}

function calendarGenDate (dtDateTime) 
{
	return ((dtDateTime.getMonth() < 9 ? '0' : '') + (dtDateTime.getMonth() + 1) + "/" + (dtDateTime.getDate() < 10 ? '0' : '') + dtDateTime.getDate() + "/" + dtDateTime.getFullYear());
}

function calendarGenTime (dtDateTime) 
{
	return ((dtDateTime.getHours() < 10 ? '0' : '') + dtDateTime.getHours() + ":" + (dtDateTime.getMinutes() < 10 ? '0' : '') + (dtDateTime.getMinutes()) + ":" + (dtDateTime.getSeconds() < 10 ? '0' : '') + (dtDateTime.getSeconds()));
}

function calendarParseTimestamp (dateTimeString) 
{
	if (!dateTimeString) return (new Date()); // timestamp returned if no parameter specified

	// if +ve integer treat as number of milliseconds from epoch else treat as date in string format
	if (NUMPATTERN.exec(dateTimeString)) return new Date(dateTimeString); 
	var dateTimeArray = dateTimeString.split(' ');
	return this.parseTime(dateTimeArray[1], this.parseDate(dateTimeArray[0]));
}


function calendarParseDate (dateString) 
{
	var dateArray = dateString.split('/');

	if (dateArray.length != 3) return alert ("Invalid date format: '" + dateString + "'.\nFormat accepted is mm/dd/yyyy.");
	if (!dateArray[1]) return alert ("Invalid date format: '" + dateString + "'.\nday of month missing.");
	if (!NUMPATTERN.exec(dateArray[1])) return alert ("Invalid day of month value: '" + dateArray[1] + "'.\nOnly numeric values allowed.");
	if (!dateArray[0]) return alert ("Invalid date format: '" + dateString + "'.\nmonth value missing.");
	if (!NUMPATTERN.exec(dateArray[0])) return alert ("Invalid month value: '" + dateArray[0] + "'.\nOnly numeric values allowed.");
	if (!dateArray[2]) return alert ("Invalid date format: '" + dateString + "'.\nyear value missing.");
	if (!NUMPATTERN.exec(dateArray[2])) return alert ("Invalid year value: '" + dateArray[2] + "'.\nOnly numeric values allowed.");

	var dtDate = new Date();
	dtDate.setDate(1);

	if (dateArray[0] < 1 || dateArray[0] > 12) return alert ("Invalid month value: '" + dateArray[0] + "'.\nAllowed range is 01-12.");
	dtDate.setMonth(dateArray[0]-1);
	 
	if (dateArray[2] < 100) dateArray[2] = Number(dateArray[2]) + (dateArray[2] < TWODIGITYEAR ? 2000 : 1900);
	dtDate.setFullYear(dateArray[2]);

	var dt_numdays = new Date(dateArray[2], dateArray[0], 0);
	dtDate.setDate(dateArray[1]);
	if (dtDate.getMonth() != (dateArray[0]-1)) return alert ("Invalid day of month value: '" + dateArray[1] + "'.\nAllowed range is 01-"+dt_numdays.getDate()+".");
	return (dtDate)
}

function calendarParseTime (timeString, dtDate) 
{
	if (!dtDate) return null;
	var timeArray = String(timeString ? timeString : '').split(':');

	if (!timeArray[0]) dtDate.setHours(0);
	else if (NUMPATTERN.exec(timeArray[0])) 
		if (timeArray[0] < 24) dtDate.setHours(timeArray[0]);
		else return displayError ("Invalid hours value: '" + timeArray[0] + "'.\nAllowed range is 00-23.");
	else return displayError ("Invalid hours value: '" + timeArray[0] + "'.\nAllowed values are unsigned integers.");
	
	if (!timeArray[1]) dtDate.setMinutes(0);
	else if (NUMPATTERN.exec(timeArray[1]))
		if (timeArray[1] < 60) dtDate.setMinutes(timeArray[1]);
		else return displayError ("Invalid minutes value: '" + timeArray[1] + "'.\nAllowed range is 00-59.");
	else return displayError ("Invalid minutes value: '" + timeArray[1] + "'.\nOnly numeric values are allowed.");

	if (!timeArray[2]) dtDate.setSeconds(0);
	else if (NUMPATTERN.exec(timeArray[2]))
		if (timeArray[2] < 60) dtDate.setSeconds(timeArray[2]);
		else return displayError ("Invalid seconds value: '" + timeArray[2] + "'.\nAllowed range is 00-59.");
	else return displayError ("Invalid seconds value: '" + timeArray[2] + "'.\nOnly numeric values are allowed.");

	dtDate.setMilliseconds(0);
	return dtDate;
}

function displayError (msgString) 
{
	alert (msgString);
	return null;
}
