/*
 * file: flightSelector.js
 * dependancies:
 * 		jQuery.min.1.2.1.js or later
 * author:	David J. Bradshaw
 * 			david.bradshaw@conchango.com
 * date: 2008-01-31
 * copyright: Conchango PLC 2008
 * desc: Creates interactive flight picker from passed in data set
 * contains:
 * 		jQuery	$().flightSelector(flights,passengers,keywords,action) extends jQuery
 * 		jQuery	$()._renderFlight() extends jQuery
 * 		jQuery	$()._flightChange() extends jQuery
 * 		jQuery  $()._flightSelect() extends jQuery
 * 		object	$.flightSelector extends jQuery
 * 		object	Flight(data)
 * 		str 	Flight.renderCollapsed(flightData)
 * 		str 	Flight.renderExpanded(flightData)
 * 		str 	Flight._render(function renderSectors, flightData)
 */


//Create protected namespace around jQuery code
(function($){

	// one way flight selection highlighter code - ADDED BY STAN ON 17/10/2009
	var allTr = $('#flightSelectorOneColumnView tbody tr');
	allTr.click(function() {
		allTr.removeClass('selected');
		var el = $(this);
		el.addClass('selected');
		var input = el.find('input');
		if (el.hasClass('select2')) {
			var p = el.prev();
			p.addClass('selected');
			input = p.find('input');
		} else if (el.hasClass('select1')) {
			el.next().addClass('selected');
		}
		input.attr({checked: true});
	});
	$('#flightSelectorOneColumnView input:checked').trigger('click');


	var showErrors = false;

	/*
	 * jQuery $().flightSelector (obj flights, obj passengers, obj keywords, str action, obj priceBoxFare) extends jQuery
	 * desc:
	 * 		Processes passed in flight data and then calls $(this)._renderFlights
	 */
	$.fn.flightSelector = function(flights,passengers,keywords,action, priceBoxFare) {
		//store data
		$.flightSelector.flights  		= flights; //Store flight option details
		$.flightSelector.passengers  	= passengers; //Store passenger details
		$.flightSelector.keywords 		= keywords; //Store passed in keywords
		$.flightSelector.action 		= action; //Store form action
		$.flightSelector.outwardDate	= ' ' + flights.outward[0].sector[0].deptDay + ' ' + flights.outward[0].sector[0].deptDate + ' ' + flights.outward[0].sector[0].deptYear;
		$.flightSelector.inwardDate		= ' ' + flights.inward[0].sector[0].deptDay + ' ' + flights.inward[0].sector[0].deptDate + ' ' + flights.inward[0].sector[0].deptYear;
		$.flightSelector.fareType 		= 'cash' == $.flightSelector.flights.fareType ? 'cost' : 'miles';
		$.flightSelector.via			= (flights.via ? flights.via + ' ' : false);

		//If more than one passenger, search totals, else search Adult data
		$.flightSelector.fareType 		+= flights.outward[0][flights.fareType+'All'] ? 'All' : 'Adult';

		// information about the fare displayed in the price box
		$.flightSelector.priceBoxFare = priceBoxFare;

  		return this.each(function(){

			//loop through all flights and create name and ID values
			function preRenderFlights(flights,prefix){
				var fLen = flights.length;

				for (var i = 0; i != fLen; i++)
					flights[i].id = (flights[i].name = prefix) + '-' + i; //Set name and ID for node
			}

            //Set display flags
            function markSelected(column,position){
                flights[column][position].selected = true; //Turn on position
                flights[column].selected = position; //store position
            }

            //Check the inward/outward flights in the selected itinerary
            function checkSelectedItinerary(){

                var itineraryId = flights.selectedItineraryId[0];
                if(itineraryId != -1){
                    for(var i=0; i < flights.outward.length; i++){
                       for(var j = 0; j < flights.outward[i].itineraryId.length; j++){
                            if(flights.outward[i].itineraryId[j] == itineraryId){
                                markSelected('outward',i);
                                markSelected('inward',flights.outward[i].inwardFlights[j]);
                                return true;
                            }
                       }
                    }
                }

                return false;
            }

			//Find cheapest flight options and store in flight data object
			function findCheapest(){

				var outward,inward,iLen;
				var oLen = flights.outward.length;


				for (outward = 0; outward != oLen; outward++) { // Loop outward flights
					iLen = flights.outward[outward].lowestFare.length;
					for (inward = 0; inward != iLen; inward++) { //Loop lowest fare for itinery lookup
						if (true == flights.outward[outward].lowestFare[inward]){
							//We found the first lowest fare

							//Store fare as a float
							$.flightSelector.cheapestFare = str2Float(flights.outward[outward][$.flightSelector.fareType][inward]);

							//Set flags to open first cheapest flight on first render
							markSelected('outward',outward);
							markSelected('inward',flights.outward[outward].inwardFlights[inward]);

							//We're done here
							return;
						}
					}
				}
				errorMsg('ERROR:Cheapest fare not found');

				//As we didn't find a cheapest fare, set default open flags to 0
				markSelected('outward',0);
				markSelected('inward',0);

			}

			function findCheapestPairings(){
				var outward,i,cLen,strFare,floatFare,index;
				var oLen = flights.outward.length;
				var fareType = 'cash' == $.flightSelector.flights.fareType ? 'cost' : 'miles';

				fareType += flights.outward[0][fareType+'All'] ? 'All' : 'Adult'; //If more than one passenge, search totals, else search Adult data

				//Store for deatils of cheapest overall flight
				var cheapestReturn = {
					outward:0,
					inward:0,
					fare:flights.outward[0][fareType][0],
					fareNum:str2Float(flights.outward[0][fareType][0])
				};

				//Loop through outgoing flights
				for (outward = 0; outward != oLen; outward++) {
					strFare = flights.outward[outward][fareType][0];  //Store first fare as string
					floatFare = 1 + str2Float(strFare); //Convert first fare to float (add one to triger if statement on first pass of inner loop)
					index = 0; //Index of cheapest flight, set to first to start with
					cLen = flights.outward[outward][fareType].length;

					//Loop through fares looking for cheapest
					for (i = 0; i != cLen; i++) {

						if (str2Float(flights.outward[outward][fareType][i]) < floatFare) { //if cheaper fare for this outbound
							strFare = flights.outward[outward][fareType][i];
							floatFare = str2Float(strFare);
							index = i;

							if (cheapestReturn.fareNum > floatFare) { //if cheapest fare found so far for all outbounds
								cheapestReturn.outward = outward;
								cheapestReturn.inward  = flights.outward[outward].inwardFlights[i];
								cheapestReturn.fare    = strFare;
								cheapestReturn.fareNum = floatFare;
							}
						}
					}

					//Store cheapest return for this outgoing flight
					flights.outward[outward].cheapestFare = flights.outward[outward].inwardFlights[index];
				}
			}

			//Get local jQuery object
			var $this = $(this);

			//Get ID of container from jQuery object
			var id = $this.attr('id');

			//Create extra meta data
			with ($.flightSelector){

                //first check the selected itinerary
                //if no selected itinerary then set the cheapest itinerary
                if(!checkSelectedItinerary()){
                    findCheapest();
                    findCheapestPairings();
                }
				preRenderFlights(flights.outward, id + '-outward');
				preRenderFlights(flights.inward,  id + '-inward' );
				passengers.total = passengers.adults
								 + passengers.children
								 + passengers.infants;
			}

			//Add CSS via jQuery object
			$this.addClass('flightSelector');

			//Fix IE font sizing
			if($.browser.msie)
				$this.addClass('fixIEfontSize');

			//Fix Safari 2 Layout
			if($.browser.safari && 500 > $.browser.version)
				$this.addClass('safari2Fix');

			//All set up, let's take off
			$this._flightRender();
		});
	};

	/*
	 * jQuery $()._flightRender extends jQuery
	 * desc:
	 * 		Renders flight picker inside element selected by jQuery.
	 */
	$.fn._flightRender = function(){

		//render passed in flight column
		function renderFlights(flights,outwardIndex){

			//Check if flight should be greyed out
			function isGrey(){
				var gLen = inwardFlights.length;
				var retCode = true; //Assume blocked

				//Loop through passed in list of allowed flights
				for (var j = 0; j != gLen; j++)
					if (inwardFlights[j] == i){
						retCode = false; //Allowed flight found.
						break;
					}
				return retCode;
			}

			/*
			//Check if flight is the cheapest option
			function isCheapest(){
				var retCode = false;

				if (costs && !grey){ //Check if this fare matches the cheapest fare.
					if (str2Float($.flightSelector.flights.outward[outIndex].costAdult[j]) == $.flightSelector.cheapestFare)
						retCode = true;
					}
				return retCode;
			}
			*/

			var html = '';
			var fLen = flights.length ;
			var grey;
			var outIndex = $.flightSelector.flights.outward.selected;

			//loop through each flight and call either expanded or collapsed render method

			if('undefined' != typeof(outwardIndex)){// Inbound column, so we have to work some extra stuff out.

				var inwardFlights = $.flightSelector.flights.outward[outwardIndex].inwardFlights;
				var lowestFare    = $.flightSelector.flights.outward[outwardIndex].lowestFare;
				var specialOffer  = $.flightSelector.flights.outward[outwardIndex].specialOffer;

				for (var i=0,j=0 ; i != fLen ; i++) {
					grey = isGrey();
					html += (flights[i].selected && !grey) ?
						flights[i].renderExpanded({lowestFare:lowestFare[j],spesh:specialOffer[j]}) :
						flights[i].renderCollapsed({grey:grey,lowestFare:lowestFare[j],spesh:specialOffer[j]});
					if (!grey) j++;
				}

				//Tidy up
				inwardFlights = null;
				lowestFare    = null;
				specialOffer  = null;
			}
			else{ //Outward column
				for (var i=0 ; i != fLen ; i++) {
					html += (flights[i].selected ) ?
						flights[i].renderExpanded({}) :
						flights[i].renderCollapsed({});
				}
			}

			return html; //pass back generated html
		}

		//Render farebox
		function fareBox() {

			function fareTypeWording() {
				with ($.flightSelector) {
					var html = '';
					if (passengers.total > 1) {
						html += '<a href="javascript: document.forms.selectFare.submit()" >'
							+ ((true == priceBoxFare.isForAllPassengers) ? keywords.allPassengers : keywords.perAdult)
							+ '</a>&nbsp;' + keywords.fareTypeITag;
					}
					else {
						html += ' ' + keywords.perAdult;
					}
					return html;
				}
			}

			function displayNote() {
				with ($.flightSelector){
                    return '<div class="intro">'
                    +'<p><strong>'+keywords.disclaimerHeader+'</strong></p>'
                    +'<p>' + keywords.disclaimer + popUp(keywords.optionalSupplementsLinkUrl,keywords.optionalSupplementsLink, true, 400) + ' ' + keywords.optionalSupplements + '</p>'
                    +'</div>';
				}
			}

            function displayPrice() {
				with ($.flightSelector){
                    return     '<div class="details">'
                    +'<p>'
                    +'<span class="total">'+ keywords.totalFare+ ' '
                    + keywords.priceBoxCurrency + ' '
					+ ((true == priceBoxFare.isForAllPassengers) ? fare.total : fare.adult)
                    + '</span> '+ fareTypeWording()
                    +'</p>'
				}
			}

			function displayTotalPrice() {
				with ($.flightSelector) {
					if (priceBoxFare.includesAllTaxes) {
						return '';
					}
					return '<p>' + keywords.total + ' ' + keywords.totalFareCurrency + ' '
							+ ((true == priceBoxFare.isForAllPassengers) ? fare.totalFareAll : fare.totalFareAdult) + ' ' + keywords.includedTaxes + '</p>';
				}
			}
			//Cash fare
			function cash(){
				with ($.flightSelector){
					return displayNote() + displayPrice() + displayTotalPrice()
							+ (fare.percentageDiscount == null  ? '': discountPercent() + '<br/>');
				}
			}

			//Cash fare multi sector, don't show anything in the price box
			function cashMultiSector(){
				with ($.flightSelector){
					return  '';
				}
			}

			//Render fare discount %
			function discountPercent(){
				with ($.flightSelector){
					return  keywords.discountPrefix + ' '
									+ fare.percentageDiscount + '% '
									+ keywords.discountSuffix;
			  }
			}

			//Render for miles redemtion
			function milesRender(singleSector){
				with ($.flightSelector){
					return	displayNote()
                            + '<div class="details">'
                            + '<p>'
                            + '<strong><span class="fare">'
							+ fare.milesTotal
							+ '</span> ' + keywords.miles + '</strong><br />'
							+ (('USA' == priceBoxFare.departureCountry) ? '<strong><span class="fare">' : '')
							+ (true == singleSector && ('' != fare.total) ?  keywords.priceBoxCurrency + ' ' + fare.total 
							+ (('USA' == priceBoxFare.departureCountry) ? '</span>' : '')
							+ ' ' + keywords.tax : '')
							+ (1 != ( passengers.total ) ? ' ' + keywords.forAllPassengers : '')
							+ (('USA' == priceBoxFare.departureCountry) ? '</strong>' : '')
							+ '<br />'
                            + '</p>';
				}
			}

			//redem miles
			function miles(){
				return milesRender(true);
			}

			//redem miles multi-sector
			function milesMultiSector(){
				return milesRender(false);
			}

			//Miles plus Money fare
			function milesMoney(){
				with ($.flightSelector){
					return displayNote()+ displayPrice() + displayTotalPrice()
							+ (('USA' == priceBoxFare.departureCountry) ? '<span class="total">' : '')
							+ ((true == priceBoxFare.isForAllPassengers) ? fare.milesTotal : fare.milesAdult) + ' ' + keywords.miles + ' '
							+ (('USA' == priceBoxFare.departureCountry) ? '</span>' : '')
							+ ((true == priceBoxFare.isForAllPassengers) ? keywords.forAllPassengers : keywords.perAdultMPM) + '<br />';
				}
			}

			//Miles plus Money Multi Sector
			//This method should never be called as this fare type is not valid
			function milesMoneyMultiSector(){
				with ($.flightSelector){
					return '<strong><span class="fare">'
							+ fare.milesAdult + '</span> ' +keywords.milesPerAdult + '</strong><br />'
							+ ((passengers.total > 1) ? keywords.priceBoxCurrency + ' ' + fare.milesTotal  + ' ' + keywords.miles + ' ' + keywords.allPassengers : '<br />') //If more than one adult display total fare.
							+ '<br />';
				}
			}
			// the "leftSide" parameter indicates if the link should have certain styles (if is true means is in the left side of the disclaimer notes)
			function popUp(url,description,leftSide,heightDim){
				if(leftSide){
				return  '<a name="" href="' + url
					+ '" style="margin-left: 0.1em; margin-right: 0pt" onclick="popup(this.href,\'1\',\'450\',\''+heightDim+'\');return false;" title="'
					+ $.flightSelector.keywords.optionalSupplementsLinkTitle + '" target="_blank">'
					+ description + '</a>';
				}else
				return  '<a name="" href="' + url
						+ '" style="margin-left: 0.8em; margin-right: 0pt" onclick="popup(this.href,\'1\',\'450\',\''+heightDim+'\');return false;" title="'
						+ $.flightSelector.keywords.newWin + '" target="_blank">'
						+ description + '</a>';
			}

			with ($.flightSelector){
				return	('cashMultiSector' != fare.type ? '<div class="infoContainer fareContainer">' : '<div class="smallFareBox">')
						+ eval(fare.type+'()') //call function matching fare type
            + ('cash' == fare.type ? new ItineraryDetails().getRewardCopy() : '')
            + (fare.revenueFilled ? // Display conditions and breakdown if revenue fare
               '<p>'
               + popUp(fare.currenciesURL,keywords.currencyCalculator,false,450)
               + popUp(fare.breakdownURL,keywords.fareBreakdown,false,550)
               + popUp(fare.conditionsURL,keywords.fareConditions,false,550)
               + '</p>'
            : '' )
						+ '</div>\n'
			}
		}

		// Render Column header
		function header(direction, date) {
			with ($.flightSelector) {
				var headerHtml = '<div class="colHeading">'
									+ '<div class="colHeadingDirection"><strong>' + direction + '</strong></div>'
									+ '<div class="colHeadingDate"><strong>' + date + '</strong></div>'
									+ '<div class="clear"/>'
								+ '</div>';
				return headerHtml;
			}
		}

		//Render outward column
		function outCol(){
			with ($.flightSelector) {
				return 	'<div id="colOutward" class="flightCol">'
							+ header(keywords.outward, outwardDate)
							+ renderFlights(flights.outward)
						+ '</div>';
			}
		}

		//Render inward column
		function inCol(){
			with ($.flightSelector) {
				return 	'<div id="colInward" class="flightCol">'
							+ header(keywords.inward, inwardDate)
							+ renderFlights(flights.inward, flights.outward.selected)
						+ '</div>';
			}
		}

		function itineraryId(){
			return '<input type="hidden" name="itineraryId" value="' + fare.itineraryId + '" />'
		}

       //Get local jQuery object
		var $this = $(this);

		//Get id of container
		var id = $this.attr('id');

        var realPathFormName = "";
        if (keywords.realPathFormName) {
            realPathFormName = '_' + keywords.realPathFormName;
        }

		//Get fare details
		var fare = new ItineraryDetails().getFareDetails();

		//Create HTML
		var html = '<form name="selectFare' + realPathFormName + '" id="selectFare" action="' + keywords.selectFareAction + '" method="post" onsubmit="return submitTest.check();">'
				 + '<input type="hidden" name="selectedFareType" value="' + ((true == priceBoxFare.isForAllPassengers) ? 'one' : 'all') + '" />'
				 + '<input type="hidden" name="selectFareTypeRedisplayPage" value="' + keywords.selectFareTypeReturnPage + '" /></form>'
				 + '<form id="flightSelectorForm" name="' + (id + realPathFormName) + '" action="' + $.flightSelector.action + '" onsubmit="return submitTest.check()">'
				 + outCol() + inCol()
                 + '<div class="clear"></div>'
                 + (fare ? fareBox() : '') + itineraryId()
				 + '</form>';

		//Write out flights html via jQuery object
		$this.html(html);

		return this; //Pass back to jQuery
	};

	/*
	 * jQuery $()._flightSelect()
	 * desc:
	 * 		Handle click on data cell. If not already selected,
	 * 		then click radio button. This check is needed to
	 * 		work round a bug in IE6/7.
	 */
	$.fn._flightSelect = function() {

		//Find radio button
		var $input = $(this).find('input:radio');

		//if not selected, then select.
		if(true != $input.attr('checked'))
			$input.click();

		return this; //Pass back to jQuery
	}

	/*
	 * jQuery $()._flightChange()
	 * desc:
	 * 		Called by selecting radio button, updates selection data
	 * 		and then calls $()._renderFlights to redraw html. Lastly
	 *      focus is returned to the selected radio button, so as not
	 *      to break keyboard access.
	 */
	$.fn._flightChange = function() {

		//Update selected flags in flight data
		function updateSelected(column,position){
			with ($.flightSelector) {
				flights[column][flights[column].selected].selected = false; //Switch off old position
				flights[column][position].selected = true; //Turn on new position
				flights[column].selected = position; //store position
			}
		}

		//Get ID of callee and extract useful info from it
		var id = $(this).attr('id');
		var foo = id.split('-');
		var rootId = foo[0]; // top level element of control
		var column = foo[1]; // inbound or outbound
		var position = foo[2]; // selected option

		//Update selected item on passed in column
		updateSelected(column,position);

		//if outward, update inward to cheapest fare
		if ('outward' == column)
			updateSelected('inward', $.flightSelector.flights.outward[ $.flightSelector.flights.outward.selected ].cheapestFare);

		//RerenderHTML
		$('#'+ rootId )._flightRender();

		//Return focus to selected radio input
		document.getElementById(id).focus();

		return this; //Pass back to jQuery
	};

	//Set up container for the data we need to store
	$.flightSelector = {};

	//Remove comma from string version of number and then convert to float
	function str2Float(str){
		return parseFloat(new String(str).replace(',',''));
	}

	function errorMsg(string){
		if (true==showErrors) alert(string);
	}

})(jQuery); //Close protected jQuery namespace

/*
 * object: Flight
 * public methods:
 * 		obj constructor(obj data{obj sector,[bool selected],[arr inwardsFlights],[arr costAdult],[arr costChild]})
 * 		str renderCollapsed([bool grey, [bool cheapest]])
 * 		str renderExpanded([bool cheapest])
 * private methods:
 * 		str _render(function renderSectors, [bool grey, [bool cheapest]])
 */

// Flight data object constructor
function Flight(data) {
  this.sector = data.sector;
  this.selected = (data.selected) ? data.selected : false;

  if (data.inwardFlights) this.inwardFlights = data.inwardFlights;
  if (data.costAdult) this.costAdult = data.costAdult;
  if (data.costAll) this.costAll = data.costAll;
  if (data.totalFareAdult) this.totalFareAdult = data.totalFareAdult;
  if (data.totalFareAll) this.totalFareAll = data.totalFareAll;
  if (data.milesAdult) this.milesAdult = data.milesAdult;
  if (data.milesAll) this.milesAll = data.milesAll;
  if (data.earnedMiles) this.earnedMiles = data.earnedMiles;
  if (data.earnedTierPoints) this.earnedTierPoints = data.earnedTierPoints;
  if (data.discountAdult) this.discountAdult = data.discountAdult;
  if (data.itineraryId) this.itineraryId = data.itineraryId
  if (data.breakdownURL) this.breakdownURL = data.breakdownURL;
  if (data.conditionsURL) this.conditionsURL = data.conditionsURL;
  if (data.currenciesURL) this.currenciesURL = data.currenciesURL;
  if (data.specialOffer) this.specialOffer = data.specialOffer;
  if (data.lowestFare) this.lowestFare = data.lowestFare;
  if (data.revenueFilled) this.revenueFilled = data.revenueFilled;
  if (data.hasVsFlight) this.hasVsFlight = data.hasVsFlight;
  if (data.hasCodeshareFlight) this.hasCodeshareFlight = data.hasCodeshareFlight;
};

/*
 * str renderCollapsed([bool grey, [bool cheapest]])
 * desc: Render collapsed flight element
 */
Flight.prototype.renderCollapsed = function(flightData){
	//function to pass to _render method
	function renderSectors(sectors, id, name, selected, greyed){
		var sLen = sectors.length; //Store length so we don't have to keep looking it up.
		var html = '<div class="flightSelection">'
						+ '<input type="radio" onclick="jQuery(this)._flightChange();" id="' + id + '" name="' + name + '"' + (selected ? ' checked="checked"' : '') + (greyed ? 'disabled' : '') +'/>'
				+ '</div>';
		for (var i = 0; i != sLen ; i++)
			with (sectors[i]) {
				//for the multi-sector journey, the departure on the first sector and the arrival on the last sector should be bold
				//for a single sector journey, both arrival and departure should be bold.
				var deptTimeHtml = '';
				var arrTimeHtml = '';
				if (sLen > 1) {
					if (i == 0) {
						deptTimeHtml = '<strong>'+ deptTime + '</strong>';
						arrTimeHtml = arrTime;
					} else if (i == sLen - 1) {
						deptTimeHtml = deptTime;
						arrTimeHtml = '<strong>' + arrTime  + '</strong>';
					} else {
						deptTimeHtml = deptTime;
						arrTimeHtml = arrTime;
					}
				} else {
					deptTimeHtml = '<strong>'+ deptTime + '</strong>';
					arrTimeHtml = '<strong>' + arrTime  + '</strong>';
				}
				html += '<div class="sectorDetails' + (i != 0 ? ' extraSectorDetails' : '') + '">'
						+ '<div class="times">'
							+ '<div class="departTime">' + deptTimeHtml + ' ' + fromCity  + '</div>'
							+ '<div class="emptyArrow">&nbsp;</div>'
							+ '<div class="arrivalTime">' + arrTimeHtml + ' ' + toCity + '</div>'
						+ '</div>' // end times
						+ '<div class="extra">'
							+ (sectors[i].carrier ? '<div class="codeshare">' + sectors[i].carrier + '</div>' : '')
						+ '</div>' // end extra
					+ '</div>'; // end sectorDetails
		}
		return html;
	}
	return this._render(renderSectors, flightData, 'collapsed');
}

/*
 * str renderExpanded([bool cheapest])
 * desc: Render expanded flight element.
 */
Flight.prototype.renderExpanded = function(flightData) {
	//function to pass to _render method
	function renderSectors(sectors, id, name, selected, greyed){
		function renderSector(sector, id, name, selected, greyed, index){
			with($.flightSelector){
				return '<div class="sectorDesc' + (index != 0 ? ' extraSectorDesc' : '' ) + '">'
							+ '<strong>' + sector.fromCity + ' - ' + sector.toCity + '</strong>'
							+ '&nbsp;&nbsp;&nbsp;&nbsp;'
							+ '<label>' + keywords.flightNum + '</label>'
							+ '<a href="' + sector.flightNumHref + '" onclick="popup(this.href,\'1\',\'430\',\'260\');return false;" title="'
								+ keywords.newWin + '" target="_blank">' + sector.flightNum + '</a>'
						+ '</div>' // end flightDesc
						+ '<div style="clear:both"></div>'
						+ '<div class="sectorDetails">'
							+ '<div class="times">'
								+ '<div class="departTime">'
									+ '<strong>' + sector.deptTime + ' ' + sector.deptDay + ' ' + sector.deptDate + ' ' + sector.deptYear + '</strong><br />'
									+ '<span>' + sector.fromCity + ' (' + sector.fromAirport + ')' + '</span>'
								+ '</div>' // end departTime
								+ '<img src="/tridion/images/to-arrow_tcm4-816305.gif" alt="Arrow image" class="directionArrow" />'
								+ '<div class="arrivalTime">'
									+ '<strong>' + sector.arrTime + ' ' + sector.arrDay + ' ' + sector.arrDate + ' ' + sector.arrYear + '</strong><br />'
									+ '<span>' + sector.toCity + ' (' + sector.toAirport + ')' + '</span>'
								+ '</div>' // end arrivalTime
							+ '</div>' // end times
							+ '<div style="clear:both"></div>'
							+ '<div class="extra">'
								+ (sector.limoURL ? '<div class="limoURL">' + '<a href="'  + sector.limoURL + '" onclick="popup(this.href,\'1\',\'430\',\'260\');return false;"' + ' title="' + keywords.newWin + '" target="_blank" >' + keywords.limoLink + '</a></div><div style="clear:both;"/>' : '')
								+ (sector.via ? '<div class="viaMessage"><strong>' + keywords.via + '&nbsp;' + sector.via + '</strong></div>' : '')
                                + (sector.cabin ? '<div class="leftAlign"><strong>' + keywords.cabin + ' </strong><span>' + sector.cabin + '</span></div><div style="clear:both;"/>' : '')
								+ (sector.carrier ? '<div class="operatedBy">' + keywords.operatedBy + '</div>' : '')
								+ (sector.duration ? '<div class="leftAlign"><strong>' + keywords.duration + ' </strong><span>' + sector.duration + '</span></div><div style="clear:both;"/>' : '')
								+ (sector.carrier ? '<div class="carrierNameURL"><a href="'  + sector.codeshareURL + '" onclick="popup(this.href,\'1\',\'430\',\'260\');return false;"' + ' title="' + keywords.newWin + '" target="_blank" >' + sector.carrier + '</a></div><div style="clear:both;"/>' : '')
								+ (sector.displayGovernmentApprovalCopy ? '<div class="leftAlign">' + keywords.governmentApproval + '</div><div style="clear:both;"/>' : '')
							+ '</div>' // end extra
							+ '<div style="clear:both"></div>'
						+ '</div>'; // end flightDetails
			}
		}

		//Render flight details
		var html = '<div class="flightSelection">'
						+ '<input type="radio" onclick="jQuery(this)._flightChange();" id="' + id + '" name="' + name + '"' + (selected ? ' checked="checked"' : '') + (greyed ? 'disabled' : '')+ '/>'
				+ '</div>'; // end flightSelection
		for (var i=0; i != sectors.length ; i++)
			html += renderSector(sectors[i], id, name, selected, greyed, i);

		return html;
	}
	return this._render(renderSectors, flightData, 'expended');
}

/*
 * str _render(function renderSectors, [bool grey, [bool cheapest]], renderType)
 * desc:
 * 		render standard container for flight details, then call passed
 *      in method to render the flight details
 */
Flight.prototype._render = function(renderSectors, flightData, renderType) {
	//Set up flight details box
	with($.flightSelector){
		var currentItinerary = this.selected? new ItineraryDetails().getDescription() : '';
		var html = '<div class="flightOption' + (this.selected ? ' selected' : '') + ('collapsed' == renderType ? ' collapsedOption' : '')
						+ (flightData.grey ? ' grey' + '">'
						// If not greyed out, add js
						: '" onclick="jQuery(this)._flightSelect();' + '">') //if cell clicked, check radio button
						+ '<div class="flightType' + (flightData.grey ? '' : (flightData.lowestFare ? ' lowPrice' : '')) + '">'
							// this.sector --> flight details in the current option;
							// this.name --> the name of the itinerary;
							// this.selected --> flag that specifies whether the current option is going to be selected or not;
							// flightData.grey --> flag that specifies whether the option is still available or not
							+ renderSectors(this.sector, this.id, this.name, this.selected, flightData.grey )
							+ '<div class="clear"></div>'
						+ '</div>'
				+ '</div>';
		return html;
	}
}

//Default constructor
function ItineraryDetails(){ }

/**
 * Gets the index of the itinerary currently selected or false in case the index can't be determined.
 */
ItineraryDetails.prototype.getIndex = function() {
  var index;
  with ($.flightSelector.flights) {
    var iLen = outward[outward.selected].inwardFlights.length;
    for (index = 0;; index++)
      if (inward.selected == outward[outward.selected].inwardFlights[index]) {
        break;
      }
      else if (index > iLen)
        return false; // Index not found
    return index;
  }
}

/*
 * Returns the fare details for the current selected itinerary.
 */
ItineraryDetails.prototype.getFareDetails = function() {
  var index = this.getIndex();

  // Extract data from index position
  try {
    with ($.flightSelector.flights.outward[$.flightSelector.flights.outward.selected]) {
      var adult = costAdult[index];
      var total = ($.flightSelector.flights.outward[$.flightSelector.flights.outward.selected].costAll ? costAll[index]
          : adult);
      var totalAdult = totalFareAdult[index];
      var totalAll = ($.flightSelector.flights.outward[$.flightSelector.flights.outward.selected].totalFareAll ? totalFareAll[index]
          : totalAdult);
      var MilesAdult = milesAdult[index];
      var MilesTotal = ($.flightSelector.flights.outward[$.flightSelector.flights.outward.selected].milesAll ? milesAll[index]
          : MilesAdult);
      var ItineraryId = itineraryId[index];
      var BreakdownURL = breakdownURL[index];
      var ConditionsURL = conditionsURL[index];
      var CurrenciesURL = currenciesURL[index];
      var RevenueFilled = revenueFilled[index];
      var type = $.flightSelector.flights.fareType;
      var sectors = sector.length
          + $.flightSelector.flights.inward[$.flightSelector.flights.inward.selected].sector.length; // count up inward and outward sectors
      var percentageDiscount = discountAdult[index];
    }
  }
  catch (e) {
    errorMsg('DATA ERROR: ' + e);
  }

  if (false == RevenueFilled)
    type += 'MultiSector';

  // Build return object here to stop IE crashing!!!
  return {
    adult : adult,
    total : total,
    totalFareAdult : totalAdult,
    totalFareAll : totalAll,
    type : type,
    milesAdult : MilesAdult,
    milesTotal : MilesTotal,
    itineraryId : ItineraryId,
    currenciesURL : CurrenciesURL,
    breakdownURL : BreakdownURL,
    conditionsURL : ConditionsURL,
    revenueFilled : RevenueFilled,
    percentageDiscount : percentageDiscount
  };
}

/**
 * Gets the reward details (offered only for redemption) of the selected itinerary. Returns null if both miles and tier points are undefined.
 */
ItineraryDetails.prototype.getRewardDetails = function() {
  var index = this.getIndex();
  try {
    with ($.flightSelector.flights.outward[ $.flightSelector.flights.outward.selected ]) {
      var miles = earnedMiles[index];
      var tierPoints = earnedTierPoints[index];
    }
  }
  catch(e) {
    errorMsg('Error getting reward details: ', e);
  }

  if ((miles != null) || (tierPoints != null)) {
    return {
      miles : miles,
      tierPoints : tierPoints
    };
  }
  return null;
}

/**
 * Gets the hasVsFlight indicator of the selected itinerary.
 */
ItineraryDetails.prototype.hasVsFlightIndicator = function() {

	var index = this.getIndex();

	var hasVsFlightIndicator = null;

	try {
		with ($.flightSelector.flights.outward[$.flightSelector.flights.outward.selected]) {
			if (hasVsFlight != null) {
				hasVsFlightIndicator = hasVsFlight[index];
			}
		}
	} catch (e) {
		alert('Error getting codeShareOutward indicator: ' + e);
	}

	return hasVsFlightIndicator;
}

/**
 * Gets the hasCodeshareFlight indicator of the selected itinerary.
 */
ItineraryDetails.prototype.hasCodeshareFlightIndicator = function() {

	var index = this.getIndex();

	var hasCodeshareFlightIndicator = null;

	try {
		with ($.flightSelector.flights.outward[$.flightSelector.flights.outward.selected]) {
			if (hasCodeshareFlight != null) {
				hasCodeshareFlightIndicator = hasCodeshareFlight[index];
			}
		}
	} catch (e) {
		alert('Error getting hasCodeshareFlight indicator: ' + e);
	}

	return hasCodeshareFlightIndicator;
}

/**
 * Gets the reward copy if miles or tier points are being rewarded for this itinerary. Should be called only for fare.type = cash
 */
ItineraryDetails.prototype.getRewardCopy = function() {

	var hasVsFlight = this.hasVsFlightIndicator();
	var hasCodeshareFlight = this.hasCodeshareFlightIndicator();

	var reward = this.getRewardDetails();

	with ($.flightSelector){
		var adultsNo = passengers.adults;
	}
	if (hasVsFlight == 'true') {
		if (reward != null) { // we have miles or tier points
			var rewardCopy = reward.miles + ' ' + keywords.miles + ' + '+ reward.tierPoints + ' ' + keywords.tierPointsEarned;
			if(adultsNo > 1 ){
				rewardCopy = rewardCopy + ' ' + keywords.perAdult;
			}
      if (hasCodeshareFlight == 'true') {
        rewardCopy += ' ' + keywords.onVSFlight + ' <br/> ' + keywords.milesAndPointsCodeShare	+ '<br/>';
        rewardCopy += keywords.pleaseCheck;
      }
			rewardCopy = rewardCopy + '<br/>';
			return rewardCopy;
		} else {
			return '';
		}
	} else if (hasVsFlight == 'false') {
		return keywords.milesAndPoints + ' <br/> ' + keywords.pleaseCheck
				+ '<br/>';
	}
}

 /*
	 * Returns the outward flight for the current selected itinerary.
	 */
 ItineraryDetails.prototype.getOutwardDetails = function() {
  return $.flightSelector.flights.outward[ $.flightSelector.flights.outward.selected ].sector;
  };
 /*
 * Returns the inward flight for the current selected itinerary.
 */
  ItineraryDetails.prototype.getInwardDetails = function() {
    return $.flightSelector.flights.inward[ $.flightSelector.flights.inward.selected ].sector;
  };

 /*
 * Returns the description of the current selected itinerary. This will be interpreted only by the screen readers.
 */
ItineraryDetails.prototype.getDescription = function () {

  function getDayDifferenceMessage(dayDifference) {
    if (dayDifference == "1") {
      return keywords.nextDay;
    }
    if (dayDifference == "2") {
      return keywords.twoDays;
    }
    return '';
  }

  function getFlightDetails (flight) {
    var firstSector = flight[0];
    var secondSector = flight.length > 1 ? flight[1] : null;
    var firstSectorDetails = getSectorDetails(firstSector);
    var secondSectorDetails =  (secondSector != null) ? ' ' + keywords.onwards + ' ' + getSectorDetails(secondSector) : '';
    return firstSectorDetails + secondSectorDetails;
//    return "'" +firstSectorDetails + "'"
//           + (secondSector != null) ? ' and onwards departing ' + getSectorDetails(secondSector) : '';
  }

  function getSectorDetails(sector) {
    return sector.deptTime + ' '
      + sector.fromCity
      + '(' + sector.fromAirport + ')'
      + ' ' + keywords.to + ' '
      + sector.arrTime
      + ' '
      + sector.toCity
      + '(' + sector.toAirport + ')'
      + ' ' + getDayDifferenceMessage(sector.dayDifference);
  }

  //You current flights are departing 11:20 London (Gatwick) to 14:45 New York (Newark Liberty)
  //and returning 07:30 (John F Kennedy) to 19:10 London (Heathrow). Price GBP 1,075.60 per adult, 6,916 miles + 1 tier point(s) earned.
  var outwardFlight = this.getOutwardDetails();
  var inwardFlight = this.getInwardDetails();
  var fare = this.getFareDetails();
  var priceMessage = fare.adult != '' ? keywords.price + ' ' + keywords.priceBoxCurrency + ' ' + fare.adult + ' ' + keywords.perAdult + '. ' : '';
  var html = '<div class="auralOnly">'
      + keywords.currentFlights + ' '
      + getFlightDetails(outwardFlight)
      + ' ' + keywords.returning +' '
      + getFlightDetails(inwardFlight)
      +'. '
      + priceMessage
      + ('cash' == fare.type ? this.getRewardCopy() : '')
      + '</div>';
  return html;
}


/*
 * Display a warning message if departing and returning airports do not match
 */
function checkAirports() {
    with ($.flightSelector.flights) {
        var outwardFromAirport = outward[outward.selected].sector[0].fromAirport;
        var outwardToAirport = outward[outward.selected].sector[0].toAirport;
        var inwardFromAirport = inward[inward.selected].sector[0].fromAirport;
        var inwardToAirport = inward[inward.selected].sector[0].toAirport;

        var outwardSectorLength = outward[outward.selected].sector.length;
        var inwardSectorLength = inward[inward.selected].sector.length;

        var outwardFromCity = outward[outward.selected].sector[0].fromCity;
        var outwardToCity = outward[outward.selected].sector[0].toCity;
        var inwardFromCity = inward[inward.selected].sector[0].fromCity;
        var inwardToCity = inward[inward.selected].sector[0].toCity;


        if (outwardSectorLength == 2) {
            outwardToAirport = outward[outward.selected].sector[1].toAirport;
            outwardToCity = outward[outward.selected].sector[1].toCity;
        }

        if (inwardSectorLength == 2) {
            inwardToAirport = inward[inward.selected].sector[1].toAirport;
            inwardToCity = inward[inward.selected].sector[1].toCity;
        }

        if (((outwardSectorLength == 1) || (outwardSectorLength == 2)) && ((inwardSectorLength == 1)
                || (inwardSectorLength == 2)) &&
            ((outwardFromCity == inwardToCity) && (outwardFromAirport != inwardToAirport)) ||
            ((outwardToCity == inwardFromCity) && (outwardToAirport != inwardFromAirport))) {
            // display the warning popup
            $("#thickboxID").click();
        }
        else if (submitTest.check()) {
            $("#flightSelectorForm").submit();
        }
    }
}

function submitFlightSelector() {
    if (submitTest.check()) {
        // close the pop-up message
        tb_remove();
        // submit the selected flights
        $("#flightSelectorForm").submit();
    }
}

function closeAirportsNotMatchWindow() {
    tb_remove();
}






















