
var calendarStartDate = new Date();
var calendarEndDate = new Date();

Event.observe(window, 'load', function() {
	dwr.engine.setErrorHandler(function(msg){
		log.error("DWR Error");
		log.error(msg);
	});

	dwr.engine.setWarningHandler(function(msg){
		log.warn("DWR Warning");
		log.warn(msg);
	});

	dwr.engine._propnames.push("map");
});	

/**
 * Function called to update the airport select boxes and the flight date range. Called when the page is first loaded
 */
function populateAirportsOnLoad(depElementName, destElementName,depDateElementName,destDateElementName){
	log.debug("-> populateAirportsOnLoad");
	var departure = DWRUtil.getValue(depElementName);
	var destination = DWRUtil.getValue(destElementName);
	RouteService.getRoutesForRoute(departure,destination, function(data) {
		log.debug("about to update airports");
		if(depElementName){
			log.debug("populating airports for " + depElementName);
			updateAirportSelect(depElementName, data.departureAirports);
		}
		if(destElementName){
			log.debug("populating airports for " + destElementName);
			updateAirportSelect(destElementName, data.destinationAirports);
		}
		log.debug("about to update dates");
		updateDates(data.defaultStartDate,data.defaultEndDate);
		
		if($(depDateElementName)){
			setDropDownDates(depDateElementName, $F(depDateElementName));
		}
		if($(destDateElementName)){
			setDropDownDates(destDateElementName, $F(destDateElementName));
		}
	});

	log.debug("<- populateAirportsOnLoad");
}

/**
 * Function called to update the airport select boxes and the flight date range. Called when one of the
 * airport selects is changed.
 */
function updateAirports(updatedElement, elementToUpdate) {
   log.debug("-> updateAirports");
   log.debug(updatedElement + " changed");
   
   var airport = DWRUtil.getValue(updatedElement);
   
   log.debug("Airport selected is " + airport);
   log.debug("Getting airports to set for " + elementToUpdate);

   RouteService.getRoutesForDepartureAirport(airport, function(data) {
	   log.debug("about to update airports");
	   updateAirportSelect(elementToUpdate, data.destinationAirports);
   });
   
   log.debug("<- updateTimetableAirports");
}
 
 /**
 * Function called to populate the entire airport list
 */
 function initAirportsFromList(depElementName, destElementName) {
 	log.debug("-> initAirports");
 	try{
 		if(typeof(pageTracker) != 'undefined' && pageTracker != null){
 			pageTracker._trackPageview('/javascript/initAirportsFromList/start.htm');
 			//pageTracker._trackEvent('javascript', 'initAirportsFromList', 'start');
 		}
 	}catch(err){
 		//suppress
 	}
 	RouteService.getAirports({
 		  callback:function(data) {
 	 		   log.debug("about to update airports");
 	 			try{
 	 				if(typeof(pageTracker) != 'undefined' && pageTracker != null){
 	 					pageTracker._trackPageview('/javascript/getRoutes/callback-start.htm');
 	 					//pageTracker._trackEvent('javascript', 'getRoutes', 'callback-start');
 	 				}
 	 			}catch(err){
 	 				//suppress
 	 			}
 	 		   if(depElementName){
 	 			   log.debug("populating airports for " + depElementName);
 	 			   updateAirportSelect(depElementName, data);
 	 		   }
 	 		   if(destElementName){
 	 			   log.debug("populating airports for " + destElementName);
 	 			   updateAirportSelect(destElementName, data);
 	 		   }
 	 			try{
 	 				if(typeof(pageTracker) != 'undefined' && pageTracker != null){
 	 					pageTracker._trackPageview('/javascript/getRoutes/callback-end.htm');
 	 					//pageTracker._trackEvent('javascript', 'getRoutes', 'callback-end');
 	 				}
 	 			}catch(err){
 	 				//suppress
 	 			}			   
 	 		},
 	 		httpMethod:"GET",
 	 		map: {
 	 			callCount:0,
 	 			page:"",
 	 			httpSessionId:"",
 	 			scriptSessionId:"" 
 	 			}
 		}
 	  );
 	
 	log.debug("<- initAirports");
 }
 
 dwr.engine._getScriptSessionId = function() {
	 if (dwr.engine._scriptSessionId == null) {
		 dwr.engine._scriptSessionId = dwr.engine._origScriptSessionId + Math.floor(Math.random() * 1000);
	 }
	 return dwr.engine._scriptSessionId;
 } 

/**
* Function called to populate the entire airport list
*/
function initAirportsAndDates(depElementName, destElementName) {
	log.debug("-> initAirports");
	try{
		if(typeof(pageTracker) != 'undefined' && pageTracker != null){
			pageTracker._trackPageview('/javascript/initAirportsAndDates/start.htm');
			//pageTracker._trackEvent('javascript', 'initAirportsAndDates', 'start');
		}
	}catch(err){
		//suppress
	}
	RouteService.getRoutes({
	    errorHandler:function(message) { alert("There was a problem while loading the list of routes. Please reload the page."); },
	    callback:function(data) {
		   log.debug("about to update airports");
			try{
				if(typeof(pageTracker) != 'undefined' && pageTracker != null){
					pageTracker._trackPageview('/javascript/getRoutes/callback-start.htm');
					//pageTracker._trackEvent('javascript', 'getRoutes', 'callback-start');
				}
			}catch(err){
				//suppress
			}
		   if(depElementName){
			   log.debug("populating airports for " + depElementName);
			   updateAirportSelect(depElementName, data.departureAirports);
		   }
		   if(destElementName){
			   log.debug("populating airports for " + destElementName);
			   updateAirportSelect(destElementName, data.departureAirports);
		   }
		   log.debug("about to update dates");
		   updateDates(data.defaultStartDate,data.defaultEndDate);
			try{
				if(typeof(pageTracker) != 'undefined' && pageTracker != null){
					pageTracker._trackPageview('/javascript/getRoutes/callback-end.htm');
					//pageTracker._trackEvent('javascript', 'getRoutes', 'callback-end');
				}
			}catch(err){
				//suppress
			}			   
		}
	  });
	
	log.debug("<- initAirports");
}

/**
 * Function to update the airport selection boxes with the values from the server.
 */
function updateAirportSelect(elementName, data) {
   log.debug('updating airports')
   // Store the currently selected value 
   var currentValue = DWRUtil.getValue(elementName);
   
   var element = $(elementName);
   
   // retain the dropdown header
   var headerText = element[0].text;

   // Remove options 
   DWRUtil.removeAllOptions(elementName);

   // If nothing came from the server, bail
   if (data == null) {
	  log.error("Server returned nothing");
      return;
   }

   // Update with results from server
   // Do this in a loop because we need to show airport name & code
   log.debug('parsing list of airports');
   
   
   // put the header back in
   var headeropt = new Option(headerText, "");
   element.options[element.options.length] = headeropt;
   
   for (var i = 0; i < data.length; i++) {
      var airportName = DWRUtil._getValueFrom(data[i], 'n');
      var airportCode = DWRUtil._getValueFrom(data[i], 'c');
      airportName = airportName + ' \u202d(' + airportCode + ')\u202c';
      if (airportName || airportCode) {
         var opt = new Option(airportName, airportCode);
         element.options[element.options.length] = opt;
      }
   }
   
   // Attempt to re-set the previously selected value
   DWRUtil.setValue(elementName, currentValue);
   
   log.debug('finished updating airports');
}
 
 /**
  * Function to update the route dates
  */
function updateDates(startDate, endDate){
	calendarStartDate = new Date();
	if (startDate) {
		log.debug("setting default start date:" + startDate);
		calendarStartDate = startDate;   
	}
	calendarEndDate = new Date();
	if (endDate) {
	   log.debug("setting default end date:" + endDate);
	   calendarEndDate = endDate;
	}
 }
 
/**
  * Function to find the flight date range for the currently selected airports.
  * This is used to enable/disable dates on the calendar.
  */
function setFlightDateRange(departureElement, destinationElement, depDateElementName, destDateElementName) {
   log.debug('updating flight dates')
   
   // Get the current departure/destination airport codes
   var departure = DWRUtil.getValue(departureElement);
   var destination = DWRUtil.getValue(destinationElement);
   
   // account for the header being selected
   if (departure == "" || destination == "") {
	   log.debug("ignoring because header value selected");
	   return;
   }
   
   RouteService.getRoute(departure,destination, function(data) {
		   var routes = data.routesAsList;
		   
		   log.debug('looking for route ' + departure + ' to ' + destination);

		   // Find the date range for the currently selected departure/destination
		   var route = null;
		   for (var i = 0; i < routes.length; i++) {
			      if (routes[i].d.c == departure && routes[i].a.c == destination) {
			    	 log.debug('route found: ' + routes[i].d.c + routes[i].a.c);
			         route = routes[i];
			      }
		   }
		   
		   updateDates(route.s,route.e);
		   
		   if($(depDateElementName)){
			   setDropDownDates(depDateElementName, $F(depDateElementName));
		   }
		   if($(destDateElementName)){
			   setDropDownDates(destDateElementName, $F(destDateElementName));
		   }
		   log.debug('start date is: ' + calendarStartDate);
		   log.debug('end date is: ' + calendarEndDate);
		   
	  });
   
   log.debug('finished updating flight dates');
}

/**
 * Calendar callback function, determines which dates are disabled based on the current flightDateRange.
 */
function isDateDisabled(date) {
      if ((calendarStartDate && date < truncateDate(calendarStartDate)) || (calendarEndDate && date > truncateDate(calendarEndDate))) {
         return true;
      }
   return false;
}   
 
function truncateDate(date){
	return new Date(date.getFullYear(),date.getMonth(),date.getDate());
}
 
 /** 
  * Repopulates the number of passengers when one has been selected
  */
 function repopulatePassengerNumbers(element, thisIndex, isAdult, adultIndex, childIndex, infantIndex, isInfant) {
	// the maximum number in each dropdown
 	var maxPAX = 8;
 	
	// there are special rules for infants - there cannot be more infants than adults
 	if (isInfant) {
 		// always set as the same number as the number of adults
 		element.options.length = 1;
	 	for (var i = 1; i <= parseInt(adultIndex); i++) {
	 		element.options[i] = new Option(i);
	 		element.options[i].value = i;
	 	} 		
 	} else  {
 		
 	 	// I have no idea why
 	 	if (isAdult) {
 	 		indexToCheck = childIndex;
 	 	} else {
 	 		indexToCheck = adultIndex;
 	 	}
 		
	 	// Populate drop down
	 	element.options.length = 1;
	 	for (var i = 1; i <= maxPAX - parseInt(indexToCheck); i++) {
	 		element.options[i] = new Option(i);
	 		element.options[i].value = i;
	 	}
 	}
 	// Reset selection if previously selected value too high
 	element.selectedIndex = parseInt(thisIndex) < i ? parseInt(thisIndex) : 0;
 	
 }

  /**
   * Populates the passenger numbers dropdowns
   */
 function populatePassengerNumbers() {
	 
	 updatePassengerNumbers('numberOfAdults');
	 updatePassengerNumbers('numberOfChildren');
	 updatePassengerNumbers('numberOfInfants');
	 
 }
 
 /**
  * Sets the passenger dropdowns when one is selected
  */
function updatePassengerNumbers(elementName) {
			
	var adultElement = $('numberOfAdults');
	var childElement = $('numberOfChildren');
	var infantElement = $('numberOfInfants');

	// Reset index previously chosen
	if(adultElement && childElement && infantElement){
		adultIndex = adultElement.options[adultElement.selectedIndex].value;
		childIndex = childElement.options[childElement.selectedIndex].value;
		infantIndex = infantElement.options[infantElement.selectedIndex].value;
	
		// repopulate the adult dropdown
		repopulatePassengerNumbers(adultElement, adultIndex, true, adultIndex, childIndex, infantIndex, false);
		// repopulate the child dropdown	
		repopulatePassengerNumbers(childElement, childIndex, false, adultIndex, childIndex, infantIndex, false);
		// repopulate the infant dropdown
		repopulatePassengerNumbers(infantElement, infantIndex, false, adultIndex, childIndex, infantIndex, true);
	}
}

/**
 * Sets all the dates in the drop downs.
 * @param inputField, to parse determine drop down names.
 * @param date, the selected date if there is one.
 */
function setDropDownDates(inputField, date) {
	var dayDropDown = $(inputField + 'Day');
	dayDropDown.childElements().each( function(e) {
		if(e.value != 'XX'){
			e.remove();
		}
	});
	for(i=1;i<=31;i++){	
		var actualDay = (i < 10 ? '0' : '') + i; 
		var option = new Element('option', {
			value :actualDay
		});
		option.innerHTML = actualDay;
		dayDropDown.appendChild(option);
		if(typeof(date) != 'undefined' && date != null && date.length > 1 && date.substring(0,2) == actualDay){
			option.selected=true;
		}
	}
	
	
	var monthYearDropDown = $(inputField + 'MonthYear');
	monthYearDropDown.childElements().each( function(e) {
		if(e.value != 'XX'){
			e.remove();
		}
	});
	

	var endYear = calendarEndDate.getFullYear();
	var endMonth = calendarEndDate.getMonth();

	var currentYear = calendarStartDate.getFullYear();
	var currentMonth = calendarStartDate.getMonth();

	for ( var yrInd = currentYear; yrInd <= endYear; yrInd++) {
		var startMth;
		var endMth;
		if (yrInd == currentYear) {
			startMth = currentMonth++;
		} else {
			startMth = 0;
		}
		if (yrInd == endYear) {
			endMth = endMonth;
		} else {
			endMth = 11;
		}
		for ( var mthInd = startMth; mthInd <= endMth ; mthInd++) {
			var actualMonth = mthInd + 1;
			var newVal = (actualMonth < 10 ? '0' : '') + actualMonth  + '/' + yrInd;
			var option = new Element('option', {
				value :newVal
			});
			option.innerHTML = Calendar._MN[mthInd] + ' ' + yrInd;
			monthYearDropDown.appendChild(option);
			if(typeof(date) != 'undefined' && date != null && date.length > 1 && date.substring(3,10) == newVal){
				option.selected=true;
			}
		}
	}
}

/**
 * Sets the dates from the drop down back to the input field.
 */
function setDate(inputField){
	var day = $F(inputField + 'Day');
	var monthYear = $F(inputField + 'MonthYear');
	if(day.length > 0 && day != 'XX' && monthYear.length > 0 && monthYear != 'XX'){
		$(inputField).value= day + '/' + monthYear;
	}else{
		$(inputField).value= 'dd/mm/yyyy';
	}
}