var Data = Class.create({
    initialize: function() {
        this.reset();
    },
    reset: function() {
        this.data = {
            airlineCodes: [],
            vendors:      [],
            airlines:     [],
            prices:       [],
            service:      {},
            calculate:    {},
            codeVendors:  {},
            codeAirlines: {}
        };
        this.state = 0;
        this.duplicateCounter = 0;

        try {
            this.criteria = {passengers: $('numAdults').value};
            var form  = document.forms['searchfrm'];
            var departureNode = form.elements['departureAirport'];
            var destinationNode = form.elements['destinationAirport'];
            try {
                var departure   = (departureNode.nodeName.toLowerCase() == 'select')
                                ? departureNode.options[departureNode.selectedIndex].text
                                : departureNode.value.split(',')[0];
                var destination = (destinationNode.nodeName.toLowerCase() == 'select')
                                ? destinationNode.options[destinationNode.selectedIndex].text
                                : destinationNode.value.split(',')[0];
                this.setData('departure',   departure);
                this.setData('destination', destination);
            } catch (e) {
                dispatchException(e);
            }
        } catch (e) {
            dispatchException(e);
        }
    },
    calculate: function() {
        this.data.calculate = {
            vendorPrices:  {},
            airlinePrices: {},
            directVendors: [],
            agents:        []
        };

        this.getVendors().each(function(vendor) {
            this.data.calculate['vendorPrices'][vendor.getCode()] = this.getVendorPrices(vendor, true);
            if (vendor.isDirect()) {
                this.data.calculate['directVendors'].push(vendor);
            } else {
                this.data.calculate['agents'].push(vendor);
            }
        }.bind(this));

        this.getAirlines().each(function(airline) {
            this.data.calculate['airlinePrices'][airline.getCode()] = this.getAirlinePrices(airline, true);
        }.bind(this));
    },
    isUpdated: function() {
        var string = 'P' + this.getPrices().length
                   + '.A' + this.getAirlines().length
                   + '.V' + this.getVendors().length;
        if (this.state != string) {
            this.state = string;
            return true;
        }
        return false;
    },
    setData: function(key, value) {
        this.data.service[key] = value;
    },
    getData: function(key) {
        if (typeof(this.data.service[key]) != "undefined") {
            return this.data.service[key];
        }
        return null;
    },
    addVendor: function(vendor) {
        return this.data.vendors.push(vendor);
    },
    setVendorAsFinished: function(finishedVendorName) {
        var vendors = this.getVendors();
        for (var i = 0, length = vendors.length; i < length; i++) {
            var vendor = vendors[i];
            if (vendor.getCode() == finishedVendorName) {
                vendor.setFinished(true);
                this.data.vendors[i] = vendor;
            }
        }
    },
    getAirlineBestFare: function(airline) {
        var prices = this.getAirlinePrices(airline);
        var bestFare = prices[0];
        for (var i = 0, length = prices.length; i < length; i++) {
            var price = prices[i];
            if (price.getValue(true) < bestFare.getValue(true) ||
                parseInt(bestFare.getValue(true)) == 0) {
                bestFare = price;
            }
        }
        return bestFare;
    },
    getVendorAirline: function(vendor) {
        var vendors = this.getVendors();
        for (var i = 0, length = vendors.length; i < length; i++) {
            if (vendors[i].getCode() == vendor.getCode()) {
                return vendors[i].getAirlines();
            }
        }
    },
    getVendorPrices: function(vendor, calculate) {
        if (! calculate) {
            return this.data.calculate['vendorPrices'][vendor.getCode()];
        }
        var result = [];
        var prices = this.getPrices();
        try {
            for (var i = 0, length = prices.length; i < length; i++) {
                if (prices[i].getVendor().getCode() == vendor.getCode()) {
                    result.push(prices[i]);
                }
            }
        } catch (e) {
            dispatchException(e);
        }
        return result;
    },
    getAirlinePrices: function(airline, calculate) {
        if (! calculate) {
            return this.data.calculate['airlinePrices'][airline.getCode()];
        }
        var result = [];
        var prices = this.getPrices();
        for (var i = 0, length = prices.length; i < length; i++) {
            var price = prices[i];
            if (price.getAirline().getCode() != airline.getCode()) {
                continue;
            }
            result.push(price);
        }
        return result;
    },
    getBestPrices: function(vendor) {
        var result = [];
        var prices = this.getPrices();
        for (var i = 0, length = prices.length; i < length; i++) {
            if (typeof(prices[i]) == "undefined") {
                continue;
            }
            var price = prices[i];
            if (price['vendor'] != vendor) {
                continue;
            }
            result.push(price);
        }
        return result;
    },
    addPrice: function(price) {
        var prices = this.getPrices();
        if (typeof(this.data.bestPrice) == 'undefined') {
            this.data.bestPrice = price;
        }
        if (price.getValue(true) < this.data.bestPrice.getValue(true)) {
            this.data.bestPrice = price;
        }
        this.data.prices.push(price);
    },
    getBestPrice: function() {
        if (typeof (this.data.bestPrice) != 'undefined') {
            return this.data.bestPrice;
        }
        return false;
    },
    addAirline: function(airline) {
        this.data.airlines.push(airline);
    },
    getAirlines: function() {
        return this.data.airlines.toArray();
    },
    getAirlineName: function(code) {
        var airlines = this.getAirlines();
        for (var i = 0, length = airlines.length; i < length; i++) {
            if (airlines[i].getCode() == code.toLowerCase()) {
                return airlines[i].getName();
            }
        }
        return code;
    },
    getVendors: function() {
        return this.data.vendors.toArray();
    },
    getDirectVendors: function() {
        return this.calculate['directVendors'];
    },
    getVendorByCode: function(code) {
        if (typeof (this.data.codeVendors[code]) == 'undefined') {
            this.getVendors().each(function() {
                var code   = arguments[0];
                var vendor = arguments[1];
                if (typeof (this.data.codeVendors[code]) == 'undefined') {
                    if (vendor.getCode() == code) {
                        this.data.codeVendors[code] = vendor;
                    }
                }
            }.bind(this, code));
        }
        if (typeof (this.data.codeVendors[code]) != 'undefined') {
            return this.data.codeVendors[code];
        }
        return false;
    },
    getPrices: function() {
        return this.data.prices.toArray();
    },
    getPrice: function(index) {
        return this.getPrices()[index];
    },
    getDirectVendors: function() {
        var directVendors = [];
        var vendors = this.getVendors();
        if (vendors.length > 0) {
            for (var i = 0, length; i < vendors.length; i++) {
                var vendor = vendors[i];
                if (vendor.isDirect()) {
                    directVendors.push(vendor);
                }
            }
        }
        return directVendors;
    },
    getAgentsNumber: function() {
        var counter = 0;
        var vendors = this.getVendors();
        if (vendors.length > 0) {
            for (var i = 0, length = vendors.length; i < length; i++) {
                var vendor = vendors[i];
                if (! vendor.isDirect()) {
                    counter++;
                }
            }
        }
        return counter;
    },
    getAgents: function() {
        var counter = 0;
        var agents  = [];
        var vendors = this.getVendors();
        for (var i = 0, length = vendors.length; i < length; i++) {
            var vendor = vendors[i];
            if (!vendor.isDirect()) {
                agents.push(vendor);
            }
        }
        return agents;
    },
    getPriceDetails: function(price) {
        return this.getPrices()[price].getDetails();
    },
    getMaxLimit: function() {
        var limit = 60;
        var vendors = this.getVendors();
        for (var i = 0, length = vendors.length; i < length; i++) {
            var vendor  = vendors[i];
            if (vendors[i].getLimit() > limit) {
                limit = vendor.getLimit();
            }
        }
        return limit;
    },
    directVendorExistsForAirline: function(airline) {
        var vendors = this.getDirectVendors();
        for (var i = 0, length = vendors.length; i < length; i++) {
            var vendor  = vendors[i];
            if (vendor.getAirlines().toString().indexOf(airline.getCode()) != -1) {
                return true;
            }
        }
        return false;
    },
    hasDirectVendors: function() {
        var vendors = this.getVendors();
        for (var i = 0, length = vendors.length; i < length; i++) {
            if (vendors[i].isDirect()) {
                return true;
            }
        }
        return false;
    },
    addAirlineCode: function(code) {
        this.code = code;
        this.getAirlines().each(function(airline) {
            if (airline.getCode() == this.code) {
                this.code = false;
            }
        }.bind(this));
        if (this.code) {
            this.data.airlineCodes.push(this.code);
        }
        this.code = null;
    },
    getAirlineCodes: function() {
        return this.data.airlineCodes;
    },
    clearAirlineCodes: function() {
        this.data.airlineCodes = [];
    },
    getAirlineByCode: function(code) {
        if (!(code in this.data.codeAirlines)) {
            this.getAirlines().each(function() {
                var code   = arguments[0];
                var airline = arguments[1];
                if (typeof (this.data.codeAirlines[code]) == 'undefined') {
                    if (airline.getCode() == code) {
                        this.data.codeAirlines[code] = airline;
                    }
                }
            }.bind(this, code));
        }
        if (code in this.data.codeAirlines) {
            return this.data.codeAirlines[code];
        }
        return false;
    },
    isFinished: function() {
        this.status = true;
        this.getVendors().each(function(vendor) {
            if (!vendor.isFinished()) {
                this.status = false;
            }
        }.bind(this));
        return this.status;
    }
});
