//Defines functions used by the following pages: Home and Search. 
//The functions that are used by other pages too can be found in common_booking.js

// this is the Main function called on entry to the page
function setUp(obDepartCity, obArriveCity, obCabin, ibDepartCity, ibArriveCity, ibCabin)
{	
	var searchType = getSearchType();
	
	//check whether the Outbound and Inbound departure cities are in the dropdown list or not
	//if one of them are not available, set default departure cities as Gateway City and LON
	if(checkDepartCities(obDepartCity, ibDepartCity, searchType) || !isDepartCity(obDepartCity)){
		obDepartCity = gatewayCityCode;
		defaultArrivalCity = 'LON';
		if(gatewayCityCode=='LON'){//if Gateway Country is UK, set arrival city as NYC 
			defaultArrivalCity = 'NYC';
		}
		obArriveCity = defaultArrivalCity;
		ibDepartCity = defaultArrivalCity;
		ibArriveCity = gatewayCityCode;
	}
	//If gateway city is not in the list, set defult to LON and NYC
	if(checkDepartCities(obDepartCity, ibDepartCity, searchType)){
		obDepartCity = 'LON';
		obArriveCity = 'NYC';
		ibDepartCity = 'NYC';
		ibArriveCity = 'LON';
	}

	if (!nonBookingPage){
		//sets the cabin groups according to the current booking type
		setCabinGroups();
		//sets the currently selected booking type
		currentSearchOption = getSearchType();
	}
	
	// do the outbound stuff
	doOutboundDeparture(obDepartCity);
	doOutboundArrival(document.main.departure.value, obArriveCity);
	
	// do the inbound stuff
	if (detailedBookingPage)
	{
		doInboundDeparture(ibDepartCity);
		doInboundArrival(document.main.departureReturn.value, ibArriveCity);
                checkMPMInboundRoute();
	}
	
	doOutboundCabin(obCabin);
	if (!nonBookingPage){
		doInboundCabin(ibCabin);
	}

  if (searchType == "milesPlusMoney") {
    document.main.isreturn[0].checked = true;
    document.main.isreturn[1].disabled = true;
  }
}

// Populates the outbound departure city drop down
// Loops through all the cities, adding the ones that have the canDepart flag set to true and that are valid 
//according to the currently selected booking type 
function doOutboundDeparture(departCity)
{	

	var selected = 0;
	var optionIndex = 0;

	document.main.departure.options.length = 0;
	for (var i = 0; i < cityNames.length; i++)
	{
		var city = cityNames[i];
		
		if ((city.canDepart) && (isAllowedForBookingType(city))) { 
			document.main.departure.options.length++;
			document.main.departure.options[optionIndex++] = new Option(city.name, city.code);
			
			if (city.code == departCity){
				selected = optionIndex - 1;
			}
		}
	}
	// set the selected one
	document.main.departure.options[selected].selected = true;
}

// Populates the outbound arrival city drop down
function doOutboundArrival(departCity, arrivalCity){
	populateArrivalDropdown(departCity, arrivalCity, document.main.arrival);
}

// populates the outbound cabin drop down
function doOutboundCabin(cabinId)
{
	var cabinList = getCabinList(true);
	// clear down the select box
		
	clearOptions(document.main.classType);
	
	var selected = 0;
	// get the array of cabins
	var cabins = cabinGroups[cabinList];
	// loop through these populating the class drop down
	for (var i = 0; i < cabins.length; i++)
	{
		var cabin = cabins[i];
		
		document.main.classType.options[i] = new Option(cabin.myFriendlyName, cabin.myId);
		if (cabin.myId == cabinId) selected = i;
	}
	// now set the default
	document.main.classType.options[selected].selected = true;
	
	// check that they tally with the inbound
	checkOutboundCabins();
}

// populates the inbound departure city drop down
function doInboundDeparture(departCity)
{
	// clear the box down
		
	clearOptions(document.main.departureReturn);
	// add all cities except the one selected in the outbound departure drop down
	var selected = 0;
	var optionIndex = 0;
		
	// get outbound departure city
	var outboundDepartureCity = document.main.departure.options[document.main.departure.selectedIndex].value;
	
	for (var i = 0; i < cityNames.length; i++){
		var city = cityNames[i];
		
		if ((city.code != outboundDepartureCity) && isAllowedForBookingType(city)){ 
			document.main.departureReturn.options[optionIndex++] = new Option(city.name, city.code);
			
			if (city.code == departCity){ 
				selected = optionIndex - 1;
			}
		}
	}
	// set the selected one
	document.main.departureReturn.options[selected].selected = true;	
}

// populates the inbound arrival city drop down
function doInboundArrival(departCity, arrivalCity){
	populateArrivalDropdown(departCity, arrivalCity, document.main.arrivalReturn);
}

/**
	Populates the given dropdown with the arrival cities for the given departure cities.
 **/
function populateArrivalDropdown(departCity, arrivalCity, arrivalDropdown){
	var searchType = getSearchType();
	
	// clear down the select box
	clearOptions(arrivalDropdown);

	var optionIndex = 0;
	var cabinList = 0;
	var selected = 0;
	for (var i = 0; i < ourRoutes.length; i++)
	{
		var route = ourRoutes[i];
		
		// if this route departs from our departcity then add it
		if ((route.departCity == departCity) && allowsBookingType(route, searchType))
		{
			var cityName = getCityName(route.arriveCity)
			arrivalDropdown.options[optionIndex++] = new Option(cityName, route.arriveCity);
			// check for the default
			if (route.arriveCity == arrivalCity)
			{
				selected = optionIndex - 1;
			}
		}
	}
	// set the selected one
	if (arrivalDropdown.length > 0){
	        arrivalDropdown.options[selected].selected = true;
        }
}

// populates the inbound cabin drop down
function doInboundCabin(cabinId){
	// clear down the select box
	clearOptions(document.main.classTypeReturn);
	
	if (canMixCabins()){	
		// get the outbound cabin
		var outboundCabinId = document.main.classType.options[document.main.classType.selectedIndex].value;
		var outboundCabins = cabinGroups[getCabinList(true)];
		var flexible = false;

		// now checked whether it is lowest, flexible or neither
		for (var i = 0; i < outboundCabins.length; i++)
		{
			var cabin = outboundCabins[i];
			if (cabin.myId == outboundCabinId)
			{
				flexible = cabin.flexible;
			}
		}

		var optionIndex = 0;
		// get the array of cabins
		var inboundCabins = cabinGroups[getCabinList(false)];
		// loop through these populating the class drop down
		for (var i = 0; i < inboundCabins.length; i++)
		{
			var cabin = inboundCabins[i];
			//if flexible is true then add only the flexible cabins, otherwise add only the non flexible cabins 
			//(neither and lowest)
			if (flexible == cabin.flexible){
				var currentOption = new Option(cabin.myFriendlyName, cabin.myId);
				document.main.classTypeReturn.options[optionIndex++] = currentOption;
				if (cabin.myId == cabinId){ 
					currentOption.selected = true;
				}
			}
		}
	}
	else{
		// can't mix cabins, inbound option must be the same as outbound
		
		// if either the outbound or inbound have different (non-combinable) options to each other, reduce 
		// the options in the drop down with the most in till we have parity
		trimClassTypeOptions();
		
		// get the outbound cabin
		var outboundCabinId = document.main.classType.options[document.main.classType.selectedIndex].value;
		// get the inbound cabins		
		var inboundCabins = cabinGroups[getCabinList(false)];
		// loop through these populating the class drop down
		for (var i = 0; i < inboundCabins.length; i++)
		{
			var cabin = inboundCabins[i];
			
			if (cabin.myId == outboundCabinId)
			{
				document.main.classTypeReturn.options[0] = new Option(cabin.myFriendlyName, cabin.myId);
				break;
			}
		}
	}
}
// trims the class type options in the case where you can't mix cabins so that they are the same
function trimClassTypeOptions()
{
	// get the one presently selected - we may need this
	var outboundSelected = document.main.classType.options.selectedIndex;
		
	clearOptions(document.main.classType);
	
	var outboundCabins = cabinGroups[getCabinList(true)];
	
	var inboundCabins = cabinGroups[getCabinList(false)];
	
	var optionIndex = 0;
	
	// loop through these populating the class drop down
	for (var i = 0; i < outboundCabins.length; i++)
	{
		var outboundCabin = outboundCabins[i];
		
		for (var j = 0; j < inboundCabins.length; j++)
		{
			var inboundCabin = inboundCabins[j];
			if (outboundCabin.myId == inboundCabin.myId)
			{
				document.main.classType.options[optionIndex++] = new Option(outboundCabin.myFriendlyName, outboundCabin.myId);
				break;
			}
		}
	}
	// set the selected one
	if (outboundSelected < document.main.classType.options.length) document.main.classType.options[outboundSelected].selected = true;
}
// checks that the outbound cabins tally with the inbound
// if the inbound cabins are 'neither' then filter the
// outbound for all but 'lowest' cabins
function checkOutboundCabins()
{
	var inboundCabinList = getCabinList(false);
	
	if (inboundCabinList != -1)
	{
		var inboundCabins = cabinGroups[inboundCabinList];

		if (inboundCabins[0].neither)
		{
			var outboundCabins = cabinGroups[getCabinList(true)];
			if (!outboundCabins[0].neither)
			{
				
				// clear them down
				clearOptions(document.main.classType);

				var optionIndex = 0;
				// now filter them
				for (var i = 0; i < outboundCabins.length; i++)
				{
					var cabin = outboundCabins[i];
					if (!cabin.flexible)
					{
						document.main.classType.options[optionIndex++] = new Option(cabin.myFriendlyName, cabin.myId);
					}
				}
			}
		}
	}
}

/**
	Determines whether the given city is a valid departure for the currently selected seach type. For exact date 
	and lowest fare The given
	city is valid if there is at least one route that departs from this city and allows the selected search type.
 **/
function isAllowedForBookingType(city){
	var searchType = getSearchType();
	
	if ((searchType == "milesPlusMoney") || (searchType == "redeemMiles")){
		for (var i = 0; i < ourRoutes.length; i++){
			var route = ourRoutes[i];
			if ((route.departCity == city.code) && allowsBookingType(route, searchType)){
				return true;	
			}
		}
		return false;
	}
	else{
		return true;
	}
}

/**
	Determines whether the given route allows the given booking type.
 **/
function allowsBookingType(route, searchType){
	if (searchType == "redeemMiles"){
		return route.allowsRedemption;
	}
	else if (searchType == "milesPlusMoney"){
		return route.allowsMPM;
	}
	else{
		return true;
	}
}

// returns the route object with this departCity and arriveCity
function getRoute(departCity, arriveCity)
{
	var route;
	
	// this will occur on first entry into the main booking page as the inbound cities are not set 
	// when this method is first called
	if (departCity == '' || arriveCity == '')
	{
		route = -1;
	}
	else
	{
		for (var i = 0; i < ourRoutes.length; i++)
		{
			route = ourRoutes[i];
			if (route.departCity == departCity && route.arriveCity == arriveCity) break;
		}
	}
	return route;
}

// gets the cabin list number from the selected departure and arrival options
function getCabinList(outbound){
	var depCityCode;
	var arrCityCode;
	// get the route
	var route;
	
	if (outbound){
		depCityCode = document.main.departure.value;
		arrCityCode = document.main.arrival.value;
		
	}
	else if (detailedBookingPage){
		depCityCode = document.main.departureReturn.value;
		arrCityCode = document.main.arrivalReturn.value;
	}
	else{
		depCityCode = document.main.arrival.value;
		arrCityCode = document.main.departure.value;
	}
	route = getRoute(depCityCode, arrCityCode);
	
	var cabinList;
	
	if (route != -1) 
	{
		cabinList = route.cabinList;
	}
	else
	{
		cabinList = -1;
	}
	
	// need to return the cabin list number
	return cabinList;
}

/**
	Sets the cabin groups according to the booking type. This method is designed to be called only from the 
	booking pages.
 **/
function setCabinGroups(){
	var bookingType;
	var searchType = getSearchType();
	if ((searchType == "redeemMiles") || (searchType == "milesPlusMoney")){
		//for Redemtion and MPM used the Redemption cabin groups
		bookingType = 3;
	}
	else{
		bookingType = 1;
	}
	cabinGroups = allCabinGroups[bookingType];
}

/**
	Determines the search type that is currently selected.
 **/
function getSearchType(){
	var radioButtons = document.getElementsByName("search_type");
	for (var i = 0; i < radioButtons.length; i++){
		var currentButton = radioButtons[i];
		if (currentButton.checked){
			return currentButton.value;
		}
	}
	//if none of the radio buttons is selected, return the value of the first control. This can happen if the
	//radio buttons are not displayed and replaced with a hidden field with the same name.
	return radioButtons[0].value;
}

/**
	Refreshes the cities and cabins dropdowns when the booking type has changed. This method tries to preserve the
	user selections if possible.
 **/
function refreshDropdownsForBookingTypeChanged(){
	var currentObDep = document.main.departure.value;
	var obArr = document.main.arrival.value;
	var preserveInbound = true;
	
	doOutboundDeparture(currentObDep);
	//if the previous selection is not present anymore in the dropdown select the default city for the gateway
	if (currentObDep != document.main.departure.value){
		document.main.departure.value = gatewayCityCode;
		obArr = getDefaultArrival(gatewayCityCode);
		preserveInbound = false;
	}
	//populate the outbound arrival
	doOutboundArrival(document.main.departure.value, obArr);
	//if obArr is not present in the dropdown select the default arrival. This can happen if the departure does not
	//change but the route that was selected is not available for the current search type
	if (obArr != document.main.arrival.value){
		tryToSelect(document.main.arrival, getDefaultArrival(document.main.departure.value));
		preserveInbound = false;
	}
	
	if (preserveInbound){
		if (detailedBookingPage){
			//populate the inbound departure
			var currentIbDep = document.main.departureReturn.value;
			var ibArr = document.main.arrivalReturn.value;
		
			doInboundDeparture(currentIbDep);
			//if the previous selection is not present anymore in the dropdown select the outbound arrival
			if (currentIbDep != document.main.departureReturn.value){
				tryToSelect(document.main.departureReturn, document.main.arrival.value);	
				ibArr = document.main.departure.value;
			}	
			doInboundArrival(document.main.departureReturn.value, ibArr);
			//if ibArr is not present in the dropdown select the departure. This can happen if the departure does not
			//change but the route that was selected is not available for the current search type
			if (ibArr != document.main.arrivalReturn.value){
				tryToSelect(document.main.arrivalReturn, document.main.departure.value);
			}
			
			// for MPM check whether we should display only the return route in the inbound dropdowns
			checkMPMInboundRoute();
		}
		// refresh the outbound cabins			
		doOutboundCabin(document.main.classType.value);	
   		// refresh inbound cabins
		doInboundCabin(document.main.classTypeReturn.value);
	}
	else{
		//if inbound selections should not be preserved, just call obArrivalChanged()
		obArrivalChanged();	
	}
}

/**
  * For MPM search checks whether the return route that corresponds to the selected outbound route is a valid MPM route.
  * If this is the case, this method takes no action. If not, sets as the inbound route the return route for the outbound.
  * This will be the only route that can be selected by the user. 
 **/
function checkMPMInboundRoute(){
	if (getSearchType() == "milesPlusMoney") {
		var departureCityCode = document.main.departure.value;
		var departureCityDesc = document.main.departure.options[document.main.departure.selectedIndex].text;
		var arrivalCityCode = document.main.arrival.value;
		var arrivalCityDesc = document.main.arrival.options[document.main.arrival.selectedIndex].text;
		var departureReturnDropdown = document.main.departureReturn;
		var arrivalReturnDropdown = document.main.arrivalReturn;
		
		if (!(isCityInDropdown(departureCityCode, arrivalReturnDropdown) && 
			isCityInDropdown(arrivalCityCode, departureReturnDropdown))){
			departureReturnDropdown.options.length = 0;
			arrivalReturnDropdown.options.lenght = 0;
			departureReturnDropdown.options[0] = new Option(arrivalCityDesc, arrivalCityCode);
			arrivalReturnDropdown.options[0] = new Option(departureCityDesc, departureCityCode);
		}
	}	
}

/**
  * Determines whether the given city is in the given dropdown.	
  **/
function isCityInDropdown(city, dropdown){
	for (var i = 0; i < dropdown.length; i++){
		if (city == dropdown.options[i].value){
			return true;
		}
	}
	return false;
}

/*
  Tries to select the given value in the given dropdown. If the given value does not exist in the dropdown, the first value will be selected. 
*/
function tryToSelect(dropdown, valueToSelect){
	var exists = false;
	for (i = 0; i < dropdown.options.length; i++){
		if (dropdown.options[i].value == valueToSelect){
			exists = true;
			break;
		}
	}
	if (exists){
		dropdown.value = valueToSelect;
	}
	else{
		dropdown.selectedIndex = 0;
	}	
}

// --------EVENT HANDLERS-------

// Outbound Departure drop down changed
function obDepChanged()
{
	// do outbound arrival cities
	var departCity = document.main.departure.options[document.main.departure.selectedIndex].value;
	doOutboundArrival(departCity, getDefaultArrival(departCity));
	
	// do outbound classes, inbound cities and classes if necessary
	obArrivalChanged();
}

// Outbound arrival drop down changed
function obArrivalChanged(){	
	// if we are on the main booking page then do the inbound stuff
	if (detailedBookingPage)
	{
		// do inbound departure - set this to the same as the outbound arrival
		doInboundDeparture(document.main.arrival.options[document.main.arrival.selectedIndex].value);

		// do inbound arrival and classes - call the event as if the inbound departure has changed
		ibDepChanged();
	}
	else{
		// do outbound classes
		doOutboundCabin(document.main.classType.value);
		if (!nonBookingPage){
			// do inbound cabins
			doInboundCabin(document.main.classTypeReturn.value);	
		}
	}
}

// Outbound cabins drop down has changed
function obCabinChanged()
{
	// set the inbound cabin to this one
	doInboundCabin(document.main.classType.value);
}

// Inbound departure drop down changed
function ibDepChanged()
{
	// do inbound arrival cities
	doInboundArrival(document.main.departureReturn.value, document.main.departure.value);
	
	// for MPM check whether we should display only the return route in the inbound dropdowns
	checkMPMInboundRoute();
	
	// do inbound classes
	ibArrivalChanged();
	
}

// Inbound arrival drop down changed
function ibArrivalChanged(){
	// refresh the outbound cabins			
	doOutboundCabin(document.main.classType.value);	

    // do inbound cabins
	doInboundCabin(document.main.classTypeReturn.value);
}

/**
	Function called when the booking type has changed. This function is designed to be called only from the booking
	pages.
 **/
function bookingTypeChanged(){
	var newlySelectedSearch = getSearchType();
	if (!(((newlySelectedSearch == "exact_date") && (currentSearchOption == "lowest_fare")) ||
		  ((newlySelectedSearch == "lowest_fare") && (currentSearchOption == "exact_date")))){

		setCabinGroups();
	
		refreshDropdownsForBookingTypeChanged();	
	}
	
  	if (newlySelectedSearch == "milesPlusMoney") {
    	document.main.isreturn[0].checked = true;
    	document.main.isreturn[1].disabled = true;
    	doRoundTrip(true);
  	}
  	if (currentSearchOption == "milesPlusMoney") {
    	document.main.isreturn[1].disabled = false;
  	}
  
  	currentSearchOption = newlySelectedSearch;
}

// -------- END EVENT HANDLERS -------

/**
	Enables or disables the controls for the return flight depending on whether round trip or one way was selected.  	
 **/
function doRoundTrip(isRoundTrip)
{
	document.main.returnday.disabled = !isRoundTrip;
	document.main.returnmonth.disabled = !isRoundTrip;
	document.main.returnyear.disabled = !isRoundTrip;
	
    document.main.classTypeReturn.disabled = !isRoundTrip;
    if (detailedBookingPage){
    	document.main.departureReturn.disabled = !isRoundTrip;
		document.main.arrivalReturn.disabled = !isRoundTrip;
	}
}

/**
	Determines whether the route between the given cities is multisector or not.	
 **/
function isMultiSector(depCityCode, arrCityCode){
	var route = getRoute(depCityCode, arrCityCode); 
	
	return route.multiSector;								 
}

/**
	Determines whether mixed cabins are allowed or not.
 **/
function canMixCabins(){
	var outboundRoute = getRoute(document.main.departure.value, document.main.arrival.value);
	var result = !outboundRoute.multiSector;
	
	if (result && detailedBookingPage){
		var inboundRoute = getRoute(document.main.departureReturn.value, document.main.arrivalReturn.value);
		result = !inboundRoute.multiSector;		
	}
	
	return result;
}