
function Calendar(leftCalendar, rightCalendar) {
	var logger = LogFactory.getLog("Calendar.js");
	var self = this;
	var months = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");

    // HTML ID values for the left and right calendar elements
	this.leftCal = leftCalendar;
	this.rightCal = rightCalendar;

    // The javascript reservation object
	var reservation;
	this.setReservation = function (r) {
		reservation = r;
	};
	var calendarDateRegex = new RegExp("^\\d{6}$");
	var calTableRegex = new RegExp("^\\d{4}$");
	var tempMessage = "<div class='calTempMessage'>Loading availability ....</div>";
	var MAX_DAYS_BETWEEN_START_END = 20;
	var calIdLoaded = new Array();
	calIdLoaded[this.leftCal] = false;
	calIdLoaded[this.rightCal] = false;
	var calIdDate = new Array();
	var today = new Date();
	var jumpToDiv;
//    var calLeft;
//    var calRight;
	this.init = function () {
		var clearDates = document.getElementById("clearDates");
		clearDates.onclick = function () {
			reservation.clearDates();
            //reservation.setStartDate("");
			self.updateCalendars();
			return false;
		};
		jumpToDiv = document.getElementById("jumpToMonth");
//        calLeft     = document.getElementById( "calLeft" );
//        calRight     = document.getElementById( "calRight" );

        // Set mouseovers
		var links = jumpToDiv.getElementsByTagName("a");
		for (var i = 0; i < links.length; i++) {
			links[i].onmouseover = function (e) {
				var elem = getEventSource(e);
				var msg;
				if (elem.innerText) {
					msg = "Jump To: " + elem.innerText;
				} else {
					msg = "Jump To: " + elem.text;
				}
				window.status = msg;
				return true;
			};
			links[i].onmouseout = function () {
				window.status = "";
				return true;
			};
		}
	};
	this.loadCalendars = function () {
//       try{
		if (arguments[0] && !(calIdLoaded[self.leftCal] && calIdLoaded[self.rightCal])) {
            // Skip this if there is an argument and both cals aren't loaded
			return;
		}
		var leapCal;
		try {
			leapCal = document.getElementById("frmLeapCal").value;
		}
		catch (ie) {
		}
		if (calIdLoaded[self.leftCal]) {
            // load with the existing date on the left
			var cal1 = document.getElementById(self.leftCal);
			var tableId;
			var tNodes = cal1.getElementsByTagName("table");
			for (var i = 0; i < tNodes.length; i++) {
				tableId = tNodes[i].id;
			}
			if (!tableId.substr) {
				return;
			}
			var leftDate = tableId.substr(8, 4);
			if (!calTableRegex.test(leftDate)) {
				return;
			}
			self.loadCalsFromString(leftDate);
		} else {
			if (leapCal) {
				self.loadCalsFromString(leapCal);
			} else {
				if (res.getStartDate().length == 0) {
            // Today's month goes on the left
					var firstCal = "" + today.getFullYear() + getMonthAsString(today);
					firstCal = firstCal.substr(2, 6);
					var lastCal = getNextMonthString(today);
					self.getCalendar(this.leftCal, firstCal);
					self.getCalendar(this.rightCal, lastCal);
				} else {
					self.loadCalsFromString(res.getStartDate().substr(0, 4));
				}
			}
		}
//       }catch( e ){
//          return;
//       }
	};
	this.loadCalsFromString = function (dateStr) {
		//alert("dateStr " + dateStr);
		var startMonth = dateStr.substr(2, 2) - 1;
		//alert("startMonth" + startMonth);
		firstCal = dateStr;
		var check = startMonth - today.getMonth();
		//alert("check " + check);
		if (check != -2 && check != 10) {
			//alert("check != -2 && check != 10")
			if (startMonth == 11) {
				var rightDate = dateStr.substring(0, 2);
				rightDate *= 1;
				rightDate++;
				rightDate = "" + rightDate;
				if (rightDate.length == 1) {
					rightDate = "0" + rightDate;
				}
				lastCal = rightDate + "01";
			} else {
				lastCal = dateStr.substring(0, 2) + (((startMonth + 2) < 10) ? "0" : "") + (startMonth + 2);
			}
		} else {
			lastCal = firstCal;
			if (startMonth == 0) {
				//alert("startMonth == 0");
				firstCal = (dateStr.substring(0, 2) - 1) + "12";
				if (firstCal.length == 3)
					firstCal = "0" + firstCal;
			} else {
				firstCal = dateStr.substring(0, 2) + (((startMonth) < 10) ? "0" : "") + (startMonth);
			}
		}
		//alert("firstCal " + firstCal + " lastCal " + lastCal);
		self.getCalendar(self.leftCal, firstCal);
		self.getCalendar(self.rightCal, lastCal);
	};
	function getMonthAsString(date) {
		var mon = date.getMonth() + 1;
		return ((mon < 10) ? "0" + mon : mon);
	}

    // onclick handler to load calendars based on a date
	var loadCalendarsForDate = function (e) {
        //alert("loadCalendarsForDate");
		var elem = getEventSource(e);
		if (elem.id.length > 0 && elem.id.indexOf("jmpto") == 0) {
			try {
				document.getElementById("frmLeapCal").value = elem.id.substr(5, 4);
			}
			catch (ie) {
			}
			self.loadCalsFromString(elem.id.substr(5, 4));
		}
		return false;
	};
	this.getCalendar = function (calId, date) {
		logger.debug("Enter getCalendar(), calId=", calId, ", date=", date);
		if (!calTableRegex.test(date)) {
			return;
		}

        disableLeftRight();
		var calElem = document.getElementById(calId);
		calElem.innerHTML = tempMessage; // is this necessary?
		calIdLoaded[calId] = false;
		var year = "20" + date.substr(0, 2);
		var month = date.substr(2, 4);
		var http = getHTTPObject();
		var cursorHelper = new CursorHelper();
		cursorHelper.setNewCursor("wait");
        // Should this be a POST?
		var uri = "/GetCalendar.do?" + reservation.getFormPostData() + "&calDate=" + date;
		http.open("GET", uri);
		http.onreadystatechange = function () {
			if (http.readyState == 4) {
				if (http.status == 200) {
					logger.debug("in handleHttpResponse() - setting innerHTML");
					calElem.innerHTML = http.responseText;
					calIdLoaded[calId] = true;
					calElem.onclick = selectDate; // do this here?
					self.updateCalendar(calId);
					calIdDate[calId] = new Date(year, month - 1, 1);
                    enableLeftRight();
				} else {
					logger.warn("Problem with response, code = ", http.status, "\n", http.responseText);
				}
				cursorHelper.removeCursor();
			}
		};
		http.send(null);
		logger.debug("Exit getCalendar()");
	};
	this.updateCalendar = function (calId) {
		logger.debug("Enter updateCalendar(), calId=", calId);
		var calElem = document.getElementById(calId);
		calElem.onclick = selectDate;
		var nodes = calElem.getElementsByTagName("A");
		for (var i = 0; i < nodes.length; i++) {
			var nodei = nodes[i];
			var subNode = nodei.lastChild;
			if (subNode.nodeType == 1) {
				nodei.removeChild(subNode);
			}
			if (reservation.getStartDate().length == 0 || reservation.getStartDate() > nodei.id) {
				removeSelClass(nodei);
			} else {
				if (reservation.getStartDate() == nodei.id) {
					if (reservation.isValid()) {
						addAmount(nodei, reservation.getAmount(nodei.id));
						addSelClass(nodei);
					} else {
						addSelClass(nodei);
					}
				} else {
					if (reservation.getEndDate().length == 0 || reservation.getEndDate() < nodei.id) {
						removeSelClass(nodei);
					} else {
						if (reservation.isValid()) {
							addAmount(nodei, reservation.getAmount(nodei.id));
							addSelClass(nodei);
						} else {
							addSelClass(nodei);
						}
					}
				}
			}
		}
		logger.debug("Exit updateCalendar(), calId=", calId);
	};
	function removeSelClass(node) {
		var className = node.className;
		if (className.indexOf(" sel") > 0) {
			node.className = className.substring(0, className.indexOf(" sel"));
		}
	}
	function addSelClass(node) {
		if (node.className.indexOf(" sel") < 0) {
			node.className = node.className + " sel";
		}
	}
	var tmpNode = document.createElement("SPAN");
	function addAmount(node, amount) {
		var newNode = tmpNode.cloneNode(false);
		var newTxt = document.createTextNode(amount);
		newNode.appendChild(newTxt);
		node.appendChild(newNode);
	}
	var selectDate = function (e) {
		logger.debug("Enter selectDate()");
		var elem = getEventSource(e);
		logger.debug("ID: ", elem.id, "\nStart Date: ", reservation.getStartDate(), "\nEnd Date: ", reservation.getEndDate());
        //alert("ID: " + elem.id + "\nStart Date: " + reservation.getStartDate() + "\nEnd Date: " + reservation.getEndDate());
		if (elem.id == null || elem.id == "" || !calendarDateRegex.test(elem.id)) {
            // The user clicked on something other than a selectable date
			return false;
		}
		if (reservation.getStartDate() == elem.id) {
            //alert("selectDate 1");
			reservation.setStartDate("");
			reservation.setEndDate("");
		} else {
			if (reservation.getStartDate().length == 0 || reservation.getEndDate().length > 0) {
                //alert("selectDate 2");
				reservation.setStartDate(elem.id);
				reservation.setEndDate("");
			} else {
				if (reservation.getEndDate().length == 0) {
					var tmpDate = reservation.getStartDate();
					var numDays = daysBetweenDateStrings(tmpDate, elem.id);
					if (numDays > MAX_DAYS_BETWEEN_START_END) {
						logger.debug("Too many days between: ", numDays);
                        //alert("selectDate 3");
						reservation.setStartDate(elem.id);
						reservation.setEndDate("");
					} else {
						if (reservation.getStartDate() > elem.id) {
                            //alert("selectDate 4");
							reservation.setStartDate(elem.id);
							reservation.setEndDate(tmpDate);
						} else {
							reservation.setEndDate(elem.id);
						}
					}
				} else {
//            alert("Should not get here!");
				}
			}
		}
		self.updateCalendars();
		logger.debug("Exit selectDate()");
		return false;
	};
	this.updateCalendars = function () {
		logger.debug("Enter updateCalendars()");
		this.updateCalendar(self.leftCal);
		this.updateCalendar(self.rightCal);
		logger.debug("Exit updateCalendars()");
	};
	var ONE_DAY = 1000 * 60 * 60 * 24;
	function daysBetweenDateStrings(dateStr1, dateStr2) {
		logger.debug("Enter daysBetweenDateStrings()");
		date1 = getDateFromIdString(dateStr1);
		date2 = getDateFromIdString(dateStr2);
        // The number of milliseconds in one day

        // Convert both dates to milliseconds
		var date1_ms = date1.getTime();
		var date2_ms = date2.getTime();

        // Calculate the difference in milliseconds
		var difference_ms = Math.abs(date1_ms - date2_ms);

        // Convert back to days and return
		logger.debug("Exit daysBetweenDateStrings()");
		return Math.round(difference_ms / ONE_DAY);
	}
	function getDateFromIdString(dateStr) {
		var year = "20" + dateStr.substr(0, 2);
		var month = dateStr.substr(2, 2);
		var day = dateStr.substr(4, 2);
		var date = new Date(year, month - 1, day);
		return date;
	}
    var disableLeftRight = function() {
        logger.debug("Enter disableLeftRight()");
        jumpToDiv.onclick = function() { return false; };
/*
        calLeft.onclick = null;
        calLeft.style.display = "none";
        calRight.onclick = null;
        calRight.style.display = "none";
*/
        logger.debug("Exit disableLeftRight()");
    }
    var enableLeftRight = function() {
        logger.debug("Enter enableLeftRight()");

        var loaded = true;
        for( var i in calIdLoaded ) {
            logger.debug("CalId: ", i, " loaded? ", calIdLoaded[i]);
            loaded = loaded && calIdLoaded[i];
        }

        if( loaded ) {
            logger.debug("LOADED!");
/*            
            var leftMonth = calIdDate[self.leftCal].getMonth();
            var rightMonth = calIdDate[self.rightCal].getMonth();
            var todayMonth = today.getMonth();
            if( leftMonth != todayMonth ) {
                calLeft.onclick  = calendarLeft;
                var lm = leftMonth - 1;
                lm = (lm<0) ? 11 : lm;
                calLeft.innerHTML = months[lm];
                calLeft.style.display = "block";
            }
            var check = rightMonth - todayMonth
            if(  check != -2 && check != 10 ) {
                calRight.onclick = calendarRight;
                calRight.innerHTML = months[ (rightMonth+1)%12 ];
                calRight.style.display = "block";
            }
*/
            jumpToDiv.onclick = loadCalendarsForDate;

        }

        logger.debug("Exit enableLeftRight()");
    }

	var calendarRight = function () {
		logger.debug("Enter calendarRight()");

        disableLeftRight();
		var cal1 = document.getElementById(self.leftCal);
		var cal2 = document.getElementById(self.rightCal);
		cal1.innerHTML = cal2.innerHTML;
		calIdDate[self.leftCal] = calIdDate[self.rightCal];
		var tDate = getNextMonthString(calIdDate[self.rightCal]);
		self.getCalendar(self.rightCal, tDate);
		logger.debug("Exit calendarRight()");
		return false;
	};
	function getNextMonthString(date) {
		logger.debug("Enter getNextMonthString()");
		var year = date.getFullYear();
		var month = date.getMonth();
		if (month == 11) {
			month = 1;
			year += 1;
		} else {
			month += 2;
		}
		if (month < 10) {
			month = "0" + month;
		}
		tYear = "" + year;
		tDate = "" + tYear.substring(2, 4) + month;
		logger.debug("Exit getNextMonthString()");
		return tDate;
	}
	var calendarLeft = function () {
		logger.debug("Enter calendarLeft()");
        disableLeftRight();
		var cal1 = document.getElementById(self.leftCal);
		var cal2 = document.getElementById(self.rightCal);
		cal2.innerHTML = cal1.innerHTML;
		calIdDate[self.rightCal] = calIdDate[self.leftCal];
		var year = calIdDate[self.leftCal].getFullYear();
		var month = calIdDate[self.leftCal].getMonth();
		if (month == 0) {
			month = 12;
			year -= 1;
		}
		if (month < 10) {
			month = "0" + month;
		}
		tYear = "" + year;
		tDate = "" + tYear.substring(2, 4) + month;
		self.getCalendar(self.leftCal, tDate);
		logger.debug("Exit calendarLeft()");
		return false;
	};
}

