
var dontUpdateDate = false;


function makeDate(f, name, tostring)
{
	var dayElem = f.elements[name + "_day"];
	var monthElem = f.elements[name + "_month"];
	var timeElem = f .elements[name + "_time"];

	var day = parseInt(dayElem.options[dayElem.selectedIndex].value, 10);
	var month = parseInt(monthElem.options[monthElem.selectedIndex].value.substring(0, 2), 10);
	var year = parseInt(monthElem.options[monthElem.selectedIndex].value.substring(3), 10);
	var daysInFeb = ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) ? 29 : 28;
	var daysInMonth = new Array(31, daysInFeb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

	if (day > daysInMonth[month - 1])
	{
		return false;
	}
	else
	{
		var datestring = month + "/" + day + "/" + year;
		var hour = null;

		if (timeElem)
		{
			hour = parseInt(timeElem.options[timeElem.selectedIndex].value, 10);
			if (hour) datestring += " " + hour + ":00";
		}

		return (tostring) ? datestring : new Date(year, month - 1, day, hour);
	}
}

/**
 * updates one set of date inputs based on the value of another
 *
 * f - form object reference
 * from - name of the date element set to use as the first date
 * to - name of the date element set to use for the second date
 * days - days to add to the first date to get the new value for the second
 */
function updateDate(f, from, to, days)
{
	var Date1 = makeDate(f, from);
	var Date2 = makeDate(f, to);

	updateDaysDrop(f, from);
	
	if ((Date1 <= Date2) || !Date1 || !Date2 || dontUpdateDate)
	{
		return;
	}
	
	var newDate = new Date(Date1.getTime() + (days * 24 * 60 * 60 * 1000));
	setDate(f, to, newDate);
	updateDaysDrop(f, to);	
}

/**
 *	Updates a date drop down to contain the correct number of days for
 *	the month selected in the corresponding date selection box
 *
 *	f - form object reference
 *	field - The prefix for the day drop down field, ie 'departure' if the drop down's id is 'departure_days'
 */
function updateDaysDrop(f, field)
{
	var select = GetElement(field + '_day');
	
	var date;
	
	while(!(date = makeDate(f, field))) {
		var new_index = parseInt(select.value, 10) - 2;
		
		select.options[new_index].selected = true;
		date = makeDate(f, field);
	}
	
	var days = daysInMonth(date);
	
	var selectedVal = select.value;
	
	select.options.length = 0;
	
	for(var i = 1; i <= days; i++) {
		select.options[i - 1] = new Option(i, i);
		
		if(i == parseInt(selectedVal)) {
			select.options[i - 1].selected = true;
		}
	}
}

/**
 *	Returns the number of days in the month of the given date object
 *
 *	date - js Date object
 */
function daysInMonth(date)
{
	var month = date.getMonth();
	
	var daysArray = new Array(12);
	
	daysArray[0] = 31;	//January
	daysArray[1] = leapYear(date) ? 29 : 28;	//February
	daysArray[2] = 31;	//March
	daysArray[3] = 30;	//April
	daysArray[4] = 31;	// May
	daysArray[5] = 30;	// June
	daysArray[6] = 31;	// July
	daysArray[7] = 31;	// August
	daysArray[8] = 30;	// September
	daysArray[9] = 31;	// October
	daysArray[10] = 30;	// November
	daysArray[11] = 31;	// December
	
	return daysArray[month];
}

/**
 *	Returns true if the given date is in a leap year
 *
 *	date - js Date object
 */
function leapYear(date)
{
	var year = date.getYear() + 1900;
	
	/* Determines leap years using the following rule
	 *	A year evenly divisible by 4 is a leap year
	 *	Exception - A year divisible by 100 is not a leap year
	 *
	 *	A year evenly divisible by 400 is a lep year  
	 */
	
	return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
}

/**
 * sets a set of form elements to a specified date
 *
 * f - form object reference
 * name - name of element set to update
 * dateObj - js Date object
 */
function setDate(f, name, dateObj, triggerOnchange)
{	
	if (f.elements[name + "_month"])
	{
		for (var i = 0; i < f.elements[name + "_month"].options.length; i++)
		{
			var optVal = f.elements[name + "_month"].options[i].value;
			var optMonth = parseInt(optVal.substring(0,2), 10);
			var optYear = parseInt(optVal.substring(3), 10);
			if ((optMonth == (dateObj.getMonth() + 1))
				&& ((optYear == dateObj.getYear() + 1900) // required by some browsers
					|| (optYear == dateObj.getYear())))
			{
				f.elements[name + "_month"].selectedIndex = i;
				updateDaysDrop(f, name);
				f.elements[name + "_day"].selectedIndex = (dateObj.getDate() - 1);

				if (triggerOnchange
					&& (typeof(f.elements[name + "_month"].onchange) == "function"))
				{
					f.elements[name + "_month"].onchange();
				}
				break;
			}
		}
	}
}

/**
 * pass a date from the calendar into the target input ('return' or 'departure')
 */
function passDate(calendar, target) {
	setDate(document.searchfrm, target, calendar.date, true);
}

/**
 * Return a date object based on the source ('return' or 'departure').
 */
function getDate(source) {
	if (!document.searchfrm) {
		return;
	}
	var f = document.searchfrm;
	var m = f.elements[source + '_month'].value.split(' ');
	var d = f.elements[source + '_day'].value;
	var ret = new Date();
	// the extra param is to ensure values are parsed as base 10, 
	// otherwise 08 and 09 become 0 because it thinks it's octal 
	ret.setDate(parseInt(d, 10));
	ret.setMonth(parseInt(m[0], 10) - 1);
	ret.setFullYear(parseInt(m[1], 10));
	return ret;
}

/*
 * updates the selectedIndex of the return_month and return_day select elements,
 * but only if they have not already been altered by the user
 *
 * @param	f	object	the search form object
 */
function updateReturnDate(f)
{
	// abort if the return date has already been altered
	if (returnDateSetByUser) return;
	
	// departure_month and return_month store their values as a pipe-delimited year|month string
	var month = f.departure_month.options[f.departure_month.selectedIndex].value.substring(5);
	var year = f.departure_month.options[f.departure_month.selectedIndex].value.substring(0,4);
	var day = f.departure_day.options[f.departure_day.selectedIndex].text;

	// creeate a Date object for the departure date
	var departDate = new Date(year, (month - 1), day);

	// create a Date object for the return date and set it to 7 days ahead of the departure date
	var returnDate = departDate;
	returnDate.setDate(departDate.getDate() + 7);

	// loop through the values of the return_month menu
	for (var i = 0; i < f.return_month.options.length; i++)
	{
		var returnValue = f.return_month.options[i].value;

		// if the year and month match up with our return Date object...
		if ((returnValue.substring(5) == returnDate.getMonth() + 1)
			&& (returnValue.substring(0,4) == returnDate.getFullYear()))
		{
			// set the selectedIndex's of the return_month and return_day elements
			f.return_month.selectedIndex = i;
			f.return_day.selectedIndex = returnDate.getDate() - 1;
			break;
		}
	}
}



/*
 * utility function to allow obtaining of DOM element references
 */
function GetElement(elementId)
{
	if (document.getElementById)
	{
		return document.getElementById(elementId);
	}		
	else if (document.all && document.all[elementId])
	{
		return document.all[elementId];
	}
	return null;
}