var daysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var showingCalendar = false;
var today = new Date();

function ShowCalendar(ctrl, hiddenCtrl, date, hilightDate, includeWeekends, minDate, minMonth, minYear, maxDate, maxMonth, maxYear, calendarEventHandler)
{
	var browserName = navigator.appName;
	var modifier = "";
	
	if(browserName == "Netscape"){
	  modifier = "px";
	}
	
	var html = "<table border=0 cellpadding=2 cellspacing=0 class=\"calender\">";

	var startDate = new Date(minYear, minMonth, minDate);
	var endDate = new Date(maxYear, maxMonth, maxDate);
	var yearSpan = maxYear - minYear;
	
	if (date == undefined) {
		date = new Date()
	}
		
	var thisMonth = new Date(date.getFullYear(), date.getMonth(), 1);
	
	// Case where user selects a month > endMonth and then toggles the year to the end year value.
	// As such we need to update the month to be equal to endMonth.
	if (!Calendar_IsSelectableDate(thisMonth, includeWeekends, startDate, endDate)) {
		  thisMonth = new Date(endDate.getFullYear(), endDate.getMonth(), 1);
	}
	
	var startOfMonths = 0;
	var endOfMonths = 11;
	
	if (thisMonth.getFullYear() == startDate.getFullYear()) {
		startOfMonths = startDate.getMonth();
	}
	
	if (thisMonth.getFullYear() == endDate.getFullYear()) {
		endOfMonths = endDate.getMonth(); 
	}
    
    // add the drop downs for month and year
	html += "<tr height=\"30\"><td colspan=\"7\" align=\"center\" valign=\"middle\" class=\"calendar_title\">";

	html += "&nbsp;&nbsp;<select class=\"calendar_dropdown\" name=\"calendar_year\" id=\"calendar_year\" onChange=\"ShowCalendar('" + ctrl + "','" + hiddenCtrl + "', new Date(this[this.selectedIndex].value," + date.getMonth() + ", 1), false," + includeWeekends + "," + minDate + "," + minMonth + "," + minYear + "," + maxDate + "," + maxMonth + "," + maxYear + ",'" + calendarEventHandler + "');\">";
	for (var i = 0; i <= yearSpan; i++) {
		html += "<option value=\"" + (minYear + i) + "\"" + (((minYear + i) == date.getFullYear()) ? " selected" : "") + ">&nbsp;" + (minYear + i) + "&nbsp;</option>";
	}
	html += "</select>";

	html += "&nbsp;&nbsp;<select class=\"calendar_dropdown\" name=\"calendar_month\" id=\"calendar_month\" onChange=\"ShowCalendar('" + ctrl + "','" + hiddenCtrl + "', new Date(" + date.getFullYear() + ",this[this.selectedIndex].value, 1), false," + includeWeekends + "," + minDate + "," + minMonth + "," + minYear + "," + maxDate + "," + maxMonth + "," + maxYear + ",'" + calendarEventHandler + "');\">";
		
	for (var i = startOfMonths; i <= endOfMonths; i++) {
		html += "<option value=\"" + i + "\"" + ((i == thisMonth.getMonth()) ? " selected" : "") + ">&nbsp;" + months[i] + "&nbsp;</option>";
	}
	html += "</select>";

	html += "</td></tr>";

	// add the day headers
	html += "<tr>";
	for (var i = 0; i < days.length; i++) {
		html += "<td align=\"center\" class=\"calendar_dayheader\">" + days[i] + "</td>";
	}
	html += "</tr>";

	// start writing the days
	html += "<tr>"

	// first go to the right spot
	var position = 0;
	for (var i = 0; i < thisMonth.getDay(); i++) {
		html += "<td align=\"center\">&nbsp;</td>";
		position++;
	}

	// now iterate through the days and add them
	var thisDate;

	for (var i = 0; i < Calendar_GetDaysInMonth(thisMonth.getMonth(), thisMonth.getFullYear()); i++)
	{
		thisDate = new Date(thisMonth.getFullYear(), thisMonth.getMonth(), i+1);
		
		
		//If the calendar month currently selected in the dropDown menu is not within the bounds endDate.getMonth(),
		//default the month to endDate.getMonth() i.e. last month that can have a date that is selectable.
		if (!Calendar_IsSelectableDate(thisDate, includeWeekends, startDate, endDate)) {
		  thisDate = new Date(endDate.getFullYear(), endDate.getMonth(), i+1);
		}
		
		thisDate.setHours(today.getHours());
		thisDate.setMinutes(today.getMinutes());
			
				
		html += "<td align=\"center\"";
		
		if (hilightDate == true && date.getDate() == (i+1)) {

			if (Calendar_IsSelectableDate(thisDate, includeWeekends, startDate, endDate)) {
				html += " class=\"calendar_selectedday\"";
			}
			else {
				html += " class=\"calendar_day_bold\"";
			}
		}
		else if (!Calendar_IsSelectableDate(thisDate, includeWeekends, startDate, endDate)) {
			html += " class=\"calendar_day_disabled\"";			
		}
		else {
			html += " class=\"calendar_day\"";
		}

		//day_verbose = Format_GetDay((i+1), (thisMonth.getMonth()+1), thisMonth.getFullYear());
		day_verbose = Format_GetDay((i+1), (thisDate.getMonth()+1), thisDate.getFullYear());
		
		html += ">";

		if (!Calendar_IsSelectableDate(thisDate, includeWeekends, startDate, endDate)) {
			html += (i+1);
		}
		else {
			html += "<a class=\"calendar_link\" href=\"javascript:Calendar_SetDate('" + ctrl + "','" + day_verbose + "');document.getElementById('" + hiddenCtrl + "').value='" + thisDate.getTime() + "';HideCalendar('" + calendarEventHandler + "')\" onMouseOver=\"window.status='" + day_verbose + "'; return true;\" onMouseOut=\"window.status=''; return true;\">" + (i+1) + "</a>";
		}
		
		html += "</td>";

		position++;

		if (position % 7 == 0) {
			html += "</tr><tr>";
		}
	}

	if (position % 7 != 0) {
		html += "</tr>";
	}

	// add the hide calendar button
	html += "<tr><td colspan=7 height=\"20\" align=\"right\" valign=\"middle\" class=\"calendar_footer\"><a class=\"calendar_link\" href=\"javascript:HideCalendar('" + calendarEventHandler + "');Mask_DisplayFomattedDate(document.getElementById('" + ctrl + "'));\" onMouseOver=\"window.status='" + LABEL_CLOSE + "'; return true;\" onMouseOut=\"window.status=''; return true;\">" + LABEL_CLOSE + "</a>&nbsp;&nbsp;</td></tr>";

	html += "</table>";

	// output
	calendarDiv = document.getElementById("calendar");
	calendarDiv.innerHTML = html;
	calendarFrame = document.getElementById("calendar_frame");

	// display the calendar under the control
	var dateInputControl = document.getElementById(ctrl);
	calendarDiv.style.top = Calendar_LocateY(dateInputControl) + (dateInputControl.offsetHeight + 2) + modifier;
	calendarDiv.style.left = Calendar_LocateX(dateInputControl) + modifier;
	
	// set the iframe
	calendarFrame.style.width = calendarDiv.offsetWidth+modifier;
	calendarFrame.style.height = calendarDiv.offsetHeight+modifier;
	calendarFrame.style.top = calendarDiv.style.top+modifier;
	calendarFrame.style.left = calendarDiv.style.left+modifier;
	calendarFrame.style.zIndex = calendarDiv.style.zIndex - 1;
	calendarFrame.style.display = "block";
	
	calendarFrame.style.visibility = "visible";
	calendarDiv.style.visibility = "visible";
	showingCalendar = true;
}

function Calendar_IsSelectableDate(date, includeWeekends, startDate, endDate)
{

	// check the year
	if (date.getFullYear() < startDate.getFullYear()) {
		return false;
	}
		
	// check the month
	if (date.getFullYear() == startDate.getFullYear() && date.getMonth() < startDate.getMonth()) {
		return false;
	}
		
	// check the date
	if (date.getFullYear() == startDate.getFullYear() && date.getMonth() == startDate.getMonth() && date.getDate() < startDate.getDate()) {
		return false;
	}
		
	// check the year
	if (date.getFullYear() > endDate.getFullYear()) {
		return false;
	}
	
	// check the month
	if (date.getFullYear() == endDate.getFullYear() && date.getMonth() > endDate.getMonth()) {
		return false;
	}
	
	// check the date
	if (date.getFullYear() == endDate.getFullYear() && date.getMonth() == endDate.getMonth() && date.getDate() > endDate.getDate()) {
		return false;
	}
	
	// if we are including weekends, then just return true
	if (includeWeekends) {
		return true;
	}

	// if we are nto including weekends, then see if the day the date occurs is either sunday or saturday, if they are, return false, else return true
	return (!includeWeekends && date.getDay() != 0 && date.getDay() != 6);
}

function Calendar_SetDate(field, date) {
	(document.getElementById(field)).value = date;
}

function Calendar_GetDate(field) {

	f = document.getElementById(field);

	if (f == null || f.value == "") {
		return new Date();
	}
    else {
        return Format_ParseDate(f.value);
    }
}

function Calendar_GetDaysInMonth(month, year) {

	// check to see if the month/year combinate falls on a leap year, if so, return 29, instead of 28
	if (month == 1) {
		if ((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0)) {
			return 29;
		}
		else {
			return 28;
		}
	}
	else {
		return daysInMonth[month];
	}
}

function Calendar_SetDateInMS(ctrl, hiddenCtrl) {
	var date = Format_ParseDate(document.forms[0].elements[ctrl].value);
	
	if (date != undefined) {
		document.forms[0].elements[hiddenCtrl].value = date.getTime();
	}
	else {
		document.forms[0].elements[hiddenCtrl].value = "";
	}
}

function Calendar_ValidateDateRange(date, minDate, maxDate, includeWeekends) {
	if (date != undefined) {
		if (!Calendar_IsSelectableDate(date, includeWeekends, minDate, maxDate)) {
			alert(MESSAGE_INVALID_DATE);
			return false;
		}
	}
	
	return true;
}

function HideCalendar(calendarEventHandler) {
	(document.getElementById("calendar")).style.visibility = "hidden";
	(document.getElementById("calendar_frame")).style.visibility = "hidden";
	showingCalendar = false;

	if (eval(calendarEventHandler))
	{	
		eval(calendarEventHandler).fireHideCalender();
	}
}

function Calendar_LocateX(item) {
	if (item.offsetParent) {
		return item.offsetLeft + Calendar_LocateX(item.offsetParent);
	}
	else {
		return item.offsetLeft;
	}
}

function Calendar_LocateY(item) {
	if (item.offsetParent) {
		return item.offsetTop + Calendar_LocateY(item.offsetParent);
	}
	else {
		return item.offsetTop;
	}
}


/* Calendar Event Handler */
function CalendarEventHandler(){}
CalendarEventHandler.prototype.fireHideCalender = function(){}
