var datePickerDivID = "datepicker";
var datePickerField = null;
var datePickerClass = "datepicker";
var iFrameDivID = "datepickeriframe";
var embeddedDiv = false;
var embeddedDivSet = false;

var dayArrayShort = new Array('Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa');
var monthArrayShort = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');

// these variables define the date formatting we're expecting and outputting.
// If you want to use a different format by default, change the defaultDateSeparator
// and defaultDateFormat variables either here or on your HTML page.
var dateSeparator = "-";
var dateFormat = "ymd";

var forwardLimitDays = 2147483647;
var backLimitDays = 2147483647;

function displayDatePicker(fieldName, anchorObject, backDays, forwardDays, tableClass) {

	if (backDays) {
		backLimitDays = backDays;
	}
	if (forwardDays) {
		forwardLimitDays = forwardDays;
	}
	if (tableClass) {
		datePickerClass = tableClass;
	}

	datePickerField = document.getElementsByName(fieldName).item(0);
	
	// If no object is given for displaying the calendar below, use
	// the named field.
	if (!anchorObject) {
		anchorObject = datePickerField;
	}
	
	var x = anchorObject.offsetLeft;
	var y = anchorObject.offsetTop + anchorObject.offsetHeight;
 
	// Deal with elements inside tables and such
	var parent = anchorObject;
	while (parent.offsetParent) {
		parent = parent.offsetParent;
		x += parent.offsetLeft;
		y += parent.offsetTop;
	}

	drawDatePicker(x, y);

}


/**
Draw the datepicker object (which is just a table with calendar elements) at the
specified x and y coordinates, using the field object as the input tag that will
ultimately be populated with a date.

This function will normally be called by the displayDatePicker function.
*/
function drawDatePicker(x, y) {
	var dt = getFieldDate(datePickerField.value);
	
	var display = false;

	// The datepicker table will be drawn inside of a <div> with an ID defined by the
	// global datePickerDivID variable. If such a div doesn't yet exist on the HTML
	// document we're working with, add one.
	if (!document.getElementById(datePickerDivID)) {
		var newNode = document.createElement("div");
		newNode.setAttribute("id", datePickerDivID);
		newNode.setAttribute("class", "dpDiv");
		newNode.setAttribute("style", "visibility: hidden;");
		document.body.appendChild(newNode);
		if (!embeddedDivSet) {
			embeddedDiv = false;
			embeddedDivSet = true;
		}
		display = true;
	} else if (!embeddedDivSet) {
		embeddedDiv = true;
		embeddedDivSet = true;
	}

	if (!embeddedDiv) {
		// Move the datepicker div to the proper x,y coordinate and toggle the visiblity
		var pickerDiv = document.getElementById(datePickerDivID);
		if (!display) {
			display = pickerDiv.style.visibility == "hidden";
		}
		pickerDiv.style.position = "absolute";
		pickerDiv.style.left = x + "px";
		pickerDiv.style.top = y + "px";
	//	pickerDiv.style.visibility = (pickerDiv.style.visibility == "visible" ? "hidden" : "visible");
		pickerDiv.style.visibility = "hidden";
		pickerDiv.style.display = "none";
	//	pickerDiv.style.display = (pickerDiv.style.display == "block" ? "none" : "block");
		pickerDiv.style.zIndex = 10000;
		// Draw the datepicker table
		refreshDatePicker(datePickerField.name, dt.getFullYear(), dt.getMonth(), dt.getDate());
		if (display) {
			pickerDiv.style.visibility = "visible";
			pickerDiv.style.display = "block";
		}
		adjustiFrame();
	} else {
		refreshDatePicker(datePickerField.name, dt.getFullYear(), dt.getMonth(), dt.getDate());
	}
	
}


/**
Draws the datepicker calendar.
*/
function refreshDatePicker(fieldName, year, month, day) {
	
	// If no arguments are passed, use today's date; otherwise, month and year
	// are required (if a day is passed, it will be highlighted later).
	var thisDay = new Date();
	if ((month >= 0) && (year > 0)) {
		thisDay = new Date(year, month, 1);
	} else {
		day = thisDay.getDate();
		thisDay.setDate(1);
	}
	
	var today = new Date();
	var backLimitDate = new Date(today.getTime() - (backLimitDays * 24 * 60 * 60 * 1000));
	var forwardLimitDate = new Date(today.getTime() + (forwardLimitDays * 24 * 60 * 60 * 1000));

	var html = "<table class=\"" + datePickerClass + "\">";
	
	var backYearEnabled = true;
	var backMonthEnabled = true;
	var forwardMonthEnabled = true;
	var forwardYearEnabled = true;
	
	if ((new Date(thisDay.getFullYear() - 1, month, 31)).getTime() < backLimitDate) {
		backYearEnabled = false;
	}
	if ((new Date(thisDay.getTime() - 1)).getTime() < backLimitDate) {
		backMonthEnabled = false;
	}
	if ((new Date(thisDay.getTime() + (30 * 24 * 60 * 60 * 1000))).getTime() > forwardLimitDate) {
		forwardMonthEnabled = false;
	}
	if ((new Date(thisDay.getFullYear() + 1, month, 1)).getTime() > forwardLimitDate) {
		forwardYearEnabled = false;
	}
	
	// Title bar, displays the current month and buttons to skip forward
	// or backward one month or year.
	html += "<tr>";
	if (backYearEnabled) {
		html += "<td class=\"skip\"><a href=\"javascript:" + getSkipAction(fieldName, thisDay, -12) + "\"><img src=\"/styles/shared/pagination_first.gif\" alt=\"Previous year\"/></a></td>";
	} else {
		html += "<td class=\"skip\"></td>";
	}
	if (backMonthEnabled) {
		html += "<td class=\"skip\"><a href=\"javascript:" + getSkipAction(fieldName, thisDay, -1) + "\"><img src=\"/styles/shared/pagination_prev.gif\" alt=\"Previous month\"/></a></td>";
	} else {
		html += "<td class=\"skip\"></td>";
	}
	html += "<td class=\"title\" colspan=\"3\">" + monthArrayShort[ thisDay.getMonth()] + " " + thisDay.getFullYear() + "</td>";
	if (forwardMonthEnabled) {
		html += "<td class=\"skip\"><a href=\"javascript:" + getSkipAction(fieldName, thisDay, +1) + "\"><img src=\"/styles/shared/pagination_next.gif\" alt=\"Next month\"/></a></td>";
	} else {
		html += "<td class=\"skip\"></td>";
	}
	if (forwardYearEnabled) {
		html += "<td class=\"skip\"><a href=\"javascript:" + getSkipAction(fieldName, thisDay, +12) + "\"><img src=\"/styles/shared/pagination_last.gif\" alt=\"Next year\"/></a></td>";
	} else {
		html += "<td class=\"skip\"></td>";
	}
	html += "</tr>";
 
	// Weekday headers
	html += "<tr>";
	var i;
	for(i = 0; i < dayArrayShort.length; i++) {
		html += "<th>" + dayArrayShort[i] + "</th>";
	}
	html += "</tr>";

	html += "<tr>";
 
	// Leading blanks
	for (i = 0; i < thisDay.getDay(); i++) {
		html += "<td>&nbsp;</td>";
	}
 
	// Days of the month
	do {
		var dayNum = thisDay.getDate();
		var onclick = "updateDateField('" + fieldName + "', '" + getDateString(thisDay) + "');";
		var enabled = true;
		if (thisDay.getTime() > forwardLimitDate.getTime() || thisDay.getTime() < backLimitDate.getTime()) {
			enabled = false;
		}
		
		if (dayNum == day) {
			html += "<td class=\"date\"><a href=\"javascript:" + onclick + "\" class=\"selected\">" + dayNum + "</a></td>";
		} else {
			if (enabled) {
				html += "<td class=\"date\"><a href=\"javascript:" + onclick + "\">" + dayNum + "</a></td>";
			} else {
				html += "<td class=\"date-disabled\">" + dayNum + "</td>";
			}
		}

		// Start a new row after Saturday
		if (thisDay.getDay() == 6) {
			html += "</tr><tr>";
		}
    
		// Increment the day
		thisDay.setDate(thisDay.getDate() + 1);
	} while (thisDay.getDate() > 1)

	// Trailing blanks
	if (thisDay.getDay() > 0) {
		for (i = 6; i > thisDay.getDay(); i--) {
			html += "<td>&nbsp;</td>";
		}
	}
	html += "</tr>";

	html += "</table>";

	document.getElementById(datePickerDivID).innerHTML = html;
	// Add an "iframe shim" to allow the datepicker to display above selection lists
	adjustiFrame();
}

/**
Convenience function for writing the code for the buttons that bring us back
or forward a month or year.
*/
function getSkipAction(fieldName, dateVal, adjust) {
	var newMonth = (dateVal.getMonth () + adjust) % 12;
	var newYear = dateVal.getFullYear() + parseInt((dateVal.getMonth() + adjust) / 12);
	if (newMonth < 0) {
		newMonth += 12;
		newYear += -1;
	}
	return "refreshDatePicker(\'" + fieldName + "\', " + newYear + ", " + newMonth + ");";
}

/**
Convert a JavaScript Date object to a string, based on the dateFormat and
dateSeparator variables at the beginning of this script library.
*/
function getDateString(dateVal) {

	var dayString = "00" + dateVal.getDate();
	var monthString = "00" + (dateVal.getMonth()+1);
	dayString = dayString.substring(dayString.length - 2);
	monthString = monthString.substring(monthString.length - 2);
	 
	switch (dateFormat) {
		case "dmy" :
			return dayString + dateSeparator + monthString + dateSeparator + dateVal.getFullYear();
		case "ymd" :
			return dateVal.getFullYear() + dateSeparator + monthString + dateSeparator + dayString;
		case "mdy" :
		default :
			return monthString + dateSeparator + dayString + dateSeparator + dateVal.getFullYear();
	}
	
}

/**
Convert a string to a JavaScript Date object.
*/
function getFieldDate(dateString) {

	var dateVal;
	var dArray;
	var d, m, y;
	 
	try {
		dArray = splitDateString(dateString);
		if (dArray) {
			switch (dateFormat) {
				case "dmy" :
					d = parseInt(dArray[0], 10);
					m = parseInt(dArray[1], 10) - 1;
					y = parseInt(dArray[2], 10);
					break;
				case "ymd" :
					d = parseInt(dArray[2], 10);
					m = parseInt(dArray[1], 10) - 1;
					y = parseInt(dArray[0], 10);
					break;
				case "mdy" :
				default :
					d = parseInt(dArray[1], 10);
					m = parseInt(dArray[0], 10) - 1;
					y = parseInt(dArray[2], 10);
					break;
			}
			dateVal = new Date(y, m, d);
		} else if (dateString) {
			dateVal = new Date(dateString);
		} else {
			dateVal = new Date();
		}
	} catch(e) {
		dateVal = new Date();
	}
	
	return dateVal;
}

/**
Try to split a date string into an array of elements, using common
date separators. If the date is split, an array is returned;
otherwise, we just return false.
*/
function splitDateString(dateString) {

	var dArray;
	if (dateString.indexOf("/") >= 0) {
		dArray = dateString.split("/");
	} else if (dateString.indexOf(".") >= 0) {
		dArray = dateString.split(".");
	} else if (dateString.indexOf("-") >= 0) {
		dArray = dateString.split("-");
	} else if (dateString.indexOf("\\") >= 0) {
		dArray = dateString.split("\\");
	} else {
		dArray = false;
	}
	return dArray;
	
}

/**
Update the field with the given fieldName with the dateString that
has been passed, and hide the datepicker. If no dateString is passed,
just close the datepicker without changing the field value. 

Also, if the page developer has defined a function called datePickerClosed
anywhere on the page or in an imported library, we will attempt to run that
function with the updated field as a parameter. This can be used for such
things as date validation, setting default values for related fields, etc.
For example, you might have a function like this to validate a start date
field:

function datePickerClosed(dateField)
{
  var dateObj = getFieldDate(dateField.value);
  var today = new Date();
  today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
 
  if (dateField.name == "StartDate") {
    if (dateObj < today) {
      // if the date is before today, alert the user and display the datepicker again
      alert("Please enter a date that is today or later");
      dateField.value = "";
      document.getElementById(datePickerDivID).style.visibility = "visible";
      adjustiFrame();
    } else {
      // if the date is okay, set the EndDate field to 7 days after the StartDate
      dateObj.setTime(dateObj.getTime() + (7 * 24 * 60 * 60 * 1000));
      var endDateField = document.getElementsByName ("EndDate").item(0);
      endDateField.value = getDateString(dateObj);
    }
  }
}

*/
function updateDateField(fieldName, dateString) {
	
	var field = document.getElementsByName (fieldName).item(0);
	if (dateString) {
		field.value = dateString;
	}
	if (!embeddedDiv) {
		var pickerDiv = document.getElementById(datePickerDivID);
		pickerDiv.style.visibility = "hidden";
		pickerDiv.style.display = "none";
		adjustiFrame();
		field.focus();
		
		// After the datepicker has closed, optionally run a user-defined function called
		// datePickerClosed, passing the field that was just updated as a parameter
		// (note that this will only run if the user actually selected a date from the datepicker)
		if ((dateString) && (typeof(datePickerClosed) == "function")) {
			datePickerClosed(field);
		}
	} else {
		drawDatePicker();
		if ((dateString) && (typeof(datePickerSelect) == "function")) {
			datePickerSelect(field);
		}
	}

}


/**
Use an "iFrame shim" to deal with problems where the datepicker shows up behind
selection list elements, if they're below the datepicker.
*/
function adjustiFrame(pickerDiv, iFrameDiv) {
	if (!embeddedDiv) {
		// Stop Opera from attempting this.
		var is_opera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1);
		if (is_opera) {
			return;
		}
		// put a try/catch block around the whole thing, just in case
		try {
			if (!document.getElementById(iFrameDivID)) {
				var newNode = document.createElement("iframe");
				newNode.setAttribute("id", iFrameDivID);
				newNode.setAttribute("src", "javascript:false;");
				newNode.setAttribute("scrolling", "no");
				newNode.setAttribute ("frameborder", "0");
				document.body.appendChild(newNode);
			}
			if (!pickerDiv) {
				pickerDiv = document.getElementById(datePickerDivID);
			}
			if (!iFrameDiv) {
				iFrameDiv = document.getElementById(iFrameDivID);
			}
	    
			try {
				iFrameDiv.style.position = "absolute";
				iFrameDiv.style.width = pickerDiv.offsetWidth;
				iFrameDiv.style.height = pickerDiv.offsetHeight ;
				iFrameDiv.style.top = pickerDiv.style.top;
				iFrameDiv.style.left = pickerDiv.style.left;
				iFrameDiv.style.zIndex = pickerDiv.style.zIndex - 1;
				iFrameDiv.style.visibility = pickerDiv.style.visibility;
				iFrameDiv.style.display = pickerDiv.style.display;
			} catch(e) { }
		} catch (ee) { }
	}
}