//popup calendar picker
//version 1.5
//chad olson
//www.surface51.com

var currentDate = new Date();

var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var daysInMonthInLeapyear = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];


var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var monthNamesAbbr = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var weekNames = ["S", "M", "Tu", "W", "Th", "F", "Sa"];
var weekNamesAbbr = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

var globalCalenderDiv = "popupCalendarDiv";
var globalCalendarInputDiv = "popupCalendarInputDiv";
var allCalendars = new Array();

var zIndex = 1001;



//make global calendar DIV tag
document.write('<div id="' + globalCalenderDiv + '" style="position:absolute; width:180; height:180; visibility:hidden; z-index:1000;"></div>');
document.write('<div id="' + globalCalendarInputDiv + '" style="position:absolute; width:180; height:20; visibility:hidden; z-index:1001;"></div>');



//****************************
//functions

//main calendar object
//thisObj - form object to save information to
//showTime - whether to show or hide time
//ampm - morning or after setting
function calendarObj(thisName, thisObj) {
	this.name = thisName;
	this.obj = thisObj;
	this.divObj = getObj(globalCalenderDiv);
	this.inputObj = getObj(globalCalendarInputDiv);
	this.inputIsShowing = false;
}

function showCalendar(calendarObj) {
	//parse form information to populate calendar
	parseCalendarDate(calendarObj);

	//build HTML for calendar
	buildCalendar(calendarObj);
}

function parseCalendarDate(calendarObj) {
	if (!calendarObj.obj) {return;}

	var datetimeArray = calendarObj.obj.value.split(" ");
	var dateArray = datetimeArray[0].split("-");
	var timeArray = (datetimeArray.length > 1) ? datetimeArray[1].split(":") : new Array();

	//year
	var thisYear = (dateArray.length > 1) ? parseInt(dateArray[0], 10) : currentDate.getFullYear();

	//month
	var thisMonth = (dateArray.length > 1) ? parseInt(dateArray[1], 10) : currentDate.getMonth() + 1;
	if (thisMonth < 1 || thisMonth > 12) {thisMonth = currentDate.getMonth() + 1;}

	//day
	var thisDay = (dateArray.length > 2) ? parseInt(dateArray[2], 10) : currentDate.getDate();
	if (thisDay < 1 || thisDay > getDaysInMonth(thisMonth, thisYear)) {thisDay = currentDate.getDate();}

	//hour
	var thisHour = (timeArray.length > 1) ? parseInt(timeArray[0], 10) : 0; //;
	if (thisHour < 0 || thisHour > 23) {thisHour = currentDate.getHours();}

	//minute
	var thisMinute = (timeArray.length > 1) ? parseInt(timeArray[1], 10) : 0; //currentDate.getMinutes();
	if (thisMinute < 0 || thisMinute > 59) {thisMinute = currentDate.getMinutes();}

	//save information to this object (will use this for each display)
	calendarObj.month = thisMonth;
	calendarObj.day = thisDay;
	calendarObj.year = thisYear;
	calendarObj.hour = thisHour;
	calendarObj.minute = thisMinute;
	calendarObj.ampm = (thisHour < 12) ? "am" : "pm";

	//save current data to allow viewer to show different months
	calendarObj.curMonth = thisMonth;
	calendarObj.curDay = thisDay;
	calendarObj.curYear = thisYear;
}

function changeMonth(calendarObj, thisIncrement) {
	var previousArray = calculateMonthYear(calendarObj.month, calendarObj.year, thisIncrement);
	calendarObj.month = previousArray[0];
	calendarObj.year = previousArray[1];

	buildCalendar(calendarObj);
}

function buildCalendar(calendarObj) {
	if (!calendarObj.divObj) {return;}

	var newHTML = "";

	var monthStartDate = new Date(calendarObj.year, (calendarObj.month - 1), 1, calendarObj.hour, calendarObj.minute);
	var startDayOfWeek = monthStartDate.getDay();

	var previousArray = calculateMonthYear(calendarObj.month, calendarObj.year, -1);
	var nextArray = calculateMonthYear(calendarObj.month, calendarObj.year, 1);

	newHTML += '<table width="100%" cellpadding="1" cellspacing="0" border="0" bgcolor="#999999">' + "\n";
	newHTML += "	<tr><td>\n";

	newHTML += '<table width="100%" cellpadding="2" cellspacing="0" border="0" bgcolor="#ffffff">' + "\n";

	//title bar
	newHTML += '	<tr bgcolor="#ccd4e0">' + "\n";
	newHTML += '		<td align="center"><a href="javascript:changeMonth(' + calendarObj.name + ', -1);">&lt;</a></td>' + "\n";

	newHTML += '		<td colspan="5" align="center"><b>';
	newHTML += '<a href="javascript:showInput(' + calendarObj.name + ');">' + monthNames[calendarObj.month - 1];
	if (!calendarObj.hideYear) {newHTML += " " + calendarObj.year;}
	newHTML += "</a>";
	newHTML += "</b></td>\n";

	newHTML += '		<td align="center"><a href="javascript:changeMonth(' + calendarObj.name + ', 1);">&gt;</a></td>' + "\n";
	newHTML += "	</tr>\n";

	//weekday names
	newHTML += "	<tr bgcolor=\"#e1e1e1\">\n";
	for (var i=0; i<7; i++) {
		newHTML += '		<td align="center"><span class="notetext">' + weekNames[i] + "</span></td>\n";
	}
	newHTML += "	</tr>\n";

	//start with blank table columns
	var isClosed = true;
	var currentDayNum = 0;
	for (var i=0; i<startDayOfWeek; i++) {
		if (isClosed) {
			newHTML += '	<tr valign="top">' + "\n";
			isClosed = false;
		}

		newHTML += "		<td></td>\n";

		currentDayNum++;
	}

	//all the days
	for (var i=0; i<getDaysInMonth(calendarObj.month, calendarObj.year); i++) {
		var thisValue = (i + 1);

		if (isClosed) {
			newHTML += '	<tr valign="top">' + "\n";
			isClosed = false;
		}

		var bgColor = ((currentDayNum + 1) % 7 <= 1) ? ' bgcolor="#efefef"' : "";
		if (currentDate.getFullYear() == calendarObj.year && currentDate.getMonth() == (calendarObj.month - 1) && currentDate.getDate() == (i + 1)) {bgColor = ' bgcolor="#acd9ff"';}
		var isSelected = (calendarObj.curYear == calendarObj.year && calendarObj.curMonth == calendarObj.month && calendarObj.curDay == (i + 1) && calendarObj.obj.value) ? true : false;
		var borderStyle = (isSelected) ? ' class="calendarSelected"' : ' class="calendarNormal"';

		newHTML += '		<td align="center"' + bgColor + borderStyle + ">";
		newHTML += '<a href="javascript:chooseDate(' + calendarObj.name + ", '" + thisValue + "');\">";
		newHTML += (isSelected) ? "<b>" + (i + 1) + "</b>" : (i + 1);
		newHTML += "</a>\n";
		newHTML += "</td>\n";

		if (((currentDayNum + 1) % 7) == 0) {
			newHTML += "	</tr>\n";
			isClosed = true;
		}

		currentDayNum++;
	}
	if (!isClosed) {
		var daysLeft = 7 - (currentDayNum % 7);
		newHTML += '		<td colspan="' + daysLeft + '"></td>' + "\n";
		newHTML += "	</tr>\n";
	}

	//time
	if (calendarObj.showTime) {
		newHTML += '	<tr>' + "\n";
		newHTML += '		<td colspan="7">';
		newHTML += '<form name="form' + calendarObj.name + '">';

		newHTML += '<select name="hour" onChange="javascript:chooseHour(' + calendarObj.name + ', this);" class="calendarpulldown">' + "\n";
		for (var i=0; i<12; i++) {
			var thisLabel = (i == 0) ? 12 : i;

			newHTML += '	<option value="' + i + '"';
			if (calendarObj.hour == i || (calendarObj.hour - 12) == i) {newHTML += " selected";}
			newHTML += '>' + thisLabel + "</option>\n";
		}
		newHTML += "</select>\n";

		newHTML += ' : <select name="minute" onChange="javascript:chooseMinute(' + calendarObj.name + ', this);" class="calendarpulldown">' + "\n";
		for (var i=0; i<12; i++) {
			var thisValue = (i * 5);
			var thisLabel = (i * 5);
			if (thisLabel < 10) {thisLabel = "0" + thisLabel;}

			newHTML += '	<option value="' + thisValue + '"';
			if (calendarObj.minute == thisLabel) {newHTML += " selected";}
			newHTML += '>' + thisLabel + "</option>\n";
		}
		newHTML += "</select>\n";

		newHTML += '<select name="ampm" onChange="javascript:chooseAMPM(' + calendarObj.name + ', this);" class="calendarpulldown">' + "\n";
		var ampmArray = ["am", "pm"];
		for (var i=0; i<ampmArray.length; i++) {
			var thisLabel = ampmArray[i];
			newHTML += '	<option value="' + thisLabel + '"';
			if (calendarObj.ampm == thisLabel) {newHTML += " selected";}
			newHTML += '>' + thisLabel + "</option>\n";
		}
		newHTML += "</select>\n";

		newHTML += '</form>';
		newHTML += "		</td>\n";
		newHTML += "	</tr>\n";
	}

	//footer
	newHTML += '	<tr bgcolor="#ccd4e0">' + "\n";
	newHTML += '		<td colspan="4">';
	newHTML += '			<a href="javascript:clearDate(' + calendarObj.name + ');" class="smalltext">clear</a>' + "\n";
	newHTML += ' | <a href="javascript:goToToday(' + calendarObj.name + ');" class="smalltext">go to today</a>' + "\n";
	newHTML += "		</td>\n";
	newHTML += '		<td colspan="3" align="right">' + "\n";
	newHTML += '			<a href="javascript:closeCalendar(' + calendarObj.name + ');" class="smalltext">close</a>' + "\n";
	newHTML += "		</td>\n";
	newHTML += "	</tr>\n";

	newHTML += "</table>\n";

	newHTML += "		</td></tr>\n";
	newHTML += "</table>\n";

	//output HTML to div tag
	calendarObj.divObj.innerHTML = newHTML;

	//move div to proper position
	var left = calendarObj.obj.offsetLeft;
	var parentObj = calendarObj.obj;
	while ((parentObj = parentObj.offsetParent) != null) {
		left += parentObj.offsetLeft;
	}

	var top = calendarObj.obj.offsetTop;
	var parentObj = calendarObj.obj;
	while ((parentObj = parentObj.offsetParent) != null) {
		top += parentObj.offsetTop;
	}

	calendarObj.divObj.style.top = top; // + thisObj.offsetHeight
	calendarObj.divObj.style.left = left + calendarObj.obj.offsetWidth + 2;

	//make sure calendar is visible
	if (calendarObj.divObj.style.visibility) {
		calendarObj.divObj.style.visibility = "visible";
	} else {
		calendarObj.divObj.visibility = "show";
	}

	//hide input if a fresh build
	closeCalendarInput(calendarObj);
}

function showInput(calendarObj) {
	if (calendarObj.inputIsShowing) {
		closeCalendarInput(calendarObj);
		exit;
	}

	//position input object
	var divTop = calendarObj.divObj.style.top.substring(0, calendarObj.divObj.style.top.length - 2);
	calendarObj.inputObj.style.top = (parseInt(divTop) + 18) + "px";
	calendarObj.inputObj.style.left = calendarObj.divObj.style.left;

	//create input HTML	
	var formName = 'form' + calendarObj.name + 'input';
	var currentDate = calendarObj.year + "-";
	if (calendarObj.month < 10) {currentDate += "0";}
	currentDate += calendarObj.month + "-";
	if (calendarObj.day < 10) {currentDate += "0";}
	currentDate += calendarObj.day;

	newHTML = "";

	newHTML += '<div class="smalltext" style="padding: 0px 6px; border-left: 1px #999 solid; border-right: 1px #999 solid; border-bottom: 1px #999 solid; background: #ccd4e0;">' + "\n";

	newHTML += '<form name="' + formName + '" onsubmit="goToDate(' + calendarObj.name + ", '" + formName + "'" + ');return false;">';
	newHTML += '<input type="text" name="inputdate" size="15" value="' + currentDate + '">';
	newHTML += ' <a href="javascript:goToDate(' + calendarObj.name + ", '" + formName + "'" + ');return false;" class="smalltext">go</a>' + "\n";
	newHTML += '</form>';

	newHTML += '</div>' + "\n";

	calendarObj.inputObj.innerHTML = newHTML;

	//make sure calendar is visible
	if (calendarObj.inputObj.style.visibility) {
		calendarObj.inputObj.style.visibility = "visible";
	} else {
		calendarObj.inputObj.visibility = "show";
	}

	calendarObj.inputIsShowing = true;
}

function goToDate(calendarObj, formName) {
	var formObj = document.forms[formName].inputdate;

	var thisMonth = (parseInt(formObj.value.substring(5, 6)) * 10) + parseInt(formObj.value.substring(6, 7));
	var thisYear = parseInt(formObj.value.substring(0, 4));

	formObj.value = "";
	formObj.blur();
	closeCalendarInput(calendarObj);

	if (thisYear >= 1900 && thisYear <= 9999 && thisMonth >= 1 && thisMonth <=12) {
		calendarObj.month = thisMonth;
		calendarObj.year = thisYear;
		buildCalendar(calendarObj);
	}
}

function goToToday(calendarObj) {
	calendarObj.month = currentDate.getMonth() + 1;
	calendarObj.day = currentDate.getDate();
	calendarObj.year = currentDate.getFullYear();

	buildCalendar(calendarObj);
}

function clearDate(calendarObj) {
	calendarObj.obj.value = '';
	updateCalendarDisplay(calendarObj);

//	showCalendar(calendarObj);
	closeCalendar(calendarObj);
}

function chooseDate(calendarObj, newValue) {
	calendarObj.day = newValue;
	updateField(calendarObj);

	if (!calendarObj.showTime) {
		closeCalendar(calendarObj);
	} else {
		showCalendar(calendarObj);
	}
}

function chooseHour(calendarObj, formObj) {
	calendarObj.hour = formObj.options[formObj.selectedIndex].value;
	if (calendarObj.ampm == "pm") {calendarObj.hour = parseInt(calendarObj.hour, 10) + 12;}
	updateField(calendarObj);

	showCalendar(calendarObj);
}

function chooseMinute(calendarObj, formObj) {
	calendarObj.minute = formObj.options[formObj.selectedIndex].value;
	updateField(calendarObj);

	showCalendar(calendarObj);
}

function chooseAMPM(calendarObj, formObj) {
	calendarObj.ampm = formObj.options[formObj.selectedIndex].value;
	if (calendarObj.ampm == "am" && calendarObj.hour >= 12) {
		calendarObj.hour = calendarObj.hour - 12;
	} else if (calendarObj.ampm == "pm" && calendarObj.hour < 12) {
		calendarObj.hour = calendarObj.hour + 12;
	}
	updateField(calendarObj);

	showCalendar(calendarObj);
}

function updateField(calendarObj) {
	var thisValue = calendarObj.year + "-";
	if (calendarObj.month < 10) {thisValue += "0";}
	thisValue += calendarObj.month + "-";
	if (calendarObj.day < 10) {thisValue += "0";}
	thisValue += calendarObj.day;

	if (calendarObj.showTime) {
		thisValue += " ";
		if (calendarObj.hour < 10) {thisValue += "0";}
		thisValue += calendarObj.hour + ":";
		if (calendarObj.minute < 10) {thisValue += "0";}
		thisValue += calendarObj.minute;
	}

	calendarObj.obj.value = thisValue;
	updateCalendarDisplay(calendarObj);
}

function updateCalendarDisplay(calendarObj) {
	var divDisplay = getObj(calendarObj.name + "Display");
	var thisDate = new Date(calendarObj.year, (calendarObj.month - 1), calendarObj.day, calendarObj.hour, calendarObj.minute);

	var newHTML = "";

	newHTML += '<table cellpadding="2" cellspacing="0" border="0"><tr><td>' + "\n";
	newHTML += '<span class="calendarDisplayText">';
	if (!calendarObj.hideWeekname) {newHTML += weekNamesAbbr[thisDate.getDay()] + ", ";}
	if (calendarObj.showFullMonth) {
		newHTML += monthNames[(calendarObj.month - 1)];
	} else {
		newHTML += monthNamesAbbr[(calendarObj.month - 1)];
	}
	newHTML += " " + calendarObj.day;
	if (!calendarObj.hideYear) {newHTML += ", " + calendarObj.year;}

	if (calendarObj.showTime) {
		newHTML += " - ";
		if (calendarObj.hour < 12) {
			newHTML += (calendarObj.hour == 0) ? "12:" : calendarObj.hour + ":";
			newHTML += (calendarObj.minute < 10) ? "0" + calendarObj.minute + "am" : calendarObj.minute + "am";
		} else {
			newHTML += (calendarObj.hour == 12) ? "12:" : (calendarObj.hour - 12) + ":";
			newHTML += (calendarObj.minute < 10) ? "0" + calendarObj.minute + "pm" : calendarObj.minute + "pm";
		}
	}
	newHTML += '</span>' + "\n";
	newHTML += '</tr></td></table>' + "\n";

	divDisplay.innerHTML = (calendarObj.obj.value) ? newHTML : "";

	//move div to proper position
	var left = calendarObj.obj.offsetLeft;
	var parentObj = calendarObj.obj;
	while ((parentObj = parentObj.offsetParent) != null) {
		left += parentObj.offsetLeft;
	}

	var top = calendarObj.obj.offsetTop;
	var parentObj = calendarObj.obj;
	while ((parentObj = parentObj.offsetParent) != null) {
		top += parentObj.offsetTop;
	}

	divDisplay.style.top = top;
	divDisplay.style.left = left;
	divDisplay.style.width = calendarObj.obj.offsetWidth;
	divDisplay.style.height = calendarObj.obj.offsetHeight;

	//make sure calendar is visible
	if (divDisplay.style.visibility) {
		divDisplay.style.visibility = "visible";
	} else {
		divDisplay.visibility = "show";
	}
}

function closeCalendar(calendarObj) {
	if (calendarObj.divObj.style.visibility) {
		calendarObj.divObj.style.visibility = "hidden";
	} else {
		calendarObj.divObj.visibility = "hide";
	}

	closeCalendarInput(calendarObj);
}

function closeCalendarInput(calendarObj) {
	if (calendarObj.inputObj.style.visibility) {
		calendarObj.inputObj.style.visibility = "hidden";
	} else {
		calendarObj.inputObj.visibility = "hide";
	}

	calendarObj.inputIsShowing = false;
}

function createCalendarButton(calendarObj) {
	var newHTML = "";

	newHTML += '<a href="javascript:showCalendar(' + calendarObj.name + ');">';
	newHTML += '<img src="/shared/icons/calendar.gif" width="68" height="15" border="0" align="absmiddle" hspace="2">';
	newHTML += "</a>\n";
	document.write(newHTML);

	document.write('<div id="' + calendarObj.name + 'Display" style="position:absolute; visibility:hidden; width:10; height:10; z-index:' + (zIndex++) + '; background-color:#fff; border: 1px solid #777;"></div>');

	if (calendarObj.obj.value) {
		parseCalendarDate(calendarObj);
		updateField(calendarObj);
	}

	//add this to the list of calendars to be updated when page onLoad
	allCalendars.push(calendarObj);
}

function updateAllCalendars() {
	if (!allCalendars) {return;}

	for (var i=0; i<allCalendars.length; i++) {
		updateCalendarDisplay(allCalendars[i]);
	}
}

function getObj(thisName) {
	if (document.getElementById) {
		var thisObj = document.getElementById(thisName);
	} else if (document.all) {
		var thisObj = document.all[thisName];
	} else if (document.layers) {
		var thisObj = document.layers[thisName];
	}

	return thisObj;
}

//adjust for leap year as needed
function getDaysInMonth(thisMonth, thisYear) {
	if (thisYear % 4 == 0) {
		if ((thisYear % 100) == 0 && (thisYear % 400) != 0) {
			return daysInMonth[thisMonth - 1];
		} else {
			return daysInMonthInLeapyear[thisMonth - 1];
		}
	} else {
		return daysInMonth[thisMonth - 1];
	}
}

//return month/year array for previous and next buttons
function calculateMonthYear(thisMonth, thisYear, thisIncrement) {
	thisMonth += thisIncrement;

	if (thisMonth < 1) {
		thisMonth = 12;
		thisYear--;
	} else if (thisMonth > 12) {
		thisMonth = 1;
		thisYear++;
	}

	return [thisMonth, thisYear];
}

