function airline(name, logo, website){
	this.name=name;
	this.logo=logo;
	this.website=website;
}

function airport(code, city){
	this.code=code;
	this.city=city;
}


function flight(order, airline, number, distance, duration, origin, destination, depart,arrive){
	this.order=order;
	this.airline=airline;
	this.number=number;
	this.distance=distance;
	this.duration=duration;//flight duration is in minutes
	this.origin=origin;
	this.destination=destination;
	this.depart=depart;
	this.arrive=arrive;
}

function leg(order, flightArr, distance, duration)
{
	this.order=order;
	this.flightArr=flightArr;
	this.distance=distance;
	this.duration=duration; //leg duration is in text - hours and minutes
}

function criteria(passes){
	//filter criteria class - passes should be a function!
	this.passes=passes;
}

function searchResult(provider, taggable, price, sortscore, bookingurl, legArr, blnYapta, timeDeviation, resId){
	this.provider=provider;
	this.isMilesScrapingEnabled=false;
	this.taggable=taggable;
	this.price=price;
	this.sortscore=sortscore;
	this.bookingurl=bookingurl;
	this.legArr=legArr;
	this.blnYapta = blnYapta; //yapta reccomends this result!
	this.timeDeviation = timeDeviation;
	this.resId = resId;
}

function search(uuid, origin, destination, type, passengers, seatClass, resArr)
{
	this.uuid=uuid;
	this.origin=origin;
	this.destination=destination;
	this.type=type;
	this.passengers=passengers;
	this.seatClass=seatClass;
	this.resArr=resArr;
}

var dayNameArr = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
var monthNameArr = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];

function minsToHours(objMins){
    var strMins=objMins.toString();
    while(strMins.substring(0,1)==0){
        strMins=strMins.substring(1);
    }
    var iMins = parseInt(strMins);
    
    var iMinPortion = iMins%60;
    var iHourPortion =parseInt(iMins / 60);
    var stRes = "";
    var stRes = stRes + iHourPortion + ":" + padZero(iMinPortion);
    return stRes;
}


function dispDuration(objMins){
    var stMins = objMins.toString();
    while(stMins.substring(0,1)==0){
        stMins=stMins.substring(1);
    }
    var iMins = parseInt(stMins);
    
    var iMinPortion = iMins%60;
    var iHourPortion =parseInt(iMins / 60);
    var stRes = "";
    var stRes = stRes + iHourPortion + "h " + iMinPortion + "m";
    return stRes;

}

function padZero(nObj){
    stRes = nObj.toString();
    stRes = "00" + stRes;
    stRes = stRes.substring(stRes.length-2, stRes.length);
    return stRes;
}

function getSearchResults(searchId){
//to switch between xml and json - change this flag...
    var blnUseJson = true;
    var params = {
      ID: searchId
     };
    var blnRes = false;
    $("#searchResultArea").html("<img src=\"/images/loader-orange1.gif\" alt=\"\" /> <b>loading</b>");
    
    var stUrl = '/search/api/xml/getSearchResults/';
    if(blnUseJson) stUrl = '/search/api/json/getSearchResults/';
    $.ajax({
        url: stUrl,
        type: 'POST',
        data: params,
        timeout: 30000,
        error: function(xhr, desc, e){
            $("#searchResultArea").html('Error loading results - ' + desc);
        },
        success: function(xml){
            cachedXml = xml;
            if(blnUseJson){
                blnRes = handleSearchResultsJson(xml);
            }
            else{
                blnRes = handleSearchResults(xml);
            }
            updateSearchResultsAdCount();
        }
    });
       
    return blnRes
}


function updateSearchResultsAdCount(){
    if($('#resComplete').visible){
        updateAds("resComplete");
    }
}

function handleSearchResultsJson(jsonString){
    try{
        searchRes = eval(jsonString);
    }
    catch(err){
        $("#searchResultArea").html('Error parsing results - ' + err);
    
    }

    cachedSearch = searchRes;
    findCheapestResult(searchRes);
    sortBy("price");
}

function handleSearchResults(xml){
    searchRes = new search();
    searchRes.uuid       = $(xml).find("search").attr("id");
    searchRes.passengers = $(xml).find("passengers").text();                  

    var originCode=$(xml).next("origin").text();
    var originCity=$(xml).next("originCity").text();
    var destCode  =$(xml).next("destination").text();
    var destCity  =$(xml).next("destCity").text();

    searchRes.origin     = new airport(originCode,originCity);
    searchRes.destination= new airport(destCode, destCity);
    searchRes.resArr = [];
    var iFlightClass=$(xml).find("seatClass").text();
    searchRes.seatClass  = "coach";
    if(iFlightClass=="1") searchRes.seatClass="first class";
    if(iFlightClass=="2") searchRes.seatClass="business";

    var blnTest = true;
    var iResultNo = 0;
    $(xml).find("result").each(function() { 
        iResultNo++;        
        var thisResult   = new searchResult();
        var resultTrip   = $(this); 
     
        thisResult.isMilesScrapingEnabled = resultTrip.find("isMilesScrapingEnabled").text();
        thisResult.blnYapta   = resultTrip.find("recommended").text();
        thisResult.resId = iResultNo;
        
        thisResult.provider   = resultTrip.find("provider").text() ;
        thisResult.price      = resultTrip.find("cost").text();
        thisResult.bookingurl = resultTrip.find("bookingurl").text();
        thisResult.taggable   = resultTrip.find("taggable").text(),
        thisResult.sortscore  = resultTrip.find("score").text();                
        thisResult.timeDeviation  = resultTrip.find("timeDeviation").text();                
        thisResult.legArr=[];
        
        //for now        
        resultAirline =new airline();
        resultTrip.find("airline").each(function(){
            var thisAirline = $(this);
            resultAirline.name = thisAirline.find("name").text();
            resultAirline.logo = thisAirline.find("logo").text();
        });

        var iLegCount = 0;
        resultTrip.find("leg").each(function(){
            iLegCount++;
            var thisLeg =new leg(iLegCount);
            var thisLegNode = $(this);
            var iFlightCount = 0;
            thisLeg.distance = thisLegNode.find("legDistance").text();
            thisLeg.duration = thisLegNode.find("legDuration").text();
            thisLeg.flightArr= [];
            thisLegNode.find("flight").each(function(){
                thisFlightNode = $(this);
                var thisFlight=new flight(iFlightCount); 
                //todo in the future - fix this tosuit multi-airline result itineraries
                thisFlight.airline    = resultAirline;
                thisFlight.number     = thisFlightNode.find("number").text();
                thisFlight.origin     = new airport(thisFlightNode.find("origin").text(), thisFlightNode.find("originCity").text());
                thisFlight.destination= new airport(thisFlightNode.find("destination").text(), thisFlightNode.find("destinationCity").text());              
                thisFlight.distance   = thisFlightNode.find("distance").text();
                thisFlight.duration   = thisFlightNode.find("duration").text();
                thisFlight.depart     = thisFlightNode.find("depart").text();
                thisFlight.arrive     = thisFlightNode.find("arrive").text();
                thisLeg.flightArr.push(thisFlight);
                
                iFlightCount++;
            });//each flight function
        
            if(iFlightCount > 1){
                for(var i=1;i < thisLeg.flightArr.length;++i){
                    prevArrive = thisLeg.flightArr[i-1].arrive;
                    thisDepart = thisLeg.flightArr[i].depart;
                }
            }
        
            thisResult.legArr.push(thisLeg);
         
        }); //each leg function
        
        
        searchRes.resArr.push(thisResult);
    }); //each result function

    cachedSearch = searchRes;
    findCheapestResult(searchRes);
    sortBy("price");
}
var blnSwitch=true;

var resCheapest;

function findCheapestResult(searchRes){
    if(resCheapest==undefined && searchRes.resArr.length > 0){

        resCheapest = searchRes.resArr[0];

        for (i=1; i<searchRes.resArr.length;++i){
            if(searchRes.resArr[i].price < resCheapest.price){
                resCheapest = searchRes.resArr[i];
            }
        }
    }
    return resCheapest;
}

function hasStops(thisRes){
    var iLegCount    = thisRes.legArr.length;
    var iFlightCount = getFlightCount(thisRes);
    blnRes = false;
    if (iFlightCount > iLegCount) blnRes=true;
    return blnRes;
}

function getClockTime(dtTime){
   var hour   = dtTime.getHours();
   var minute = dtTime.getMinutes();
   var ap = "AM";
   if (hour   > 11) { ap = "PM";             }
   if (hour   > 12) { hour = hour - 12;      }
   if (hour   == 0) { hour = 12;             }
   var timeString = hour +
                    ':' +
                    padZero(minute) +
                    " " +
                    ap;
   return timeString;
    
}

function isValidDate(strDateString){
    var blnRes = true;
    if(strDateString=="None" ||
        strDateString==""   ||
        strDateString=="NaN")
        blnRes=false;
    return blnRes;
}

function getStopDetails(thisResult){
    var resultHtml = "";
    for(var i=0;i<thisResult.legArr.length;++i){
        var thisLeg = thisResult.legArr[i];
        if(thisLeg.flightArr.length>1){
            resultHtml+= '<div id="legDetails-' + thisResult.resId + '-' + i + '" class="popup hidden">';
            for(var j=1;j<thisLeg.flightArr.length;++j){
                if(i==0){
                     resultHtml += "<p class=\"out\"><strong>Departing: </strong>";
                }
                else{
                     resultHtml += "<p class=\"ret\"><strong>Returning: </strong>";
                }
                resultHtml += "layover in ";
                resultHtml += thisLeg.flightArr[j].origin.city;
                if(isValidDate(thisLeg.flightArr[j-1].arrive) && isValidDate(thisLeg.flightArr[j].depart)){
                    resultHtml += " (" + getClockTime(dateParse(thisLeg.flightArr[j-1].arrive));
                    resultHtml += " - " + getClockTime(dateParse(thisLeg.flightArr[j].depart)) + ")";
                }            
            }
			resultHtml += '</div>';
        }
    }
    resultHtml += "</div>";
    return resultHtml;
}

function renderSearchResults(searchRes){
    var pageRecords = 5;
    var initRecords = 5;
    var pageCount = 0;
    
    $("#searchResultArea").html("");

    for(var i=0; i< searchRes.resArr.length;++i){
        var resultHtml = "";
        var thisResult = searchRes.resArr[i];
        
        resultHtml += renderThisResult(thisResult);
        $("#searchResultArea").append(resultHtml);
    }
}

function renderThisResult(thisResult){
    var resultHtml = "";
    resultHtml += '<div class="result resultDetailsOff" id="result' + thisResult.resId + '">\n';
    resultHtml += '<div class="resultWrapper">\n';
	resultHtml += '<div class="yRecommends">';
    if (thisResult.blnYapta.toString() == 'true'){
		var recommendText = ""
		if(thisResult.price!=resCheapest.price){
			recommendText = 'recommended over the cheapest ($' + addCommas(resCheapest.price) + ')'
		}else{
			recommendText = 'recommended and cheapest'
		}

		resultHtml += '<a href="javascript:void(0);" onclick="showHidePopup(this, \'#recommend-' + thisResult.resId + '\', \'#result' + thisResult.resId + '\', \'.result\');">' + recommendText + '</a>\n';
		
    }        
    resultHtml += '</div>';
    resultHtml += '<div class="resultLeft">\n';

    for(var j=0;j<thisResult.legArr.length;++j){
        var thisLeg = thisResult.legArr[j];
        resultHtml += '<div class="leg">';
        resultHtml += '<div class="direction">';
        if(j==0) 
            img = "jet-right-bl.gif";
        else
            img = "jet-left-bl.gif";
        resultHtml += '<img src="/images/' + img + '" alt="" />';
        resultHtml += '</div>';

        resultHtml += '<div class="logo">';
        resultHtml += '<img src="/images/airline-logos-icons/' + thisLeg.flightArr[0].airline.logo + '" alt="" />';
        resultHtml += '</div>';

        resultHtml += '<div class="airline">';
        resultHtml += '<b>' + thisLeg.flightArr[0].airline.name + '</b>&nbsp;' + thisLeg.flightArr[0].number + '<br/>';
        resultHtml += '<small>';

        if(thisLeg.flightArr.length==1)
        {
            resultHtml += "non-stop ";
        }
        else
		{
			resultHtml += '<a href="javascript:void(0);" onclick="showHidePopup(this, \'#legDetails-' + thisResult.resId + '-' + j + '\', \'#result' + thisResult.resId + '\', \'.result\');return false;">';
            resultHtml += thisLeg.flightArr.length-1;
            resultHtml += " stop";
            if(thisLeg.flightArr.length>2) resultHtml +="s";
            resultHtml += "</a> ";
        }

        resultHtml += "(" + dispDuration(thisLeg.duration) + ")";
        resultHtml += '</small>';
        resultHtml += '</div>';

        var stDepDateTime = thisLeg.flightArr[0].depart;
        var depDateTime = dateParse(stDepDateTime); 
        var stArrDateTime= thisLeg.flightArr[thisLeg.flightArr.length-1].arrive; 
        var arrDateTime = dateParse(stArrDateTime);

        resultHtml += '<div class="date">';
        resultHtml += dayNameArr[depDateTime.getDay()] + ", " + monthNameArr[depDateTime.getMonth()] + " " + depDateTime.getDate() + '<br/>';
        resultHtml += '<small>' + getClockTime(depDateTime) + " - " + getClockTime(arrDateTime) + '</small>';
        resultHtml += '</div>';

        resultHtml += '<div class="city">';
        resultHtml += thisLeg.flightArr[0].origin.city + ' <small>(' + thisLeg.flightArr[0].origin.code + ')</small><br/>';
        resultHtml += thisLeg.flightArr[thisLeg.flightArr.length-1].destination.city + " <small>(" + thisLeg.flightArr[thisLeg.flightArr.length-1].destination.code + ")</small>";
        resultHtml += '</div>';
        
        resultHtml += '</div>'; // end leg
        //we're not doing this on the "all results" side yet - #1862 - uncomment the following to match top 5 behaviour
        /*
        if(thisResult.blnYapta.toString() == 'true' && thisResult.price > resCheapest.price ){
            resultHtml += '<div  id="det_2_' + thisResult.resId  + '"><a href="javascript: void(0);" onclick="showDetails(' + thisResult.resId  + ');">Compare with the cheapest flight ($' + addCommas(resCheapest.price) + ')</a></div>';
        
        }
        */
        resultHtml += '<div class="clearboth"></div>';
    }

    resultHtml += '</div>'; //end results left

    resultHtml += '<div class="price">';
    resultHtml += "<div><span>Buy from the airline: <b><a href='" 
	+ thisResult.bookingurl + "' target='_blank'>$"
	+ addCommas(thisResult.price) + "</a></b></span>";
    if( cachedSearch.passengers>1 ){
	resultHtml += '<br><span class="floatRight">price per person</span>';
    }
    resultHtml += '</div><div><img src="/images/hr-or.gif" alt="or" /></div><div><div id="track'+thisResult.resId+'">' 
	+ genTagLink(thisResult, thisResult.resId) + '</div></div>';
    resultHtml += '</div>'; // end price
    
    if (thisResult.blnYapta.toString() == 'true' || hasStops(thisResult)){    //only show these details on the reccomended five or has stopovers!
        //resultHtml += '<div class="detailWrapper hidden" id="resultDetails' + thisResult.resId  + '">'; // start details section
        if(hasStops(thisResult)){
            resultHtml += getStopDetails(thisResult);
        }
        
        if(thisResult.blnYapta.toString()=='true'){
            resultHtml += renderComparison(thisResult);

        }
        resultHtml += '<div class="clearBoth"></div>';
        //resultHtml += '</div>';//detailwrapper
    }
    //resultHtml += '<span class="corner-mblue-tl"></span><span class="corner-mblue-tr"></span><span class="corner-mblue-bl"></span><span class="corner-mblue-br"></span>';
    //resultHtml += '</div>';
	resultHtml += '</div>';
    resultHtml += '<div class="clearboth"></div>';

    return resultHtml;
}


function renderComparison(thisResult){
    var resultHtml = "";

	resultHtml+= '<div id="recommend-' + thisResult.resId + '" class="popup hidden">';
    if(thisResult.price==resCheapest.price)
    {
        resultHtml += ' <h4>This is the cheapest flight.</h4>';
    }
    else{
        resultHtml += ' <h4>Compared with the cheapest flight(s), this one is:</h4>';
        resultHtml += '\n<table>';
        resultHtml += '\n<tr><td><b>price</b>';
        
        if( cachedSearch.passengers>1 ){
            resultHtml += ' per person';
        }
        resultHtml += '</td>';
        resultHtml += '\n<td>$';
        resultHtml += addCommas(thisResult.price - resCheapest.price);
        resultHtml += ' more</td>'
                
        resultHtml += '</tr><tr><td><b>total duration</b></td>';
        resultHtml += '\n<td>';
        if(getDuration(thisResult) == getDuration(resCheapest)){
            resultHtml+="equal";
        }
        else if(getDuration(thisResult) < getDuration(resCheapest)){
            resultHtml += getDuration(resCheapest)-getDuration(thisResult);
            resultHtml += "m shorter";
        }
        else{
            resultHtml += dispDuration(getDuration(thisResult)-getDuration(resCheapest));
            resultHtml += " longer";
        }
        resultHtml += "</td></tr><tr><td><b>number of stops</b></td>";
        resultHtml += "\n<td>";
        if(getFlightCount(thisResult) == getFlightCount(resCheapest)){
            resultHtml += "equal";
        }
        else if(getFlightCount(thisResult) <= getFlightCount(resCheapest)){
            resultHtml += getFlightCount(resCheapest)-getFlightCount(thisResult);
            resultHtml += "fewer";
        }
        else{
            resultHtml += getFlightCount(thisResult)-getFlightCount(resCheapest);
            resultHtml += "more";
        }
        resultHtml += "</td></tr><tr><td><b>departure times</b></td>";
        resultHtml += "\n<td>";
        if(thisResult.timeDeviation > resCheapest.timeDeviation){
            resultHtml += "closer";
        }
        else if(thisResult.timeDeviation == resCheapest.timeDeviation){
            resultHtml += "equal";
        }
        else{
            resultHtml += "further";
        }
        resultHtml += "</td>";
        resultHtml += '</tr>';
        resultHtml += '\n</table>';
    }
    resultHtml += '</div>';
    return resultHtml;
}

function doFilter(criteriaArray){
    var resultsToDisplay= new search(cachedSearch.uuid, cachedSearch.origin, cachedSearch.destination, cachedSearch.type, cachedSearch.passengers, cachedSearch.seatClass);
    resultsToDisplay.resArr=[];
    for(var i=0; i< cachedSearch.resArr.length;++i){
        var thisSearchResult = cachedSearch.resArr[i];
        var blnInclude=true;
        for(var j=0; j< criteriaArray.length; ++j){
            var thisCriteria = criteriaArray[j];
            if(!thisCriteria.passes(thisSearchResult)) blnInclude=false;
        }
        if(blnInclude) resultsToDisplay.resArr.push(thisSearchResult);
    }
    testRes = new searchResult();
    testRes.price=200;
    renderSearchResults(resultsToDisplay);
}   
var currentFilters = [];
var cachedSearch;
    

function formatDateObject(dtDateObject){
    var stRes = "";
    try{
       stRes = "new Date(" 
        + dtDateObject.getFullYear() + ", " 
        + dtDateObject.getMonth()    + ", " 
        + dtDateObject.getDate()     + ", " 
        + dtDateObject.getHours()    + ", " 
        + dtDateObject.getMinutes()  + ",0)";
    }
    catch(err){
        stRes= "'None'";
    }
    return stRes;
}
    
function genTagLink(flightResult, intId){
    var resultHtml = "";
    if(flightResult.taggable == "available"){
        resultHtml += "<button id=\"tagItButton_all_" + intId + "\" class=\"orangeDarkSmall\" onClick=\"postTrip(new searchResult(";
//        resultHtml += "<a href=\"javascript:postTrip(new searchResult(";
        resultHtml += flightResult.isMilesScrapingEnabled + ",'" 
	    + flightResult.provider + "\', '', " 
	    + flightResult.price + ", '', '', [  ";
        for(var i=0; i< flightResult.legArr.length; ++i){
            var thisLeg = flightResult.legArr[i];
            resultHtml += "new leg(" + i + ", [  ";

            for(var j=0; j< thisLeg.flightArr.length; ++j){
                var thisFlight  =thisLeg.flightArr[j];
                resultHtml += "new flight(" + j + ",'" + thisFlight.airline.name + "', "; 
                resultHtml += "'" + thisFlight.number + "', " ;
                resultHtml += "'" + thisFlight.distance + "', ";
                resultHtml += "'" + thisFlight.duration + "', ";
                resultHtml += "new airport('" + thisFlight.origin.code + "', '" + thisFlight.origin.city + "'), ";
                resultHtml += "new airport('" + thisFlight.destination.code + "', '" + thisFlight.destination.city + "'), ";
                if(thisFlight.depart=="None"){
                    resultHtml += "'', ";
                }
                else{
                    resultHtml += formatDateObject(thisFlight.depart) + ", ";//"'" + thisFlight.depart + "', ";
                }
                if(thisFlight.arrive=="None"){
                    resultHtml += "'') , ";
                }
                else
                {
                    resultHtml += formatDateObject(thisFlight.arrive) + "), ";
                }
            }
            resultHtml = resultHtml.substring(0, resultHtml.length -2);
            resultHtml += "]";
            resultHtml += ") , ";
        }            
        resultHtml = resultHtml.substring(0, resultHtml.length -2);
        resultHtml += "]";
        resultHtml += ", '" + flightResult.blnyapta + "'";
        resultHtml += "), " ;

        resultHtml += "'" + flightResult.price + "', ";
        resultHtml += "'" + cachedSearch.origin.code + "', ";
        resultHtml += "'" + cachedSearch.destination.code + "'";
        resultHtml += ", " + intId;
        resultHtml += ", " + cachedSearch.passengers;
        resultHtml += ", '" + cachedSearch.seatClass + "'," ;
	resultHtml += (flightResult.isMilesScrapingEnabled)
	    ? ("$('#includeAwardTix"+intId+":checked').val()!=null") : ("false");
        resultHtml += ");\"  ><span id=\"yaptagit_" + intId + "\">track price drops</span>";
//        resultHtml += "</a>";
        resultHtml += '</button>';
	if (flightResult.isMilesScrapingEnabled) {
	    resultHtml += '<br /><input type="checkbox" id="includeAwardTix'+intId+'" /> <label for="includeAwardTix'+intId+'">Include award tickets</label>';
	}
    }
    else if(flightResult.taggable=="tagged"){
        resultHtml += '<img src="/images/check-dark.gif" alt="" /> Tracking in '
	    + "<a href=\"/mytrips/\" >My Trips</a>";
    }
    else 
    {
        resultHtml += "";
    }
    return resultHtml;
}


function parseIntNotOct(stString){
    if (stString.substring(0,1)=="0") stString = stString.substring(1,2);
    iRes = parseInt(stString);
    return iRes;    
}

//function to parse from string in yyyy-mm-dd hh:mm:ss format into datetime object
function dateParse(stOriginalDate){
    var dtResultDate = new Date();
    if(typeof(stOriginalDate)=="string"){
        
        var stYear = stOriginalDate.toString().substring(0,4);
        var stMonth = stOriginalDate.toString().substring(5,7);
        var stDate = stOriginalDate.toString().substring(8,10);
        var stHour = stOriginalDate.toString().substring(11,13);
        var stMinute = stOriginalDate.toString().substring(14,16);

        dtResultDate.setFullYear(parseInt(stYear), (parseIntNotOct(stMonth)-1),parseIntNotOct(stDate));
        dtResultDate.setHours(parseIntNotOct(stHour));
        dtResultDate.setMinutes(parseIntNotOct(stMinute)); 
    }
    else{
        dtResultDate = stOriginalDate;
    }

    
    return dtResultDate;
}

function genPostThisTripXml(thisResult, thePrice, origin, destination,iDentFiller, travellers, seatClass,bIncludeAwardTix, bTopFive){
    var resultXml = "";
    resultXml = resultXml + "<addTrip><trip>";
    if (bIncludeAwardTix) {
	resultXml += "<trackMiles>True</trackMiles>";
    }
    resultXml = resultXml + "<air>";
    resultXml = resultXml + "<price amount=\"" + trim(thePrice) + "\"></price>";
    
    for(var i=0; i< travellers; ++i){
        resultXml = resultXml + "<passenger type=\"adult\"/>";
    }

    for(var i=0; i< thisResult.legArr.length; ++i){
        var thisLeg = thisResult.legArr[i];
        resultXml += "\n<leg>";
        for(var j=0; j< thisLeg.flightArr.length; ++j){
            var thisFlight  =thisLeg.flightArr[j];
            // 5/5/08 - eric - dealing w/ empty depart or arrive datetimes
            var depDate = "";
            var depTime = "";
            var arrDate = "";
            var arrTime = "";
            resultXml = resultXml + "\n<flight>";
            resultXml = resultXml + "<airline>" + thisFlight.airline + "</airline>\n";
            resultXml = resultXml + "<flightNumber>" + thisFlight.number + "</flightNumber>\n";
            resultXml = resultXml + "<class>" + seatClass + "</class>\n";            
            resultXml = resultXml + "<duration>" + thisFlight.duration + "</duration>\n";
            resultXml = resultXml + "<departure airport=\"" + thisFlight.origin.code + "\"";
            //handle empty departure and arrival times
            if (isValidDate(thisFlight.depart.toString())) {
                var depDateTime = dateParse(thisFlight.depart);
                depDate = depDateTime.getFullYear() + "-" + (depDateTime.getMonth()+1) + "-" + depDateTime.getDate();
                depTime = depDateTime.getHours() + ":" + padZero(depDateTime.getMinutes());
                resultXml = resultXml +  " time=\"" + depTime + "\" date=\"" + depDate + "\"";
            }
            resultXml = resultXml + "/>\n<arrival airport=\"" + thisFlight.destination.code + "\"";
            if (isValidDate(thisFlight.arrive.toString())) {
                var arrDateTime = dateParse(thisFlight.arrive);
                arrDate = arrDateTime.getFullYear() + "-" + (arrDateTime.getMonth()+1) + "-" + arrDateTime.getDate();
                arrTime = arrDateTime.getHours() + ":" + padZero(arrDateTime.getMinutes());
                resultXml = resultXml + " time=\"" + arrTime + "\" date=\"" + arrDate + "\"";
            }
            resultXml = resultXml + "/>\n</flight>";
        }    
        resultXml += "\n</leg>";    
    }
    resultXml = resultXml + "</air></trip></addTrip>";
    return resultXml;
}

function genTripWrapperXml(thisSource, xmlContent){
    var resultXml = "";
    resultXml = resultXml + "<?xml version=\"1.0\"?>\n";
    resultXml = resultXml + "<request>\n<clientInfo><version>1.0.0.0</version><meta>yapta.com</meta>";
    resultXml = resultXml + "<source>" + thisSource + "</source>";
    resultXml = resultXml + "</clientInfo>\n";
    resultXml = resultXml + xmlContent;
    resultXml = resultXml + "</request>\n";
    return resultXml;
}


function genPostTripXml(thisResult, thisSource, thePrice, travellers, seatClass,bIncludeAwardTix,bTopFive){
    return genTripWrapperXml(thisSource, genPostThisTripXml(thisResult, thePrice, '','',1,travellers, seatClass, bIncludeAwardTix, bTopFive));
}

function updateCachedSearchAsTagged(ident){
    var newCachedSearch = new search(cachedSearch.uuid, cachedSearch.origin, cachedSearch.destination, cachedSearch.type,  cachedSearch.passengers, cachedSearch.seatClass, []);
    for (var i=0; i< cachedSearch.resArr.length; ++i){
        var thisRes = cachedSearch.resArr[i];
        if(thisRes.resId==ident) thisRes.taggable="tagged";
        newCachedSearch.resArr.push(thisRes);
    }
    cachedSearch = newCachedSearch;
}

function postTrip(thisResult, thePrice, origin, destination, ident, travellers, seatClass, bIncludeAwardTix, bTopFive, bNoMyTripsLink)
{
    
    if(travellers==undefined) tavellers=1;
    if(seatClass==undefined)  seatClass="Coach";
    if(bTopFive==undefined)   bTopFive=false;
    if(bTopFive.toString()=="undefined") bTopFive=false;
    
    var stSource = "";

    var strCurrUrl = this.window.location.toString();
    if(strCurrUrl.indexOf("search")>0)
    {
        if(bTopFive==true){
            stSource = "searchRecommended";
        }
        else{
            stSource = "searchAll";
        }
    }
    else if(strCurrUrl.indexOf("airport")>0)
    {  
        stSource = "browse";
    }
    
    
    var postData = genPostTripXml(thisResult, stSource, thePrice, travellers, seatClass,bIncludeAwardTix,bTopFive);
  
    var params = {
    };
    var blnRes = false;

    var allTrackLink= "#track"+ident;
    var recTrackLink= "#rec_track" + ident;

    /* replace this with a "tagging" link or spinner */
    loadingHtm(allTrackLink, 'saving', 0);
    loadingHtm(recTrackLink,'saving',0);
    $.ajax({
        url: '/client/?',
        type: 'POST',
        data: postData,
        timeout: 10000,
        error: function(){
			var htm = 'Tracking in <a href="/mytrips/">My Trips</a>';
            loadingHtm(allTrackLink, htm, 1);
            loadingHtm(recTrackLink, htm, 1);
        },
        success: function(xml){
            try{
                stResult = $(xml).find("status").text();
                if(stResult=="ACCESS_DENIED"){
                    loadingHtm(allTrackLink, 'tracked', 1);
                    loadingHtm(recTrackLink,'tracked',1);
                    redirectLogin();
                }
                else if(stResult=="OK"){
                    updateCachedSearchAsTagged(ident);
		            var stItinId = $(xml).find("itinerary").find("id").text();
		            var stItinGroupId = $(xml).find("itineraryGroup").find("groupid").text();
		            if (!bNoMyTripsLink) {
			        //htm+='<span class="buy">Added to <a href="/mytrips/trip/?id=' + stItinGroupId + '">My Trips &raquo;</a></span>';
			            var htm = 'Tracking in <a href="/mytrips/trip/?id=' 
                                        + stItinGroupId + '">My Trips</a>';
		            }
                    loadingHtm(allTrackLink, htm, 1);
                    loadingHtm(recTrackLink, htm, 1);
                    if(hasUserLoggedInError(xml)) 
                    {
                        redirectLogin();
                    }

                }
                else{
                    // Error.  Just send user to My Trips page
                    // to view the trip.  Job system will pick up later.
			        var htm = 'Tracking in <a href="/mytrips/">My Trips</a>';
                    loadingHtm(allTrackLink, htm, 1);
                    loadingHtm(recTrackLink, htm, 1);
                }
            }
            catch(err){
                // Error.  Just send user to My Trips page
                // to view the trip.  Job system will pick up later.
			    var htm = 'Tracking in <a href="/mytrips/">My Trips</a>';
                loadingHtm(allTrackLink, htm, 1);
                loadingHtm(recTrackLink, htm, 1);
            }
        }
    });
    
    return blnRes;

}

function trim(stringToTrim) {
    return stringToTrim.replace(/^\s+|\s+$/g,"");
}

function hasUserLoggedInError(xml){
    var strPostUser = $(xml).find("user").text();
    
    var blnRes = false;
    if(strPostUser==""){
        blnRes = true;
    }
    else{
        
    }
    return blnRes;
}



//this uses absolute url with host as we may be sending redirect to an airline booking site or a search engine booking site
function redirectBook(strURL){
    this.window.location=strURL;
}


function redirectLogin(){
    var retLocation = "/login/?returnTo=" + this.window.location.pathname  + this.window.location.search;
    
    this.window.location = retLocation;
}


function addCommas(nStr)
{
//trap integer values...
    nStr=nStr.toString();
    nStr += '';
    x = nStr.split('.');
    x1 = x[0];
    x2 = x.length > 1 ? '.' + x[1] : '.00';
    
    x2= x2.length < 3 ? x2+'0' : x2;

    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}

function comparePreviousComparison(a,b){
    var res=0;
    if(lastSortAsc){
        switch(lastSort)
        {
            case "airline":
                res= compareAirline(a,b,true);
                break;
            case "price":
                res=comparePrice(a,b,true);
                break;
            case "duration":
                res=compareDuration(a,b,true);
                break;
            case "time":
                res=compareTime(a,b,true);
                break;
            case "sortScore":
                res=compareScore(a,b,true);
                break;
        }
    }
    else{
        switch(lastSort)
        {
            case "airline":
                res=compareAirlineDesc(a,b,true);
                break;
            case "price":
                res=comparePriceDesc(a,b,true);
                break;
            case "duration":
                res=compareDurationDesc(a,b,true);
                break;
            case "time":
                res=compareTimeDesc(a,b,true);
                break;
            case "sortScore":
                res=compareScoreDesc(a,b,true);
                break;
        }
    }
    return res;
}

function comparePrice(a,b, z){
    var res=a.price-b.price;
    if(z==undefined && res==0) res=comparePreviousComparison(a,b);
    return res;
}

function comparePriceDesc(a,b,z){
    var res= comparePrice(b,a,z);
    if(z==undefined && res==0) res=comparePreviousComparison(a,b);
    return res;
}



function compareAirline(a,b,z){
    var x=a.legArr[0].flightArr[0].airline.name.toLowerCase();
    var y=b.legArr[0].flightArr[0].airline.name.toLowerCase();
    var res = ((x < y) ? -1 : ((x > y) ? 1 : 0));
    if(z==undefined && res==0) res=comparePreviousComparison(a,b);
    return res;
}

function getFlightCount(sRes){
    var flightCount = 0;
    for(var i=0; i<sRes.legArr.length;++i){
        flightCount += sRes.legArr[i].flightArr.length;
    }
    var res=flightCount;
    return res;
}


function compareAirlineDesc(a,b,z){
    var res = compareAirline(b,a,z);
    if(z==undefined && res==0) res=comparePreviousComparison(a,b);
    return res;
}

function getDuration(sRes){
    var theDur = 0;
    for (var i=0; i<sRes.legArr.length;++i){
        theDur+=parseInt(sRes.legArr[i].duration);
    }
    
    return theDur;
}

function compareDuration(a,b,z){
    var aDur= 0;
    var bDur=0;
    aDur = getDuration(a);
    bDur = getDuration(b);
    var res = aDur-bDur;
    if(z==undefined && res==0) res=comparePreviousComparison(a,b);
    return res;
}
function compareDurationDesc(a,b,z){
    var res = compareDuration(b,a,z);
    if(z==undefined && res==0) res=comparePreviousComparison(a,b);
    return res;
}



function compareScore(a,b,z){
    var aScore= 0;
    var bScore =0;
    aScore +=parseInt(a.sortscore);
    bScore+=parseInt(b.sortscore);
    var res = aScore-bScore;
    if(z==undefined && res==0) res=comparePreviousComparison(a,b);
    return res;
}
function compareScoreDesc(a,b,z){
    var res = compareScore(b,a,z);
    if(z==undefined && res==0) res=comparePreviousComparison(a,b);
    return res;
}

function compareTime(a,b,z){
    var aDeviation= 0;
    var bDeviation =0;
    aDeviation +=parseInt(a.timeDeviation);
    bDeviation+=parseInt(b.timeDeviation);
    var res = aDeviation-bDeviation;
    if(z==undefined && res==0) res=comparePreviousComparison(a,b);
    return res;
}

function compareTimeDesc(a,b,z){
    var res = compareTime(b,a,z);
    if(z==undefined && res==0) res=comparePreviousComparison(a,b);
    return res;
}

var currSort = "";
var lastSort = "";
var lastSortAsc = true;
var sortAsc=true;

function sortResultsBy(theArrToSort, stSortField,blnAsc){
    if(blnAsc){
        switch(stSortField)
        {
            case "airline":
                theArrToSort.sort(compareAirline);
                break;
            case "price":
                theArrToSort.sort(comparePrice);
                break;
            case "duration":
                theArrToSort.sort(compareDuration);
                break;
            case "time":
                theArrToSort.sort(compareTime);
                break;
            case "sortScore":
                theArrToSort.sort(compareScore);
                break;
        }
    }
    else{
        switch(stSortField)
        {
            case "airline":
                theArrToSort.sort(compareAirlineDesc);
                break;
            case "price":
                theArrToSort.sort(comparePriceDesc);
                break;
            case "duration":
                theArrToSort.sort(compareDurationDesc);
                break;
            case "time":
                theArrToSort.sort(compareTimeDesc);
                break;
            case "sortScore":
                theArrToSort.sort(compareScoreDesc);
                break;
        }
    }
    return theArrToSort;
} 

jQuery.preloadImages = function()
{
  for(var i = 0; i<arguments.length; i++)
  {
    jQuery("<img>").attr("src", arguments[i]);
  }
}
$.preloadImages("/images/sorting.png");

function sortBy(stField){
    //start spinner here...
    if(currTab == "resComplete"){
         var blockMessage = '<p><img src="/images/sorting.png" border=0></p>';
          $.blockUI(blockMessage);
    }
    //delay 50ms so that the ui has a chance to update before we start the browser-intensive bit
    setTimeout(function(){
        var theArrToSort = cachedSearch.resArr;
        //the array.sort() function does not retain the previous sort order when applying a new sort. The documentation might claim that it does, but it lies.
        //this will have to be addressed somehow.
        
        var theOldSortField= $("#sortBy" + currSort);
        theOldSortField.removeClass();
        
        //remove current arrow from a href id = "sortBy" + stField
        if(currSort==stField){
            sortAsc=!sortAsc;
        }
        else{
            lastSortAsc = sortAsc;
            sortAsc=true;
        }
        theArrToSort = sortResultsBy(theArrToSort, stField,sortAsc);
        //add relevant arrow to a href id = "sortBy" + stField
        var theNewSortField=$("#sortBy" + stField);
        if(sortAsc==true){
             theNewSortField.addClass("sortAsc");
        }
        else{
             theNewSortField.addClass("sortDesc");
        }    
    
        if(lastSort!=stField)
        {
            lastSort = stField;
        }
        currSort=stField;
    
    
        cachedSearch.resArr = theArrToSort;
        renderSearchResults(cachedSearch);
        //remove spinner here
        $.unblockUI();
    },50);
}

/* slide down for search details
    - Aaron
*/
function showDetails(id){
    var wrapDiv = '#result' + id;
    var detailDiv = '#resultDetails' + id;
    var detailHref = '#det' + id;
    var detailHref2 = '#det_2_' + id;
    var corners = wrapDiv + ' .corner-mblue-tl, ' + wrapDiv + ' .corner-mblue-tr, ' + wrapDiv + ' .corner-mblue-bl, ' + wrapDiv + ' .corner-mblue-br';
    var detailImg = '#img' + id;
    var imgDown = "/images/arrow-down-bl.gif";
    var imgUp = "/images/arrow-up-bl.gif";

    $(detailHref).blur();

    if($(detailHref).html() == 'hide'){
        $(corners).css('display', 'none');
        $(detailDiv).addClass('hidden');
        $(detailHref).html('details');
        $(detailImg).attr("src",imgDown);
        $(wrapDiv).removeClass('resultDetails').addClass('resultDetailsOff');
        $(detailHref2).show();
    
    }else{
        $(corners).css('display', 'block');
        $(wrapDiv).addClass('resultDetails').removeClass('resultDetailsOff');
        $(detailHref).html('hide');
        $(detailImg).attr("src",imgUp);
        $(detailDiv).removeClass('hidden');
        $(detailHref2).hide();
    }
}



function showDetailsTop5(id){
    var wrapDiv = '#top5_result' + id;
    var detailDiv = '#top5_resultDetails' + id;
    var detailHref = '#top5_det' + id;
    var detailHref2 = '#top5_det_2_' + id;
    var corners = wrapDiv + ' .corner-mblue-tl, ' + wrapDiv + ' .corner-mblue-tr, ' + wrapDiv + ' .corner-mblue-bl, ' + wrapDiv + ' .corner-mblue-br';
    var detailImg = '#top5_img' + id;
    var imgDown = "/images/arrow-down-bl.gif";
    var imgUp = "/images/arrow-up-bl.gif";

    $(detailHref).blur();

    if($(detailHref).html() == 'hide'){
        $(corners).css('display', 'none');
        $(detailDiv).addClass('hidden');
        $(detailHref).html('details');
        $(detailImg).attr("src",imgDown);
        $(wrapDiv).removeClass('resultDetails').addClass('resultDetailsOff');
        $(detailHref2).show();

    
    }else{
        $(corners).css('display', 'block');
        $(wrapDiv).addClass('resultDetails').removeClass('resultDetailsOff');
        $(detailHref).html('hide');
        $(detailImg).attr("src",imgUp);
        $(detailDiv).removeClass('hidden');
        $(detailHref2).hide();
    }
}


function loadingHtm(id, htm, loadState){

    switch(loadState){
        case 0: // spinner
            img = '/images/loader-orange1.gif';
            break;
        case 1: // success
            img = '/images/check-dark.gif';
            break;
        case 2: // error
            img = '/images/circle-red.gif';
            break;
        default: // spinner
            img = '/images/loader-orange1.gif';
    }

    // removing this for now, we'll revisit when we are able to link back to trip details off an ajax requested 'track it' click. - Aaron
    // htm = '<strong>' + htm + '</strong>';
    //wrapping in try/catch so that tagging before complete resultset has loaded doesn't cause errors
    try{
        $(id).html('<img src="' + img + '" alt="" /> ' + htm);
    }
    catch(err){
    }
}
