// this gets set to true once the users interacts with the second date inputs
var dontUpdateDate = false;


/**
 * Called when the search page loads to initialize the days drop downs so
 * they contain the correct number of days for the selected month
 */
function date_Init(traveltypeid)
{	
	var form = document.forms.booking_form;
	
	switch (traveltypeid)
	{
		case 'air':
			updateDaysDrop(form, 'departure');
			updateDaysDrop(form, 'return');
			break;
	}
}




/**
 * after validating, creates a Date object from the form element values
 *
 * f - form object reference
 * name - name of the date input set, ie 'return' for 'return_day', 'return_month'
 * format - string date format to return instead of Date object
 */
function makeEpicDate(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 = makeEpicDate(f, from);
	var Date2 = makeEpicDate(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 = epicGetElement(field + '_day');
	
	var date;
	
	while(!(date = makeEpicDate(f, field))) {
		var new_index = parseInt(select.value, 10) - 2;
		
		select.options[new_index].selected = true;
		date = makeEpicDate(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.booking_form, target, calendar.date, true);
}

/**
 * Return a date object based on the source ('return' or 'departure').
 */
function getDate(source) {
	if (!document.booking_form) {
		return;
	}
	var f = document.booking_form;
	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;
}





/**
 * returns false on enter key events to prevent form from being prematurely submitted
 */
function handleEnterKey(e)
{
	// IE doesn't pass event as arg so use the global value
	e = (!e) ? window.event : e;

	// IE uses different event property to store which key was pressed
	var code = (!e.keyCode) ? e.which : e.keyCode;
	
	// return false unless key != 13 (enter key)
	return (code == 13) ? false : true;
}

/**
 * toggles visibility of the return date options
 */
function epicToggleOneway(display)
{
	var returnOptionsDiv = epicGetElement('return-date-options');
	if (returnOptionsDiv) returnOptionsDiv.style.display = display;
}


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


/*
 * generates an HTTP object, currently used for XMLHTTPRequest
 */
function getHTTPObject() {
	
	var xmlhttp;

	if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
		try {
			xmlhttp = new XMLHttpRequest();
		} catch (e) {
			xmlhttp = false;
		}
	}
	
	return xmlhttp;
}
