function flightFinder() {
    //form setup
    this.Form = new DraftfcbForm(document.forms["skyFlights"]);
    this.Form.FormHandle.onsubmit = function() { return false };
    this.Form.ErrorBox = $("p#flightsFormErrorIntro");
    this.Form.Rules.push(
        { Field:  "departFrom",    Method: "Required",          ErrorId: "errorDepartNameRequired" },
        { Field:  "arriveAt",      Method: "Required",          ErrorId: "errorArriveNameRequired" },
        { Field:  "departDate",    Method: "Required",          ErrorId: "errorDepartDateRequired" },
        { Field:  "departDate",    Method: "DateValid",         ErrorId: "errorDepartDateValid" },
        { Field:  "departDate",    Method: "DateNotPast",       ErrorId: "errorDepartDatePast" },
        { Method: "Conditional",   ErrorId: "errorReturnDateRequired", Params: { DependentField: "tripType", DependentValue: "R", ConditionalField: "returnDate", ConditionalMethod: "Required" } },
        { Method: "Conditional",   ErrorId: "errorReturnDateValid",    Params: { DependentField: "tripType", DependentValue: "R", ConditionalField: "returnDate", ConditionalMethod: "DateValid" } },
        { Method: "Conditional",   ErrorId: "errorReturnDatePast",     Params: { DependentField: "tripType", DependentValue: "R", ConditionalField: "returnDate", ConditionalMethod: "DateNotPast" } },
        { Method: "ConditionalReturn", ErrorId: "errorReturnDateLater", Params: { DependentField: "tripType", DependentValue: "R", StartField: "departDate", EndField: "returnDate" } }
    );

    //properties
    this.JSONParams = {
        LANGUAGE: "GB",
        SITE:     "BDCQBDCQ",
        TRIP_FLOW: "YES",
        EMBEDDED_TRANSACTION: "AirAvailability",
        ARRANGE_BY: "E",
        FLIGHTS_NEEDED_1: "10",
        FLIGHTS_NEEDED_2: "10"
    };
    this.SearchTime = {
        "EarlyMorning": { B_TIME_WINDOW: "4",   B_ANY_TIME: "FALSE",    B_TIME: "0500" },
        "LateMorning":  { B_TIME_WINDOW: "2",   B_ANY_TIME: "FALSE",    B_TIME: "1100" },
        "Afternoon":    { B_TIME_WINDOW: "2",   B_ANY_TIME: "FALSE",    B_TIME: "1500" },
        "Evening":      { B_TIME_WINDOW: "2",   B_ANY_TIME: "FALSE",    B_TIME: "1900" },
        "Night":        { B_TIME_WINDOW: "2",   B_ANY_TIME: "FALSE",    B_TIME: "2300" }
    };
    this.ServiceURI = this.Form.FormHandle.action;
    this.Response = null;
    this.Carriers = [
        { Code: "SU", Name: "Aeroflot",         Linkname: "aeroflot" },
        { Code: "AM", Name: "Aeromexico",       Linkname: "aeromexico" },
        { Code: "AF", Name: "Air France",       Linkname: "airfrance" },
        { Code: "AZ", Name: "Alitalia",         Linkname: "alitalia" },
        { Code: "CZ", Name: "China Southern",   Linkname: "chinasouthern" },
        { Code: "CO", Name: "Continental",      Linkname: "continental" },
        { Code: "OK", Name: "Czech Airlines",   Linkname: "czech" },
        { Code: "DL", Name: "Delta",            Linkname: "delta" },
        { Code: "KL", Name: "KLM",              Linkname: "klm" },
        { Code: "KE", Name: "Korean Air",       Linkname: "koreanair" },
        { Code: "NW", Name: "Northwest",        Linkname: "northwest" },
        { Code: "UX", Name: "Air Europa",       Linkname: "aireuropa" },
        { Code: "CM", Name: "Copa Airlines",    Linkname: "copa" },
        { Code: "KQ", Name: "Kenya Airways",    Linkname: "kenyan" }
    ];
    this.LogoBase = "/images/content/about/miles/";
    this.Months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
    this.SmallMonths = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
    this.Itinerary = new itinerary();

    this.Airports =  airportListImport;

    //general methods
    this.BuildResultsTable = buildResultsTable;
    this.ChangeView = changeView;
    this.ClearResponse = clearResponse;
    this.GetAirportLink = getAirportLink;
    this.GetCarrierLogo = getCarrierLogo;
    this.GetDateString = getDateString;
    this.GetDisplayDate = getDisplayDate;
    this.HandleAdd = handleAdd;
    this.HandleDrop = handleDrop;
    this.HandleMainDrop = handleMainDrop;
    this.HandlePrinterFriendly = handlePrinterFriendly;
    this.HandleResults = handleResults;
    this.HandleSubmit = handleSubmit;
    this.ImportResponse = importResponse;
    this.Init = init;
    this.MakeFlightRow = makeFlightRow;
    this.MakeSegmentRow = makeSegmentRow;
    this.PopulateErrorSummary = populateErrorSummary;
    this.PopulateResultsSummary = populateResultsSummary;
    this.ProcessForm = processForm;

    //autocomplete methods
    this.FindValue = findValue;
    this.SelectDepartItem = selectDepartItem;
    this.SelectArriveItem = selectArriveItem;
    this.FormatItem = formatItem;

    function buildResultsTable(trip, intTripIndex, targetTable) {
        if (!$("#" + targetTable).length) {
            $('<table id="' + targetTable + '" class="flightResultsTable" cellpadding="0" cellspacing="0" border="0"/>').insertAfter($("#" + targetTable + "Headers"));
        }
        
        var table = $("table#" + targetTable);
        $.each(trip.Flights, function(j, flight) {
            table.append(FlightFinder.MakeFlightRow(flight, intTripIndex, j, targetTable));
        });
    }

    function changeView(viewState) {
        switch (viewState) {
            case "searching":
                $("div#flightsQueryBox").hide();
                $("#flightsProgressBox").show();
                $("#flightsResponseBox").show("fast");
                break;
            case "error":
                $("div#flightsProgressBox").hide();
                $("#flightsErrorSummaryTable").show();
                $("#flightsErrorActions").show();
                $("#flightsErrorBox").show("fast");
                break;
            case "results":
                $("div#flightsProgressBox").hide();
                $("#flightsResultsSummaryTable").show();
                $("#flightsResultsActions").show();
                $("#flightsResultsBox").show("fast");
                break;
            case "modify":
                $("#flightsErrorSummaryTable").hide();
                $("#flightsErrorActions").hide();
                $("#flightsErrorBox").hide();
                $("#flightsResultsSummaryTable").hide();
                $("#flightsResultsActions").hide();
                $("#flightsResultsBox").hide();
                $("div#flightsResponseBox").hide();
                $("#flightsQueryBox").show("fast");
                break;
            case "itinerary":
                if ($("div#flightsQueryBox").css("display") == "block") {
                    $("div#flightsQueryBox").hide();
                } else if ($("div#flightsResponseBox").css("display") == "block") {
                    $("div#flightsResultsBox").hide();
                    $("div#flightsErrorBox").hide();
                    $("div#flightsResponseBox").hide();
                }
                $("#flightsItineraryActions").show();
                this.Itinerary.RebuildTable();
                $("div#flightsItineraryBox").show("fast", function() {
                    $("div#itinerary").hide("fast");
                });
                break;
            case "new":
                $("div#flightsItineraryBox").hide();
                $("div#itinerary").show("fast", function() {
                    $("div#flightsQueryBox").show("fast");
                });
                break;
            default:
        }
    }

    function clearResponse() {
        $("p.flightsErrorMessage").remove();
        $("tr.flightResultsRow").remove();
    }

    function getAirportLink(strCode) {

        var airportIndex = this.Airports.searchProperty("Code", strCode);

        if (airportIndex > -1) {
            var airportInfo = this.Airports[airportIndex];
            var name = airportInfo.Name;
            var link = airportInfo.Link;
            return $("<a/>").attr("href", link).attr("title", "Guide: " + name).html(strCode);
        } else {
            return strCode;
        }
    }
    
    function getCarrierLogo(strCode) {
        var carrierIndex = this.Carriers.searchProperty("Code", strCode);
        if (carrierIndex > -1) {
            var carrierInfo = this.Carriers[carrierIndex];
            var alt = carrierInfo.Name;
            var src = this.LogoBase + carrierInfo.Linkname + ".png";
            return $("<img/>").addClass("alpha").attr("src", src).attr("alt", alt);
        } else {
            return "&nbsp;";
        }
    }

    function getDateString(objDate) {
        var month = objDate.getMonth() + 1;
        month = (month < 10) ? "0" + month.toString() : month.toString();
        var day = objDate.getDate();
        day = (day < 10) ? "0" + day.toString() : day.toString();
        return (objDate.getFullYear().toString() + month + day);
    }

    function getDisplayDate(objDate) {
        return (objDate.getDate().toString() + " " + this.Months[objDate.getMonth()] + " " + objDate.getFullYear().toString());
    }

    function handleAdd(elemTr) {
        var responseId = elemTr.id.split("_");
        var flight = this.Response[responseId[1]].Flights[responseId[2]];
        this.Itinerary.Add(flight);
    }

    function handleDrop(elemDiv) {
        this.Itinerary.Drop(elemDiv.id);
    }

    function handleMainDrop(elemTr) {
        var flightId = elemTr.id.replace("itinerary_", "");
        this.Itinerary.Drop(flightId);
    }

    function handlePrinterFriendly() {
        this.ChangeView("itinerary");
    }

    function handleResults() {
        this.Response = this.ImportResponse(FlightScheduleResponse);
        if (this.Response.error) {
            var error = this.Response.error[0];
            $("<p/>").addClass("flightsErrorMessage").html(error.ERROR_DESCRIPTION).insertAfter($("div#flightsErrorBox h2"));
            this.PopulateErrorSummary();
            this.ChangeView("error");
        } else {
            if (this.Response.length == 2) {
                $("#flightsReturningBox").show();
            } else {
                $("#flightsReturningBox").hide();
            }
            for (var i = 0; i < this.Response.length; i++) {
                var targetTable = i ? "flightsReturning" : "flightsDeparting";
                this.BuildResultsTable(this.Response[i], i, targetTable);
            }
            this.PopulateResultsSummary();
            this.ChangeView("results");
        }
    }

    function handleSubmit() {
        if (this.Form.Validate()) {
            this.ProcessForm();
        }
    }

    function importResponse(scheduleResponse) {
        if (scheduleResponse.error) {
            return scheduleResponse;
        } else {
            var arrTrips = new Array();
            for (var i=0; i<scheduleResponse.length; i++) {
                var currTrip = scheduleResponse[i];
                var objTrip = new Object();
                objTrip.Flights = new Array();
                for (var j=0; j<currTrip.flights.length; j++) {
                    objTrip.Flights.push(new savedFlight(currTrip.flights[j].SEGMENTS));
                }
                arrTrips.push(objTrip);
            }
            return arrTrips;
        }
    }

    /**
     * initialization
     */
    function init() {
        //set page events
        $("#departFrom").focus(function() {
            this.value = '';
            $("#departCode").get(0).value = "";
        });

        $("#arriveAt").focus(function() {
            this.value = '';
            $("#arriveCode").get(0).value = "";
        });

        //set autocompletes
        $("#departFrom").autocomplete(
                "/airportautocomplete.sky",
            {
                delay:10,
                minChars:3,
                matchSubset:1,
                matchContains:1,
                cacheLength:10,
                onItemSelect:this.SelectDepartItem,
                onFindValue:this.FindValue,
                formatItem:this.FormatItem,
                selectFirst:true,
                autoFill:false
            }
        );

        $("#arriveAt").autocomplete(
                "/airportautocomplete.sky",
            {
                delay:10,
                minChars:3,
                matchSubset:1,
                matchContains:1,
                cacheLength:10,
                onItemSelect:this.SelectArriveItem,
                onFindValue:this.FindValue,
                formatItem:this.FormatItem,
                selectFirst:true,
                autoFill:false
            }
        );

        //itinerary events
        $("li#itineraryAction_printFriendly img").click(function() {
            FlightFinder.HandlePrinterFriendly();
        });

        //form events
        $("input#flightsSubmit").click(function() {
            this.form.elements["departFrom"].value = (this.form.elements["departFrom"].value == "Enter city to depart from") ? "" : this.form.elements["departFrom"].value;
            this.form.elements["arriveAt"].value = (this.form.elements["arriveAt"].value == "Enter destination city") ? "" : this.form.elements["arriveAt"].value;
            FlightFinder.HandleSubmit();
        });

        //response actions
        $(".flightsErrorActionModify,li#flightsResultsActionModify img").click(function() {
            FlightFinder.ChangeView("modify");
        });
        $("li#flightsActionNew").click(function() {
            FlightFinder.ChangeView("new");
        });

        this.Itinerary.Init();
    }

    function makeFlightRow(objFlight, intTripIndex, intFlightIndex) {
        var tr = $("<tr/>").attr("id", "flight_" + intTripIndex + "_" + intFlightIndex).addClass("flightResultsRow").hover(function() { $(this).addClass("over"); }, function() { $(this).removeClass("over"); });
        if (!(intFlightIndex % 2)) {
            tr.addClass("odd");
        }
        var tdA = $("<td/>").addClass("flightResultsA").html('<img src="/images/graphics/go/flights/addIcon.gif" alt="+" width="15" height="15" border="0"/><span>Add to itinerary</span>');
        tdA.children().click(function() {
            FlightFinder.HandleAdd(this.parentNode.parentNode);
        });
        tdA.appendTo(tr);
        var tdB = $("<td/>").addClass("flightResultsB").attr("colspan", "4");
        var flightTable = $("<table/>").addClass("flightSegment").attr("cellspacing", "0").attr("cellpadding", "0").attr("border", "0");
        $.each(objFlight.Segments, function(k, segment) {
            flightTable.append(FlightFinder.MakeSegmentRow(segment, k == objFlight.Segments.length - 1));
        });
        flightTable.appendTo(tdB);
        tdB.appendTo(tr);
        
        return tr;
    }

    function makeSegmentRow(objSegment, isLastSegment) {
        var segmentTr = $("<tr/>");
        var tdA = $("<td/>").addClass("flightSegmentsA");
        tdA.append(this.GetCarrierLogo(objSegment.AIRLINE_CODE)).appendTo(segmentTr);
        $("<td/>").addClass("flightSegmentsB").html(objSegment.AIRLINE_CODE + " " + objSegment.FLIGHT_NUMBER).appendTo(segmentTr);
        var tdC = $("<td/>").addClass("flightSegmentsC").html(objSegment.DEPARTURE_CITY_NAME + " (");
        tdC.append(this.GetAirportLink(objSegment.DEPARTURE_LOCATION_CODE));
        tdC.append(")<br/>" + objSegment.GetDepartTimeDisplay()).appendTo(segmentTr);
        var tdD = $("<td/>").addClass("flightSegmentsD").html(objSegment.DESTINATION_CITY_NAME + " (");
        tdD.append(this.GetAirportLink(objSegment.DESTINATION_LOCATION_CODE));
        tdD.append(")" + "<br/>" + objSegment.GetArriveTimeDisplay()).appendTo(segmentTr);
        $("<td/>").addClass("flightSegmentsE").html(isLastSegment ? objSegment.FLIGHT_TIME : "&nbsp;").appendTo(segmentTr);

        return segmentTr;
    }

    function populateErrorSummary() {
        $("td#flightsErrorSummaryFrom").html(this.GetAirportLink(this.JSONParams.B_LOCATION_1));
        $("td#flightsErrorSummaryTo").html(this.GetAirportLink(this.JSONParams.E_LOCATION_1));
        $("td#flightsErrorSummaryDepart").html(this.GetDisplayDate($("#departDate").datepicker("getDate")));
        if (this.JSONParams.TRIP_TYPE == "R") {
            $("th#flightsErrorSummaryReturnLabel").html("Returning:");
            $("td#flightsErrorSummaryReturn").html(this.GetDisplayDate($("#returnDate").datepicker("getDate")));
        } else {
            $("td#flightsSummaryReturn").empty();
            $("th#flightsErrorSummaryReturnLabel,td#flightsErrorSummaryReturn").html("&nbsp;");
        }
    }

    function populateResultsSummary() {
        $("td#flightsResultsSummaryFrom").html(this.Response[0].Flights[0].GetDepartName() + " (");
        $("td#flightsResultsSummaryFrom").append(this.GetAirportLink(this.Response[0].Flights[0].GetDepartCode()));
        $("td#flightsResultsSummaryFrom").append(")");
        $("td#flightsResultsSummaryTo").html(this.Response[0].Flights[0].GetArriveName() + " (");
        $("td#flightsResultsSummaryTo").append(this.GetAirportLink(this.Response[0].Flights[0].GetArriveCode()));
        $("td#flightsResultsSummaryTo").append(")");
        $("td#flightsResultsSummaryDepart").html(this.GetDisplayDate($("#departDate").datepicker("getDate")));
        if (this.JSONParams.TRIP_TYPE == "R") {
            $("th#flightsResultsSummaryReturnLabel").html("Returning:");
            $("td#flightsResultsSummaryReturn").html(this.GetDisplayDate($("#returnDate").datepicker("getDate")));
        } else {
            $("td#flightsSummaryReturn").empty();
            $("th#flightsResultsSummaryReturnLabel,td#flightsResultsSummaryReturn").html("&nbsp;");
        }
    }

    function processForm() {
        var departTime = this.SearchTime[this.Form.FormHandle.elements["departTime"].value];
        var returnTime = this.SearchTime[this.Form.FormHandle.elements["returnTime"].value];

        this.JSONParams.B_LOCATION_1 = (this.Form.FormHandle.elements["departCode"].value !== "") ? this.Form.FormHandle.elements["departCode"].value : this.Form.FormHandle.elements["departFrom"].value.substring(0, 3).toUpperCase();
        this.JSONParams.E_LOCATION_1 = (this.Form.FormHandle.elements["arriveCode"].value !== "") ? this.Form.FormHandle.elements["arriveCode"].value : this.Form.FormHandle.elements["arriveAt"].value.substring(0, 3).toUpperCase();
        this.JSONParams.TRIP_TYPE = this.Form.GetFieldValue(this.Form.FormHandle.elements["tripType"]);
        this.JSONParams.B_DATE_1 = this.GetDateString($("#departDate").datepicker("getDate")) + departTime.B_TIME;
        this.JSONParams.B_ANY_TIME_1 = departTime.B_ANY_TIME;
        this.JSONParams.B_TIME_WINDOW_1 = departTime.B_TIME_WINDOW;
        if (this.JSONParams.TRIP_TYPE == "R") {
            this.JSONParams.B_DATE_2 = this.GetDateString($("#returnDate").datepicker("getDate"))  + returnTime.B_TIME;
            this.JSONParams.B_ANY_TIME_2 = returnTime.B_ANY_TIME;
            this.JSONParams.B_TIME_WINDOW_2 = returnTime.B_TIME_WINDOW;
        } else {
            delete(this.JSONParams.B_DATE_2);
        }
        var flightsURI = this.ServiceURI + "?";
        for (var i in this.JSONParams) {
            flightsURI += i + "=" + this.JSONParams[i] + "&";
        }
        flightsURI = flightsURI.substring(0, flightsURI.length - 1);
        this.ClearResponse();
        this.ChangeView("searching");
        $.getScript(flightsURI, function() {
            FlightFinder.HandleResults();
        });
    }

    /**
     * ====== autocomplete methods ============================================================
     */

    /**
     * Upon selection, the 3-letter airport code is plugged into the associated hidden input
     * @param li
     * @param objInput - HTMLInputElement
     */
    function findValue(li, objInput) {
        if (li == null) {
            alert("No match!");
        } else {
            var sValue = null;
            // if coming from an AJAX call, let's use the CityId as the value
            if (!!li.extra) {
                sValue = li.extra[0];
            } else {
                sValue = li.selectValue;
            }

            objInput.value = sValue;
        }
    }

    /**
     * Handles a departing city selection
     * @param li
     */
    function selectDepartItem(li) {
        findValue(li, $("input#departCode").get(0));
    }

    /**
     * Handles an arriving city selection
     * @param li
     */
    function selectArriveItem(li) {
        findValue(li, $("input#arriveCode").get(0));
    }

    function formatItem(row) {
        return row[0];
    }

    /**
     * ====== extra form validation methods ======================================================
    */
    this.Form.Conditional = function(intRulesIndex) {
        var objParams = this.Rules[intRulesIndex].Params;
        var objDependent = this.FormHandle.elements[objParams.DependentField];
        if (
                (objParams.ConditionalMethod !== "Required" && this.RuleTest( { Field: objParams.ConditionalField, Method: "Required" } ) && this.GetFieldValue(objDependent) == objParams.DependentValue) ||
                (objParams.ConditionalMethod == "Required" && this.GetFieldValue(objDependent) == objParams.DependentValue)
        ) {
            return this.RuleTest( { Field: objParams.ConditionalField, Method: objParams.ConditionalMethod } );
        } else {
            return true;
        }
    }

    this.Form.ConditionalReturn = function(intRulesIndex) {
        var objParams = this.Rules[intRulesIndex].Params;
        var objDependent = this.FormHandle.elements[objParams.DependentField];
        if (this.RuleTest( { Field: "returnDate", Method: "Required" } ) && this.GetFieldValue(objDependent) == objParams.DependentValue) {
            var startValue = this.FormHandle.elements[objParams.StartField].value.split("/");
            var startDate = new Date(startValue[2], startValue[1] - 1, startValue[0]);
            var endValue = this.FormHandle.elements[objParams.EndField].value.split("/");
            var endDate = new Date(endValue[2], endValue[1] - 1, endValue[0]);
            return (startDate <= endDate);
        } else {
            return true;
        }
    }

    this.Form.GetFieldValue = function(objElement) {
        if (objElement[0].type == "radio") {
            for (var i=0; i<objElement.length; i++) {
                if (objElement[i].checked) {
                    return objElement[i].value;
                }
            }
        }
    }
}

function itinerary() {
    //properties
    this.Flights = new Array();

    //methods
    this.Add = add;
    this.RebuildTable = rebuildTable;
    this.ChangeMessaging = changeMessaging;
    this.CompareFlights = compareFlights;
    this.Cookies = new cookieHandler();
    this.Drop = drop;
    this.Init = init;
    this.Load = load;
    this.MakeMarkupBox = makeMarkupBox;
    this.MakeMarkupRow = makeMarkupRow;
    this.ResetLast = resetLast;
    this.ResetOddRows = resetOddRows;
    this.Save = save;

    function add(objFlight) {
        if (this.Flights.searchProperty("ID", objFlight.ID) == -1) {
            this.Flights.push(objFlight);
            this.Flights.sort(this.CompareFlights);
            var boxes = $("div.itineraryFlightBox");
            var newBox = this.MakeMarkupBox(objFlight);
            var rows = $("tr.itineraryResultsRow");
            var newRow = this.MakeMarkupRow(objFlight);
            var newIndex = this.Flights.searchProperty("ID", objFlight.ID);
            if (!$("table#itineraryFlights").length) {
                $('<table id="itineraryFlights" class="flightResultsTable" cellpadding="0" cellspacing="0" border="0"/>').insertAfter($("table#itineraryFlightsHeaders"));
            }
            if (!boxes.length) {
                this.ChangeMessaging();
                newBox.appendTo("div#itinerary div.itineraryMiddleContent");
                newRow.appendTo("table#itineraryFlights");
                $("p#flightsItineraryEmpty").hide("fast", function() {
                    $("table#itineraryFlights").show("fast");
                });
            } else {
                if (newIndex == 0) {
                    newBox.insertBefore(boxes.filter(":first"));
                    newRow.insertAfter(rows.filter(":first"));
                } else if (newIndex == boxes.length) {
                    newBox.insertAfter(boxes.filter(":last"));
                    newRow.insertAfter(rows.filter(":last"));
                } else {
                    newBox.insertBefore(boxes[newIndex]);
                    newRow.insertBefore(rows[newIndex]);
                }
            }
            newBox.show("fast");
            this.ResetLast();
            this.ResetOddRows();
            this.Save();
        }
    }

    function changeMessaging(message) {
        $("li.itineraryMessages").hide();
        switch (message) {
            case "empty":
                $("li#itineraryMessage_empty").show("fast");
                break;
            default:
        }
    }

    function compareFlights(a, b) {
        if (a.GetDepartDate() < b.GetDepartDate())
            return -1;
        if (a.GetDepartDate() > b.GetDepartDate())
            return 1;
        return 0;
    }

    function drop(flightId) {
        flightIndex = this.Flights.searchProperty("ID", flightId);
        if (flightIndex > -1) {
            this.Flights.splice(flightIndex, 1);
            $("div#" + flightId).hide("fast", function() {
                $(this).remove();
            });
            $("tr#itinerary_" + flightId).remove();
            this.ResetLast(flightId);
            this.ResetOddRows();
            this.Save();
            if (!this.Flights.length) {
                this.ChangeMessaging("empty");
                $("table#itineraryFlights").hide("fast", function() {
                    $("p#flightsItineraryEmpty").show("fast");
                });
            }
        }
    }

    function init() {
        this.Load();
    }

    function load() {
        var flightStore = this.Cookies.Read("yourItinerary");
        if (flightStore) {
            var parsedFlights = JSON.parse(this.Cookies.Read("yourItinerary"));
            if (parsedFlights.length) {
                this.ChangeMessaging();
                for (var i = 0; i < parsedFlights.length; i++) {
                    var parsedFlight = parsedFlights[i];
                    var newFlight = new savedFlight(parsedFlight.Segments)
                    this.Flights.push(newFlight);
                    var newBox = this.MakeMarkupBox(newFlight);
                    if (i == parsedFlights.length - 1) {
                        newBox.addClass("last");
                    }
                    newBox.appendTo("div#itinerary div.itineraryMiddleContent").show("fast");
                }
                $("p#flightsItineraryEmpty").hide("fast", function() {
                    $("table#itineraryFlights").show("fast");
                });
                this.ResetLast();
            } else {
                this.ChangeMessaging("empty");
            }
        } else {
            this.ChangeMessaging("empty");
        }
    }

    function makeMarkupBox(objFlight) {
        var div = $("<div/>").attr("id", objFlight.ID).addClass("itineraryFlightBox").css("display", "none");
        var table = $("<table/>").addClass("itineraryFlightTable").attr("cellpadding", "0").attr("cellspacing", "0").attr("border", "0");
        $("<tr><th>Flight:</th><td>" + objFlight.Segments[0].AIRLINE_CODE + " " + objFlight.Segments[0].FLIGHT_NUMBER + "</td></tr>").appendTo(table);
        $("<tr><th>Date:</th><td>" + objFlight.GetDepartDateDisplay() + "</td></tr>").appendTo(table);
        $("<tr><th>Depart:</th><td>" + objFlight.GetDepartTimeDisplay() + " (" + objFlight.Segments[0].DEPARTURE_LOCATION_CODE + ")</td></tr>").appendTo(table);
        $("<tr><th>Arrive:</th><td>" + objFlight.GetArriveTimeDisplay() + " (" + objFlight.Segments[objFlight.Segments.length - 1].DESTINATION_LOCATION_CODE + ")</td></tr>").appendTo(table);
        if (objFlight.Stops.length) {
            var trStops = $("<tr/>").append($("<th/>").html("Stops:"));
            var stops = objFlight.Stops;
            var tdStops = $("<td/>");
            for (var i = 0; i < stops.length; i++) {
                tdStops.append(stops[i] + (i < stops.length - 1 ? ", " : ""));
            }
            tdStops.appendTo(trStops);
            trStops.appendTo(table);
        }
        $("<tr><th>Duration:</th><td>" + objFlight.Segments[objFlight.Segments.length - 1].FLIGHT_TIME + "</td>").appendTo(table);
        table.appendTo(div);
        var span = $("<span/>").addClass("itineraryFlightActionList").addClass("delete").click(function() {
            FlightFinder.HandleDrop(this.parentNode);
        }).html("<img src=\"/images/graphics/go/flights/delete.gif\" width=\"131\" height=\"17\" alt=\"Delete\"/>");
        span.appendTo(div);

        return div;
    }

    function makeMarkupRow(objFlight) {
        var tr = $("<tr/>").attr("id", "itinerary_" + objFlight.ID).addClass("itineraryResultsRow").hover(function() {
            $(this).addClass("over");
        }, function() {
            $(this).removeClass("over");
        });
        var tdA = $("<td/>").addClass("itineraryResultsA").html('<span>Remove from itinerary</span>');
        tdA.children().click(function() {
            FlightFinder.HandleMainDrop(this.parentNode.parentNode);
        });
        tdA.appendTo(tr);
        $("<td/>").addClass("itineraryResultsB").html(objFlight.GetDepartDateDisplay()).appendTo(tr);

        var tdC = $("<td/>").addClass("itineraryResultsC").attr("colspan", "4");
        var flightTable = $("<table/>").addClass("itinerarySegment").attr("cellspacing", "0").attr("cellpadding", "0").attr("border", "0");
        $.each(objFlight.Segments, function(i, segment) {
            var segmentTr = $("<tr/>");
            var tdA = $("<td/>").addClass("itinerarySegmentsA");
            tdA.append(FlightFinder.GetCarrierLogo(segment.AIRLINE_CODE)).appendTo(segmentTr);
            $("<td/>").addClass("itinerarySegmentsB").html(segment.AIRLINE_CODE + " " + segment.FLIGHT_NUMBER).appendTo(segmentTr);
            var tdC = $("<td/>").addClass("itinerarySegmentsC").html(segment.DEPARTURE_CITY_NAME + " (");
            tdC.append(FlightFinder.GetAirportLink(segment.DEPARTURE_LOCATION_CODE));
            tdC.append(")<br/>" + segment.GetDepartTimeDisplay()).appendTo(segmentTr);
            var tdD = $("<td/>").addClass("itinerarySegmentsD").html(segment.DESTINATION_CITY_NAME + " (");
            tdD.append(FlightFinder.GetAirportLink(segment.DESTINATION_LOCATION_CODE));
            tdD.append(")" + "<br/>" + segment.GetArriveTimeDisplay()).appendTo(segmentTr);
            $("<td/>").addClass("flightSegmentsE").html(i == objFlight.Segments.length - 1 ? segment.FLIGHT_TIME : "&nbsp;").appendTo(segmentTr);
            segmentTr.appendTo(flightTable);
        });
        flightTable.appendTo(tdC);
        tdC.appendTo(tr);

        return tr;
    }

    function rebuildTable() {
        $("table#itineraryFlights").remove();
        $('<table id="itineraryFlights" class="flightResultsTable" cellpadding="0" cellspacing="0" border="0"/>').insertAfter($("table#itineraryFlightsHeaders"));
        $.each(this.Flights, function(i, Flight) {
            var newRow = FlightFinder.Itinerary.MakeMarkupRow(Flight);
            newRow.appendTo("table#itineraryFlights");
        });
        this.ResetOddRows();
    }

    function resetLast(flightId) {
        $("div.itineraryFlightBox").removeClass("last");
        var divs = $("div.itineraryFlightBox");
        if (flightId) {
            divs = divs.not("#" + flightId);
        }
        divs.filter(":last").addClass("last");
    }

    function resetOddRows() {
        $("tr.itineraryResultsRow").removeClass("odd").filter(":even").addClass("odd");
    }

    function save() {
        var flightsJSON = JSON.stringify(this.Flights);
        this.Cookies.Create("yourItinerary", flightsJSON, 30);
    }
}

function savedFlight(responseSegments) {
    //properties
    this.Segments = new Array();
    this.Stops = new Array();
    this.ID = null

    //methods
    this.GetArriveCode = getArriveCode;
    this.GetArriveDate = getArriveDate;
    this.GetArriveName = getArriveName;
    this.GetArriveTimeDisplay = getArriveTimeDisplay;
    this.GetDepartCode = getDepartCode;
    this.GetDepartDate = getDepartDate;
    this.GetDepartDateDisplay = getDepartDateDisplay;
    this.GetDepartName = getDepartName;
    this.GetDepartTimeDisplay = getDepartTimeDisplay;
    this.SetID = setId;
    this.SetStops = setStops;

    function getArriveCode() {
        return this.Segments[this.Segments.length - 1].DESTINATION_LOCATION_CODE;
    }

    function getArriveDate() {
        return this.Segments[this.Segments.length - 1].GetArriveDate();
    }

    function getArriveName() {
        return this.Segments[this.Segments.length - 1].DESTINATION_CITY_NAME;
    }

    function getArriveTimeDisplay() {
        var departDate = this.GetDepartDate();
        var arriveDate = this.Segments[this.Segments.length - 1].GetArriveDate();
        var strArrive = (arriveDate.getHours() < 10 ? "0" : "") + arriveDate.getHours() + ":" + (arriveDate.getMinutes() < 10 ? "0" : "") + arriveDate.getMinutes();
        var departCompare = new Date(departDate.getFullYear(), departDate.getMonth(), departDate.getDate());
        var arriveCompare = new Date(arriveDate.getFullYear(), arriveDate.getMonth(), arriveDate.getDate());
        if (arriveCompare > departCompare) {
            intDaysDiff = (arriveCompare - departCompare) / (24 * 60 * 60 * 1000);
            strArrive += " +&nbsp;" + intDaysDiff + (intDaysDiff > 1 ? "&nbsp;days" : "&nbsp;day");
        }
        return strArrive;
    }

    function getDepartCode() {
        return this.Segments[0].DEPARTURE_LOCATION_CODE;
    }
    function getDepartDate() {
        return this.Segments[0].GetDepartDate();
    }

    function getDepartDateDisplay() {
        var dd = this.GetDepartDate();
        return dd.getDate() + " " + FlightFinder.SmallMonths[dd.getMonth()] + " " + dd.getFullYear();
    }

    function getDepartName() {
        return this.Segments[0].DEPARTURE_CITY_NAME;
    }

    function getDepartTimeDisplay() {
        return this.Segments[0].GetDepartTimeDisplay();
    }

    function setId() {
        var fd = this.GetDepartDate();
        var strDate = fd.getFullYear().toString() + (fd.getMonth() < 10 ? "0" : "") + fd.getMonth().toString() + (fd.getDate() < 10 ? "0" : "") + fd.getDate().toString() + (fd.getHours() < 10 ? "0" : "") + fd.getHours().toString() + (fd.getMinutes() < 10 ? "0" : "") + fd.getMinutes().toString();
        var strFlight = "";
        var strRoute = this.Segments[0].DEPARTURE_LOCATION_CODE;
        for (var i=0; i<this.Segments.length; i++) {
            strFlight += this.Segments[i].AIRLINE_CODE + this.Segments[i].FLIGHT_NUMBER + (i < this.Segments.lenth - 1 ? "-" : "");
            strRoute += "-" + this.Segments[i].DESTINATION_LOCATION_CODE;
        }
        this.ID = strDate + "_" + strFlight + "_" + strRoute;
    }

    function setStops() {
        for (var i=0; i<this.Segments.length - 1; i++) {
            this.Stops.push(this.Segments[i].DESTINATION_CITY_NAME);
        }
    }

    //init
    for (var i=0; i<responseSegments.length; i++) {
        this.Segments.push(new flightSegment(responseSegments[i]));
    }
    this.SetStops();
    this.SetID();
}

function flightSegment(responseSegment) {
    // 'public' properties
    this.DEPARTURE_CITY_NAME = null;
    this.DEPARTURE_LOCATION_CODE = null;
    this.DEPARTURE_LOCATION_NAME = null;
    this.DESTINATION_CITY_NAME = null;
    this.DESTINATION_LOCATION_CODE = null;
    this.DESTINATION_LOCATION_NAME = null;
    this.AIRLINE_CODE = null;
    this.FLIGHT_NUMBER = null;
    this.DEPARTURE_TIME = null;
    this.ARRIVAL_TIME = null;
    this.FLIGHT_TIME = null;
    this.NUMBER_OF_STOPS = null;

    // 'public' methods
    this.GetArriveDate = getArriveDate;
    this.GetArriveTimeDisplay = getArriveTimeDisplay;
    this.GetDepartDate = getDepartDate;
    this.GetDepartTimeDisplay = getDepartTimeDisplay;
    this.ResponseDateToObject = responseDateToObject;

    function getArriveDate() {
        return this.ResponseDateToObject(this.ARRIVAL_TIME);
    }

    function getArriveTimeDisplay() {
        var dd = this.GetDepartDate();
        var ad = this.GetArriveDate();
        var strArrive = (ad.getHours() < 10 ? "0" : "") + ad.getHours() + ":" + (ad.getMinutes() < 10 ? "0" : "") + ad.getMinutes();
        var departCompare = new Date(dd.getFullYear(), dd.getMonth(), dd.getDate());
        var arriveCompare = new Date(ad.getFullYear(), ad.getMonth(), ad.getDate());
        if (arriveCompare > departCompare) {
            intDaysDiff = (arriveCompare - departCompare) / (24 * 60 * 60 * 1000);
            strArrive += " +&nbsp;" + intDaysDiff + (intDaysDiff > 1 ? "&nbsp;days" : "&nbsp;day");
        }
        return strArrive;
    }

    function getDepartDate() {
        return this.ResponseDateToObject(this.DEPARTURE_TIME);
    }

    function getDepartTimeDisplay() {
        var dd = this.GetDepartDate();
        return (dd.getHours() < 10 ? "0" : "") + dd.getHours() + ":" + (dd.getMinutes() < 10 ? "0" : "") + dd.getMinutes();
    }

    function responseDateToObject(strDate) {
        var intYear = parseInt(strDate.substring(0,4));
        var strMonth = strDate.substring(4, 6);
        var intMonth = ((strMonth.substring(0, 1) == "0") ? parseInt(strMonth.substring(1, 2)) : parseInt(strMonth)-1);
        var strDay = strDate.substring(6, 8);
        var intDay = (strDay.substring(0, 1) == "0") ? parseInt(strDay.substring(1, 2)) : parseInt(strDay);
        var strHrs = strDate.substring(8, 10);
        var intHrs = (strHrs.substring(0, 1) == "0") ? parseInt(strHrs.substring(1, 2)) : parseInt(strHrs);
        var strMins = strDate.substring(10, 12);
        var intMins = (strMins.substring(0, 1) == "0") ? parseInt(strMins.substring(1, 2)) : parseInt(strMins);
        return new Date(intYear, intMonth, intDay, intHrs, intMins, 0);
    }

    for (var i in responseSegment) {
        this[i] = responseSegment[i];
    }
}