// JavaScript Calendar for Liberty
// Make sure to also put calendar.inc in the file you are calling this from
// @author Jason Gabriele, Travwell

var months = new Array('January','February','March','April','May','June','July','August','September','October','November','December');

var defaultDay = new Date().getDate();
var defaultMonth = new Date().getMonth()+1;
var defaultYear = new Date().getFullYear();

var selectedDay = defaultDay;
var selectedMonth = defaultMonth;
var selectedYear = defaultYear;

//Iframe's src location
var iFrameSource = '';
//field open
//var object
var inAction = false;
//array to hold objects
var compareArray = null;
//second month is present
//set to true if second month is present
var secondMonth = true;
//is konqueror?
//workaround for khtml browsers
var khtml = false;
var netscape = false;
var firefox = false;
if(window.navigator.product) {
	if(window.navigator.product.toLowerCase().indexOf("khtml")!=-1) khtml = true;
}
//check for safari and netscape
if(window.navigator.vendor) {
	if(window.navigator.vendor.toLowerCase().indexOf("apple")!=-1) {
		khtml = true;
	} else if(window.navigator.vendor == "Netscape") { 
		netscape = true;
	} else if(window.navigator.vendor == "Firefox") {
		firefox = true;
	}
}
//for firefox bug
var alreadyShown = false;
//is QA Server
var qaServer = false;
if(window.location.href.indexOf("qa.")!=-1) qaServer = true;
//number of days to skip forward by default
//only applicable to the compareFields function
//and only when day fields are already filled in
var daySkip = 0;

function showCalendar(inputBox) {
	if(showCalendar.arguments.length == 0) return false;
	
	if(!alreadyShown && firefox) {
		document.getElementById("cal_frame").style.display = "block";
		document.getElementById("cal_frame").style.display = "none";
		alreadyShown = true;
	}
	
	checkFormat(inputBox); //replace dashes
	
	if(showCalendar.arguments.length > 2) {
		compareArray = new Array(showCalendar.arguments.length-1);
		for(var i=1;i<showCalendar.arguments.length;i++) {
			compareArray[i-1] = showCalendar.arguments[i];
		}
	}
	
	if(inputBox.value == "" || !inputBox.value.indexOf("/") || inputBox.value == "mm/dd/yyyy" || inputBox.value == "MM/DD/YYYY") {
		year = defaultYear;
		month = defaultMonth;
		day = defaultDay;
	} else {
		var dateParts = inputBox.value.split("/");
		if(dateParts.length == 3) {
			month = new Number(dateParts[0]);
			day = new Number(dateParts[1]);
			year = new Number(dateParts[2]);
		} else {
			year = defaultYear;
			month = defaultMonth;
			day = defaultDay;
		}
	}
	
	//set year dropdown
	var drop = window.frames["cal_frame"].document.forms["calendarForm"].yearDrop.options;
	
	for(var x = 0; x < drop.length; x++) {
		if(drop[x].value == year) {
			window.frames["cal_frame"].document.forms["calendarForm"].yearDrop.selectedIndex = x;
			break;
		}
	}
	//set month dropdown
	window.frames["cal_frame"].document.forms["calendarForm"].monthDrop.selectedIndex = month-1;

	if(inAction) {
		hideCalendar();
	}
	inAction = inputBox;
	calendar(month,day,year,1);

	if(secondMonth) {
		if(month == 12) {
			calendar(1,1,parseInt(year)+1,2);
		} else {
			calendar(parseInt(month)+1,1,year,2);
		}
	}
	
	if(khtml || netscape) {
		document.getElementById("cal_frame").style.visibility = "visible";
	} else {
		document.getElementById("cal_frame").style.display = "block";
	}
	
	positionWindow(inputBox);
}

//pass true if you want to save
function hideCalendar(save) {
	if(!inAction) return;
	if(save) {
		inAction.value = getSelectedMonth() + "/" + getSelectedDay() + "/" + getSelectedYear();
	}
	inAction = null;

	if(khtml || netscape) {
		document.getElementById("cal_frame").style.visibility = "hidden";
	} else {
		document.getElementById("cal_frame").style.display = "none";
	}
	
	if(compareArray) {
		compareFields();
	}
}

//returns true if calendar is shown
function isCalendarShown() {
	return inAction;
}

function returnDate(month,day,year) {
	today = new Date();
	tempDate = new Date(year,month-1,day);
	if((tempDate.getTime() - today.getTime()) > 31536000000) {
		alert("Sorry, you cannot book dates more than 1 year in advance.");
		return false;
	}
	
	inAction.value = month + "/" + day + "/" + year;
	hideCalendar();
}

function calendar(month,day,year,calNum) {

	if(!month) month = defaultMonth;
	if(!day) day = defaultDay;
	if(!year) year = defaultYear;
	if(!calNum) calNum = 1;
	
	//make sure date is valid
	if(!checkValid(month,day,year)) return false;
		
	var selected = new Date(year,month-1,day);
	if(calNum == 1) {
		//set selected
		selectedDay = day;
		selectedMonth = month;
		selectedYear = year;
	}

	//start table
	var tdCount = 0;
	var html = "<table class='calendar'><tr>";
	html += "<th colspan='7'>" + months[selected.getMonth()] + "</th>";
	html += "</tr><tr>";
	
	//get start day
	var firstDay = new Date(year,month-1,1).getDay();
	for(var x=0; x<firstDay; x++) {
		html += "<td>&nbsp;</td>";
		tdCount++;
	}
	
	today = new Date();
	
	//make calendar
	for(var x = 1; x<=31; x++) {
		if(tdCount % 7 == 0) html += "</tr><tr>";
		
		if(checkValid(month,x,year)) {
			var tempDay = new Date(year,month-1,x);
			returnCode = "" + month + "," + x + "," + year;
			html += "<td";
			if(calNum == 1 && x == selectedDay && month == selectedMonth && year == selectedYear) {
				if((tempDay.getTime() - today.getTime()) < 0) {
					html += " class='selected'>" + tempDay.getDate() + "</td>";
				} else {
					html += " class='selected'><a href='javascript:void parent.returnDate(" + returnCode + ")'>" + tempDay.getDate() + "</a></td>";
				}
			} else if((tempDay.getTime() - today.getTime()) < 0) {
				html += " class='past'>" + tempDay.getDate() + "</td>";
			} else {
				html += "><a href='javascript:void parent.returnDate(" + returnCode + ")'>" + tempDay.getDate() + "</a></td>";
			}
		} else {
			break;
		}
		tdCount++;
	}

	//finish with blank cells
	if((tdCount%7)>0) {
		var left =  7 - tdCount%7;
		for(var x=0;x<left;x++) {
			html += "<td>&nbsp;</td>";
		}
	}
	
	html += "</tr></table>";
	
	window.frames["cal_frame"].document.getElementById("calendar"+calNum).innerHTML = html;
	
	return true;
}

function updateCalendar() {
	month = getSelectedMonth();
	day = getSelectedDay();
	year = getSelectedYear();
	calendar(month,day,year,1);
	if(secondMonth) {
		if(month == 12) {
			calendar(1,1,parseInt(year)+1,2);
		} else {
			calendar(parseInt(month)+1,1,year,2);
		}
	}
	positionWindow(inAction);
}

function checkValid(month,day,year) {
	tryDate = new Date(year,month-1,day);
	if(tryDate.getFullYear() == year && 
	   tryDate.getDate() == day &&
	   tryDate.getMonth() == month - 1) {
		return true;
	} else {
		return false;
	}
}

//checks a string and returns a date object
function extractDate(dateString) {
	if(dateString == "" || !dateString.indexOf("/") || dateString.toLowerCase() == "mm/dd/yyyy") {
		return false;
	} else {
		var dateParts = dateString.split("/");
		if(!dateParts.length == 3) {
			return false;
		} else {
			month = new Number(dateParts[0]);
			day = new Number(dateParts[1]);
			year = new Number(dateParts[2]);
		}
		
		if(checkValid(month,day,year)) {
			return new Date(year,month-1,day);
		} else {
			return false;
		}
	}
}

function getSelectedYear() {
	var drop = window.frames["cal_frame"].document.forms["calendarForm"].yearDrop;
	return selectedYear = drop.options[drop.selectedIndex].value;
}
function getSelectedDay() {
	return selectedDay;
}
function getSelectedMonth() {
	var drop = window.frames["cal_frame"].document.forms["calendarForm"].monthDrop;
	return selectedMonth = drop.options[drop.selectedIndex].value;
}

//setup the fields with todays date.
// @param objects 1 or more fields to populate
function setupFields(fields) {
	if(setupFields.arguments.length == 0) return false;

	//setup first field if necessary
	if(setupFields.arguments[0].value == "" || setupFields.arguments[0].value.toLowerCase() == "mm/dd/yyyy") {
    	var tempDay = defaultDay + 14;
    	var tempMonth = defaultMonth;
    	var tempYear = defaultYear;
	    futureDate = new Date(tempYear,tempMonth-1,tempDay);
	    setupFields.arguments[0].value = "" + (futureDate.getMonth()+1) + "/" + futureDate.getDate() + "/" + futureDate.getFullYear();
	} else { //extract current date
	    var tempDate;
	    if(!(tempDate = extractDate(setupFields.arguments[0].value))) return false;
	    var tempDay = tempDate.getDate();
    	var tempMonth = tempDate.getMonth()+1;
    	var tempYear = tempDate.getFullYear();
	}
	
	//setup rest of the fields
	if(setupFields.arguments.length > 1) {
		for(var i=1;i<setupFields.arguments.length;i++) {
		    if(setupFields.arguments[i].value == "" || setupFields.arguments[i].value.toLowerCase() == "mm/dd/yyyy") {
			    var futureEndDate = new Date(tempYear,tempMonth-1,tempDay+3);
			    setupFields.arguments[i].value = "" + (futureEndDate.getMonth()+1) + "/" + futureEndDate.getDate() + "/" + futureEndDate.getFullYear();
			    tempDay+=3;
			} else {
			    var tempDate;
	            if(!(tempDate = extractDate(setupFields.arguments[i].value))) return false;
        	    tempDay = tempDate.getDate();
            	tempMonth = tempDate.getMonth()+1;
            	tempYear = tempDate.getFullYear();
			}
		}
	}
}

//check several fields to make sure they operate in order
function compareFields() {
	if(compareArray==null || compareArray.length < 2) return false;
	checkFormat(compareArray[0]); //replace dashes
	
	var tempDate;
	var previousDate;
	
	for(var i=1;i<compareArray.length;i++) {
		if(compareArray[i].value == "" && (previousDate = extractDate(compareArray[i-1].value))) {
			startYear = previousDate.getFullYear();
	   		startDay = previousDate.getDate();
	   		startMonth = previousDate.getMonth()+1;
	   		
			futureDate = new Date(startYear,startMonth-1,startDay+daySkip);
			compareArray[i].value = "" + (futureDate.getMonth()+1) + "/" + futureDate.getDate() + "/" + futureDate.getFullYear();
		} else {
			checkFormat(compareArray[i]); //replace dashes
			if((tempDate = extractDate(compareArray[i].value)) && (previousDate = extractDate(compareArray[i-1].value))) {
		   		startYear = previousDate.getFullYear();
		   		startDay = previousDate.getDate();
		   		startMonth = previousDate.getMonth()+1;
		   		
				endYear = tempDate.getFullYear();
		   		endDay = tempDate.getDate();
		   		endMonth = tempDate.getMonth()+1;
		   		
		   		if(checkValid(startMonth,startDay,startYear) && checkValid(endMonth,endDay,endYear)) {
					if((startMonth >= endMonth && startDay > endDay && startYear >= endYear) || 
					   (startMonth > endMonth && startYear >= endYear) ||
					    startYear > endYear) { //end day is before start day
						futureDate = new Date(startYear,startMonth-1,startDay+daySkip);
						compareArray[i].value = "" + (futureDate.getMonth()+1) + "/" + futureDate.getDate() + "/" + futureDate.getFullYear();
					}
				} else {
					break;
				}
			} else {
				break;
			}
		}
	}
}

//check for dashes
//param string field to check
function checkFormat(field) {
	if(field.value.indexOf("-")!=-1) {
		var replaceDashes = /-/g;
		field.value = field.value.replace(replaceDashes, "/");
	}
}

//Move calendar forward one month
function moveMonthForward() {
	moveCalendarMonth(1);
}
//Move calendar backward one month
function moveMonthBackward() {
	moveCalendarMonth(-1);
}
//Move calendar by increment
//param int negative=back, positive=forward
function moveCalendarMonth(moveIncrement) {
	month = parseInt(getSelectedMonth());
	day = parseInt(getSelectedDay());
	year = parseInt(getSelectedYear());
		
	//if current month is december then move forward one year
	var tempYearIndex = parseInt(window.frames["cal_frame"].document.forms["calendarForm"].yearDrop.selectedIndex);
	if((month + moveIncrement) > 12) {
		var moveToMonth = 1;
		var moveToYear = year + 1;
		var tempYearIndex = tempYearIndex + 1;
	} else if((month + moveIncrement) < 1) {
		var moveToMonth = 12;
		var moveToYear = year - 1;
		var tempYearIndex = tempYearIndex - 1;
	} else {
		var moveToMonth = month + moveIncrement;
		var moveToYear = year;
	}
	
	//check if date is out of range of calendar
	var numOptions = window.frames["cal_frame"].document.forms["calendarForm"].yearDrop.options.length;
	var lowOption = parseInt(window.frames["cal_frame"].document.forms["calendarForm"].yearDrop.options[0].value);
	var highOption = parseInt(window.frames["cal_frame"].document.forms["calendarForm"].yearDrop.options[numOptions-1].value);
	if(moveToYear < lowOption || moveToYear > highOption) {
		alert("Sorry. That date is out of the range currently available for reservations.");
		return;
	}
	
	//check if day is out of range for month
	if(!checkValid(moveToMonth,day,moveToYear)) {
		
	}
	
	calendar(moveToMonth,day,moveToYear,1);
	if(secondMonth) {
		if(moveToMonth+1 == 13) {
			calendar(1,1,moveToYear+1,2);
		} else {
			calendar(moveToMonth+1,1,moveToYear,2);
		}
	}
	
	//update select boxes first before calling calendar
	window.frames["cal_frame"].document.forms["calendarForm"].monthDrop.selectedIndex = moveToMonth - 1;
	window.frames["cal_frame"].document.forms["calendarForm"].yearDrop.selectedIndex = tempYearIndex;
	
	positionWindow(inAction);
}

//Positioning 
//Taken from http://www.quirksmode.org/about/copyright.html
function findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

function findPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}

//position the window according to the inputBox and its position in the window
//param object the input box you are working on
function positionWindow(inputBox) {

	xPos = findPosX(inputBox);
	yPos = findPosY(inputBox) + 22;
	
	if (window.innerWidth) {
        windowWidth = window.innerWidth + window.pageXOffset - 20;
    } else {
        windowWidth = document.body.offsetWidth + document.body.scrollLeft - 20;
	}

	//modified code from quirksmode - resizes the iframe in case its too small for its contents - modified by jason
	if(document.getElementById('cal_frame').contentWindow) {
		var test1 = document.getElementById('cal_frame').contentWindow.document.body.scrollHeight;
		var test2 = document.getElementById('cal_frame').contentWindow.document.body.offsetHeight;
		if (test1 > test2) {// all but Explorer Mac
			document.getElementById('cal_frame').style.height = "" + document.getElementById('cal_frame').contentWindow.document.body.scrollHeight + "px";
			document.getElementById('cal_frame').style.width = "" + document.getElementById('cal_frame').contentWindow.document.body.scrollWidth + "px";
			if(windowWidth < (parseInt(document.getElementById('cal_frame').style.width)+xPos)) {
				var moveLeft = ((parseInt(document.getElementById('cal_frame').style.width)+xPos)-windowWidth);
				if(!isNaN(moveLeft) && (moveLeft>0)) {
					xPos -= moveLeft;
				}
			}
		} else { // Explorer Mac;
			document.getElementById('cal_frame').height = "" + document.getElementById('cal_frame').contentWindow.document.body.offsetHeight + "px";
			document.getElementById('cal_frame').width = "" + document.getElementById('cal_frame').contentWindow.document.body.offsetWidth + "px";
			if(windowWidth < (parseInt(document.getElementById('cal_frame').width)+xPos)) {
				var moveLeft = ((parseInt(document.getElementById('cal_frame').width)+xPos)-windowWidth);
				if(!isNaN(moveLeft) && (moveLeft>0)) {
					xPos -= moveLeft;
				}
			}
		}
	}

	document.getElementById("cal_frame").style.left = "" + xPos + "px";
	document.getElementById("cal_frame").style.top = "" + yPos + "px";
}

//Creates the iframe instance
function createCalenderHTML() {
	if(document.body.appendChild) {
		var spana = document.createElement("span");
		spana.innerHTML = "<iframe id='cal_frame' name='cal_frame' src='" + iFrameSource + "'></iframe>";
		document.body.appendChild(spana);
		if(khtml || netscape) {
			document.getElementById("cal_frame").style.visibility = "hidden";
		} else {
			document.getElementById("cal_frame").style.display = "none";
		}
	}
}
//Switch on and off the iframe (for external scripts) (mac only)
function calFrameOn() {
	if(khtml || netscape) {
		document.getElementById("cal_frame").style.visibility = "visible";
	}
}
function calFrameOff() {
	if(khtml || netscape) {
		document.getElementById("cal_frame").style.visibility = "hidden";
	}
}
