/**************************************************************************************
  htmlDatePicker v0.1
  
  Copyright (c) 2005, Jason Powell
  All Rights Reserved

  Redistribution and use in source and binary forms, with or without modification, are 
    permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of 
      conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list 
      of conditions and the following disclaimer in the documentation and/or other materials 
      provided with the distribution.
    * Neither the name of the product nor the names of its contributors may be used to 
      endorse or promote products derived from this software without specific prior 
      written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 
  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
  OF THE POSSIBILITY OF SUCH DAMAGE.
  
  -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  
  Script amended by Mark Small on behalf of RND Software Technology Inc. (Canada) 2009

  
***************************************************************************************/
// User Changeable Vars
var HighlightToday  = true;    // use true or false to have the current day highlighted
var DisablePast    = true;    // use true or false to allow past dates to be selectable

// The month names in your native language can be substituted below
var MonthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
var MonthLengths = new Array(31,28,31,30,31,30,31,31,30,31,30,31);

// Global Vars
var now;
var eDate;
var wDate;
var ny; // Today's Date
var nm;
var nd;
var sy; // currently Selected date
var sm;
var sd;
var y; // Working Date
var m;
var d;
var color;
var calBtn;

var YEAR = 0;
var MONTH = 1;
var DAY = 2;

var dateNode_a = [ null, null, null ];

//Ensure that the correct date nodes are present on the HTML form
function getDateNodes() {
	
	var retVal = true;
	
	dateNode_a = [ null, null, null ];
	var node_a = document.getElementsByTagName("select");
	for (var i = 0; i < node_a.length; i++) {
		
		switch (node_a[i].getAttribute("name")) {
			
			case "arrivalDay":
				dateNode_a[DAY] = node_a[i];
				break;
			
			case "arrivalMonth":
				dateNode_a[MONTH] = node_a[i];
				break;
			
			case "arrivalYear":
				dateNode_a[YEAR] = node_a[i];
				break;
			
			default: break;
		}
	}
	
	if (!dateNode_a[DAY] || !dateNode_a[MONTH] || !dateNode_a[YEAR]) {
		
		alert("HTML form does NOT contain the necessary form fields");
		retVal = false;
	}
	
	return retVal;
}

/*
  Function: GetDate()
  Function fired from html element
*/
function GetDate(node) {
	
	DestroyCalendar();
	
	calBtn = node;
	
	//collect the date component values from form variables
	if (!dateNode_a[0])
		if (!getDateNodes()) return;
	
	//Create a date from the form fields values
	sy = Number(dateNode_a[YEAR].value).valueOf();
	sm = Number(dateNode_a[MONTH].value).valueOf();
	sd = Number(dateNode_a[DAY].value).valueOf();
	wDate = new Date(sy, sm, sd);
	
	//prevent historic dates
	if (now.getTime() > wDate.getTime()) {
		
		sy = ny;
		sm = nm;
		sd = nd;
	}
	
	y = sy;
	m = sm;
	d = sd;
	
	DrawCalendar();
	
	return;
}

/*
  function DestoryCalendar()
  
  Purpose: Destory any already drawn calendar so a new one can be drawn
*/
function DestroyCalendar() {
	
	var cal = document.getElementById("dpCalendar");
	if (!cal) cal = EnsureCalendarExists();
	cal.innerHTML = "";
	cal.style.display = "none";
	return;
}

function DrawCalendar() {
	
	DestroyCalendar();
	
  	var cal = document.getElementById("dpCalendar");
	
	var sCal= "<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\">"
			+ "<tbody>"
			+ "<tr>"
			+   "<td class=\"cellButton\">"
			+     "<span onclick=\"PrevMonth();\" onmouseover=\"setPointerOn(this);\" onmouseout=\"setPointerOff(this);\" title=\"Previous Month\">&lt;&lt;</span>"
			+   "</td>"
			+   "<td class=\"cellMonth\" width=\"80%\" colspan=\"5\">"
			+     MonthNames[m] + " " + y
			+   "</td>"
			+   "<td class=\"cellButton\">"
			+     "<span onclick=\"NextMonth();\" onmouseover=\"setPointerOn(this);\" onmouseout=\"setPointerOff(this);\" title=\"Next Month\">&gt;&gt;</span>"
			+   "</td>"
			+ "</tr>"
			+ "<tr>"
			+   "<td>S</td><td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td>"
			+ "</tr>"
			;
	
	var wDay = 1;
	wDate = new Date(y, m, wDay);
	MonthLengths[1] = (isLeapYear(wDate)) ? 29 : 28;
	
	var dayclass = "";
	var isToday = false;
	for(var r = 1; r < 7; r++) {
		
		sCal += "<tr>";
		
		for (var c = 0; c < 7; c++) {
			
			wDate = new Date(y, m, wDay);
//if (eDate) {
//	alert("eDate: "+eDate.getFullYear()+"-"+(eDate.getMonth()+1)+"-"+eDate.getDate()+"\n"+
//	"wDate: "+wDate.getFullYear()+"-"+(wDate.getMonth()+1)+"-"+wDate.getDate());
//}
			if ((wDate.getDay() == c) && (wDay <= MonthLengths[m])) {
				
				if ((wDate.getDate() == sd) && (wDate.getMonth() == sm) && (wDate.getFullYear() == sy)) {
					
					dayclass = "cellSelected";
					isToday = true;  // only matters if the selected day IS today, otherwise ignored.
				}
				else if ((wDate.getDate() == nd) && (wDate.getMonth() == nm) && (wDate.getFullYear() == ny) && HighlightToday) {
					
		          dayclass = "cellToday";
		          isToday = false;
		        }
				else if (eDate && (eDate.getTime() < wDate.getTime())) {
					
		          dayclass = "cellOld";
		          isToday = false;
		        }
				else {
					
					dayclass = "cellOld";
					isToday = false;
				}
				
				if (eDate && (eDate.getTime() < wDate.getTime())) {
					
					// user wants past dates to be read only
					sCal += "<td class=\"" + dayclass + "\">" + wDay + "</td>";
				}
				else if (((now > wDate) && !DisablePast) || (now <= wDate) || isToday) { // >
					
					// user wants past dates selectable
					if (dayclass == "cellOld") dayclass = "cellDay";
					sCal	+= "<td id=\"" + dayclass + "\" class=\"" + dayclass + "\" onclick=\"ReturnDay(this);\" onmouseover=\"setPointerOn(this);\" onmouseout=\"setPointerOff(this);\">"
							+    wDay
							+  "</td>"
							;
				}
				else {
					
					// user wants past dates to be read only
					sCal += "<td class=\"" + dayclass + "\">" + wDay + "</td>";
				}
				
				wDay++;
			}
			else {
				sCal += "<td class=\"unused\"></td>";
			}
		}
		
		sCal = sCal + "</tr>";
	}
	
	sCal	+= "<tr>"
  			+    "<td colspan=\"4\" class=\"unused\"></td>"
			+    "<td colspan=\"3\" id=\"cellCancel\" class=\"cellCancel\" onclick=\"DestroyCalendar();\" onmouseover=\"setPointerOn(this);\" onmouseout=\"setPointerOff(this);\">"
			+      "Cancel"
			+    "</td>"
			+  "</tr>"
			+  "</tbody>"
			+  "</table>"
			;

	cal.innerHTML = sCal; // works in FireFox, opera
	cal.style.display = "inline";
	
	var l = 0;
	var tmp = calBtn;
	var name;
	do {
		
		l += tmp.offsetLeft;
		tmp = tmp.offsetParent;
		name = tmp.nodeName.toLowerCase();
		
	} while ((name != "body") && (name != "html"));
	
	if (l < 0) l = 10;

	var t = 0;
	tmp = calBtn;
	do {
		
		t += tmp.offsetTop;
		tmp = tmp.offsetParent;
		name = tmp.nodeName.toLowerCase();
		
	} while ((name != "body") && (name != "html"));
	
	
	t -= cal.offsetHeight;
	t += calBtn.offsetHeight;
	if (t < 0) t = 10;
	
	cal.style.left = l + "px";
	cal.style.top = t + "px";
}

function PrevMonth() {
	
	m--;
	if (m == -1) {
		
		m = 11;
		y--;
	}
	DrawCalendar();
}

function NextMonth() {
	
	m++;
	if (m == 12) {
		
		m = 0;
		y++;
	}
	DrawCalendar();
}

function ReturnDay(node) {
	
	d = Number(node.childNodes[0].nodeValue).valueOf();
	
	//ensure that form supports the selected year
	var node_a = dateNode_a[YEAR].getElementsByTagName("option");
	if (node_a.length > 0) {
		
		if (y > Number(node_a[node_a.length - 1].childNodes[0].nodeValue).valueOf()) {
			
			while (dateNode_a[YEAR].hasChildNodes()) dateNode_a[YEAR].removeChild(dateNode_a[YEAR].childNodes[0]);
			for (var i = ny; i <= y; i++) {
				
				var node = document.createElement("option");
				node.value = Number(i).toString();
				var text = document.createTextNode(node.value);
				node.appendChild(text);
				dateNode_a[YEAR].appendChild(node);
			}
		}
	}
	
	dateNode_a[YEAR].value = y;
	dateNode_a[MONTH].value = m;
	dateNode_a[DAY].value = d;
	DestroyCalendar();
}

function EnsureCalendarExists() {
	
	var cal = document.getElementById("dpCalendar");
	if (!cal) {
		
		cal = document.createElement("div");
		cal.setAttribute("id", "dpCalendar");
		document.body.appendChild(cal);
	}
	return cal;
}

function isLeapYear(dTest) {
	
	var y = dTest.getYear();
	var bReturn = false;
	
	if (y % 4 == 0) {
		
		if (y % 100 != 0) bReturn = true;
		else if (y % 400 == 0) bReturn = true;
	}

	return bReturn;
}

function setPointerOn(node) {
	
	node.style.cursor = "pointer";
	var id = node.getAttribute("id");
	if (!id) id = "";
	if (id == "cellCancel") {
		color = node.style.backgroundColor;
		node.style.backgroundColor = "#aaa";
	}
	
	else if (id == "cellDay") {
		node.style.border = "solid 1px blue";
	}
}

function setPointerOff(node) {
	
	node.style.cursor = "default";
	var id = node.getAttribute("id");
	if (!id) id = "";
	if (id == "cellCancel") node.style.backgroundColor = color;
	
	else if (id == "cellDay") {
		node.style.borderColor = "transparent";
	}
}

function start_up() {
	
	now = new Date();
	ny = now.getFullYear();
	nm = now.getMonth();
	nd = now.getDate();
	
	var node = document.getElementById("startDate");
	if (node) {
		
		var re = new RegExp("^2[0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]$");
		var date = node.value;
		if (date.search(re) != -1) {
			
			var match_a = date.match(/(.*)-(.*)-(.*)/);
			var sDate = new Date(Number(match_a[1]).valueOf(), Number(match_a[2]).valueOf() - 1, Number(match_a[3]).valueOf());
			if (sDate.getTime() > now.getTime()) {
				
				now = sDate;
				ny = now.getFullYear();
				nm = now.getMonth();
				nd = now.getDate();
			}
		}
	}
	
	eDate = null;
	node = document.getElementById("endDate");
	if (node) {
		
		var re = new RegExp("^2[0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]$");
		var date = node.value;
		if (date.search(re) != -1) {
			
			var match_a = date.match(/(.*)-(.*)-(.*)/);
			eDate = new Date(Number(match_a[1]).valueOf(), Number(match_a[2]).valueOf() - 1, Number(match_a[3]).valueOf());

			if (eDate < now) {
				
				eDate = null;
				alert("Invalid End Date specified");
			}
		}
	}
	
	var node_a = document.getElementsByTagName("select");
	for (var i = 0; i < node_a.length; i++) {
		
		switch (node_a[i].getAttribute("name")) {
			
			case "arrivalYear":
				while (node_a[i].hasChildNodes()) node_a[i].removeChild(node_a[i].childNodes[0]);
				for (j = 0; j < 2; j++) {
					
					node = document.createElement("option");
					node.value = Number(ny + j).toString();
					var text = document.createTextNode(node.value);
					node.appendChild(text);
					node_a[i].appendChild(node);
				}
				break;
			
			default: break;
		}
	}
	
	//collect the date component values from form variables
	if (!dateNode_a[0])
		if (!getDateNodes()) return;
	
	//set the default date to today
	dateNode_a[YEAR].value = ny;
	dateNode_a[MONTH].value = nm;
	dateNode_a[DAY].value = nd;
	
	//set date field validations
	dateNode_a[YEAR].onchange = valid_date;
	dateNode_a[MONTH].onchange = valid_date;
	dateNode_a[DAY].onchange = valid_date;
}

function valid_date() {
	
	var year = parseInt(dateNode_a[YEAR].value);
	var month = parseInt(dateNode_a[MONTH].value);
	var day = parseInt(dateNode_a[DAY].value);
	
	wDate = new Date(year, month, day);
	dateNode_a[YEAR].value = wDate.getFullYear();
	dateNode_a[MONTH].value = wDate.getMonth();
	dateNode_a[DAY].value = wDate.getDate();
	
	if (wDate.getTime() < now.getTime()) {
		dateNode_a[YEAR].value = ny;
		dateNode_a[MONTH].value = nm;
		dateNode_a[DAY].value = nd;
	}
	
	else if (eDate && (eDate.getTime() < wDate.getTime())) {
		dateNode_a[YEAR].value = eDate.getFullYear();
		dateNode_a[MONTH].value = eDate.getMonth();
		dateNode_a[DAY].value = eDate.getDate();
	}
}

