// Hudson JavaScript libraries
// Requires prototype.js to be loaded beforehand.



/* AJAX detection -- Set a cookie indicating that AJAX is supported for this 
 * browser. The server code will check this cookie to determine whether or
 * not to display an AJAX-enhanced version of the site.
 * NOTE: boundary cases:
 *   - The first page on the site that the customer goes to will automatically render as
 *		   "AJAX off" because the server will not yet know if the customer supports AJAX.
 *   - If the customers *turns off* JavaScript after they have visited the site we will
 * 	   not be able to detect that -- they will still register as ""AJAX-enabled".
 */
document.cookie = (Ajax.getTransport()) ? "ajax_enabled=1; path=/" : "ajax_enabled=0; path=/";



/* -- Hudson helpers. */

ajaxError = function(transport) {
	alert("Error loading: " + transport.status + ": " + transport.statusText);
}

function loadAirlines(siteID, direction, airport, suffix, form) {
	var flight_month = getSelectedValue(form['PICKUPMONTH' + suffix]);
	var flight_day		= getSelectedValue(form['PICKUPDAY' + suffix]);
	
	clearSelect(form['AIRLINE' + suffix]);
	addOptionToSelect(form['AIRLINE' + suffix], 'Loading...', '');

	fillAirlines = function(transport) {
		clearSelect(form['AIRLINE' + suffix]);
		fillSelectFromXML(form['AIRLINE' + suffix], transport.responseXML, 'airline', 'No airlines available');
		loadFlightCities(siteID, direction, airport, suffix, form);
	}

	new Ajax.Request('/cgi-bin/ajax/get_airlines', 
			{method:			'post',
			 postBody:		'site_id=' + siteID + '&flight_month=' + flight_month +
			 						'&flight_day=' + flight_day + '&direction=' + direction +
			 						'&airport=' + airport,
			 onSuccess:	fillAirlines,			 
			 onFailure:		ajaxError} );
}

function loadFlightCities(siteID, direction, airport, suffix, form) {
	var flight_month = getSelectedValue(form['PICKUPMONTH' + suffix]);
	var flight_day		= getSelectedValue(form['PICKUPDAY' + suffix]);
	var airline			= getSelectedValue(form['AIRLINE' + suffix]);
	
	clearSelect(form['FLIGHTCITY' + suffix]);
	addOptionToSelect(form['FLIGHTCITY' + suffix], 'Loading...', '');

	fillFlightCities = function(transport) {
		clearSelect(form['FLIGHTCITY' + suffix]);
		fillSelectFromXML(form['FLIGHTCITY' + suffix], transport.responseXML, 'city', 'No cities available');
	}

	new Ajax.Request('/cgi-bin/ajax/get_flight_cities', 
			{method:			'post',
			 postBody:		'site_id=' + siteID + '&flight_month=' + flight_month +
			 						'&flight_day=' + flight_day + '&direction=' + direction +
			 						'&airport=' + airport + '&airline=' + airline,
			 onSuccess:	fillFlightCities,			 
			 onFailure:		ajaxError} );
}



/* -- General JavaScript helpers */

/** document.changed
 * A workaround for a bug I discovered while developing the AJAX-related functions.
 *
 * When an external page (in this instance the calendar control) tries to execute the
 * onchange() function of a control (even indirectly through a wrapper function) to start
 * an AJAX request I was getting "NS_ERROR_NOT_AVAILABLE" JavaScript errors in Firefox.
 *
 * This workaround adds a new global function which accepts an HTML element object. A
 * timer is set to trigger the object's onchange() event after 20 milliseconds -- thereby 
 * redirecting the onchange() request to come from the parent browser. There's a bit more 
 * code in there to cover instances where multiple requests come in within 20 milliseconds.
 *
 * Tested in Safari 2.02, Mozilla Firefox 1.07, Internet Explorer 6
 */
document.changed = function(htmlElement) { 
	var trigger_changes = function() {
		elements = document.getElementsByClassName('bug_workaround');
		for (var i = 0 ; i < elements.length; i++) {
			elements[i].onchange();
			elements[i].className = elements[i].className.replace(/(\s*bug_workaround\s*)/g, '');
		}
	}

	htmlElement.className += ' bug_workaround '; 
	window.setTimeout(trigger_changes, 20); 
}

/** addOptionToSelect
 * Add a new option to the given select list.
 * list - handle for a select list.
 * text - description text for the option.
 * value - value for the option.
 */
function addOptionToSelect(list, text, value) {
	var option = document.createElement('option');
	option.value = value;
	var labelNode = document.createTextNode(text);
	option.appendChild(labelNode);
	list.appendChild(option);
}

/** clearSelectList
 * Clear out the given select list.
 * selectlist - handle for a select list.
 */
function clearSelect(selectList) {
	selectList.options.length = 0
}

/** fillSelectFromXML
 * Retrieve a list of values from the given XML using the given tag name.
 * Fill the given select list with those values.
 * list - handle for a select list.
 * xml - XML document.
 * tagName - name of the XML tags holding the desired values.
 * displayIfBlank - If no values are available, create one option with 
 *			value of '' and name set to this variable.
 */
function fillSelectFromXML(list, xml, tagName, displayIfBlank) {
	var items = xml.getElementsByTagName(tagName);
	for (var i = 0; i  < items.length; i++) {
		var item = items[i].firstChild.nodeValue;
		addOptionToSelect(list, item, item);
	}
	if (items.length == 0) {
		addOptionToSelect(list, displayIfBlank, '');
	}
}

/** getSelectedValue
 * Return the selected value for the given select list.
 * list - handle for a select list.
 */
function getSelectedValue(selectList) {
	return selectList.options[selectList.selectedIndex].value
}


/** disableSubmitButtonOnSubmit
 * Setup a handler to disable all submit buttons 
 * for the given form when the form is submitted.
 */
function disableSubmitButtonsOnSubmit(formName) {
	for (var i = 0; i < document.forms.length; i++) {
		form = document.forms[i];
		if (form.name == formName) {
			if (form.addEventListener) {
				form.addEventListener('submit', eventDisableSubmitButtons, false);			
			} else if (form.attachEvent) {
				form.attachEvent('onsubmit', eventDisableSubmitButtons);
			} else {
				form.onsubmit = eventDisableSubmitButtons;
			}
		}
	}
}

function eventDisableSubmitButtons(evt) {
	evt = (evt) ? evt : ((window.event) ? window.event : "")
	if (evt) {
		var elem
        if (evt.target) {
            if (evt.currentTarget && (evt.currentTarget != evt.target)) {
                elem = evt.currentTarget
            } else {
                elem = evt.target
            } 
        } else {
            elem = evt.srcElement
        }
		return disableSubmitButtonsOnForm(elem);
	}
}

/** Only works reliably for forms with one submit button. */
function disableSubmitButtonsOnForm(form) {
	for (var i = 0; i < form.elements.length; i++) {
		element = form.elements[i];
		
		// Because we want to keep the value being submitted by the
		// submit button, and it won't be submitted if we disable it:
		// make a copy of the submit button.
		if (element.type == 'submit') {
			var hiddenField = document.createElement('input');
			hiddenField.type = 'hidden';
			hiddenField.name = element.name;
			hiddenField.value = element.value;
			form.appendChild(hiddenField);
			
			element.disabled = true;
		}
	}
	return true;
}
