/* 
 * The car model domain model. 
 * The origin information is added as comment behind each line. 
 */
function Model(id, category, categoryName, engineType, brand, series, carbody,
    modelType, gearbox, basePrice,
    fuelConsumption, fuelConsumptionUnit,
    emission, emissionUnit, torsional, acceleration, kw, ps, fuelType,
    doorCount, seatCount, trunkVolume, payload, roofload,
    oldFuelPrice) {
  
    this.id = id; // XML: KFZID
    this.category = category;// XML: Fzg_Kl_Nr
    this.categoryName = categoryName;// XML: FzgKlasse
    this.engineType = engineType;// XML: Motart
    this.brand = brand;// XML: Marke
    this.series = series;// XML: Hauptbaureihe
    this.carbody = carbody;// XML: Aufbau
  
    this.modelType = modelType;// XML: Modell_Typ
    this.gearbox = gearbox;// XML: Getriebeart
    this.basePrice = basePrice;// XML: Preis
    this.fuelConsumption = fuelConsumption;// XML: Verbrauch_gesamt [1/2]
    this.fuelConsumptionUnit = fuelConsumptionUnit;// XML: Verbrauch_gesamt [2/2]
  
    this.emission = emission;// XML: CO2 [1/2]
    this.emissionUnit = emissionUnit;// XML: CO2 [2/2]
    this.torsional = torsional;// XML: NM$$baseModel.
    this.acceleration = acceleration;// XML: Beschleun
    this.kw = kw;// XML: kW
    this.ps = ps;// XML: PS
    this.fuelType = fuelType;// XML: Kraftsvar Motoffart
    this.doorCount = doorCount;// XML: Tueren
    this.seatCount = seatCount;// XML: SitzeMax
    this.trunkVolume = trunkVolume;// XML: KoffVolumen
    this.payload = payload;// XML: Zuladung
    this.roofload = roofload;// XML: Dachlast

    this.oldFuelPrice = oldFuelPrice;// XML: PreisX (depends on fuel type)

}

function Graph() {

    var points = [];

    this.addPoint = function(point) {
        points.push(point);
    }

    this.getPoint = function(index) {
        return points[index];
    }
    this.getCostValuesAsArray = function() {
        var pointsArray = [];
        jQuery.each(points, function(i,val){
            pointsArray.push(val.toArray());
        });
        return(pointsArray);
    }
}

function Point(xValue, yValue) {

    var x = xValue;
    var y = yValue;

    this.getX = function() {
        return Math.round(x);
    }

    this.getY = function() {
        return Math.round(y);
    }

    this.toArray = function() {
        return [this.getX(), this.getY()];
    }
}

/*
 * The Class CostsLight. This is a variant of class Costs used in the Light Version.
 */
function CostsLight(fuelCostsPerKmNew, userKilometrage) {

    var theTotalCosts = fuelCostsPerKmNew * userKilometrage;

    /* The name of this method must be identical with the one in class Costs. */
    this.getTotalCostsOneYear = function() {
        return theTotalCosts;
    }
}

/*
 * The class Costs.
 *
 * @param operands the calculation components in €
 *        [wv/lossInValueOneMonth, fix/fixCostsOneMonth, bk/operatingCostsOneMonth, wk/maintainingCostsOneMonth]
 * @param oldFuelCosts in €/km - the costs included in operatingCostsOneYear.
 * @param newFuelCosts in currency/km
 * @param kilometrage in km
 * @param euroExchangeRate factor to multiply operands with
 */
function Costs(operands, oldFuelCosts, newFuelCosts, kilometrage, euroExchangeRate) {

    var theOperands = operands;
    var theIncludedFuelCosts = oldFuelCosts;
    var theNewFuelCosts = newFuelCosts;
    var theKilometrage = kilometrage;
    var theExchangeRage = euroExchangeRate;
    var behaveCommercial = LABELS.get("behaveCommercial");

    
    this.getLossInValueOneYear = function() {
        var result = theOperands[0] * 12.0 * theExchangeRage;
        if (behaveCommercial) {
            result = result / (1.0 + VAT_GERMANY);
        }
        return Math.round(result);
    }

    /** Calling this method only makes sense if behaveCommercial is true. */
    this.getVat4LossInValueOneYear = function() {
        return this.getLossInValueOneYear() * VAT_GERMANY;
    }

    this.getFixCostsOneYear = function() {
        var result = theOperands[1] * 12.0 * theExchangeRage;
        if (behaveCommercial) {
            result = result - VATCOSTS_GERMANY_FIXCOSTS;
        }
        return Math.round(result);
    }

    /** Calling this method only makes sense if behaveCommercial is true. */
    this.getVat4FixCostsOneYear = function() {
        return VATCOSTS_GERMANY_FIXCOSTS;
    }

    this.getOperatingCostsOneYearWithoutFuel = function() {
        var operatingCostsOneYearIncludingFuelCostsWithWrongPrice = (theOperands[2] * 12.0);
        var result =  operatingCostsOneYearIncludingFuelCostsWithWrongPrice - (theIncludedFuelCosts * theKilometrage); // in €
        if (result < 0.0) {
            return 0.0;
        }
        return Math.round(result);
    }
    
    this.getOperatingCostsOneYear = function() {
        var result = (this.getOperatingCostsOneYearWithoutFuel() * theExchangeRage) + (theNewFuelCosts * theKilometrage);
        if (behaveCommercial) {
            result = result / (1.0 + VAT_GERMANY);
        }
        return Math.round(result);
    }

    /** Calling this method only makes sense if behaveCommercial is true. */
    this.getVat4OperatingCostsOneYear = function() {
        return this.getOperatingCostsOneYear() * VAT_GERMANY;
    }

    this.getMaintainingCostsOneYear = function() {
        var result = theOperands[3] * 12.0 * theExchangeRage;
        if (behaveCommercial) {
            result = result / (1.0 + VAT_GERMANY);
        }
        return Math.round(result);
    }

    /** Calling this method only makes sense if behaveCommercial is true. */
    this.getVat4MaintainingCostsOneYear = function() {
        return this.getMaintainingCostsOneYear() * VAT_GERMANY;
    }

    /* The name of this method must be identical with the one in class CostsLight. */
    this.getTotalCostsOneYear = function() {
        return this.getLossInValueOneYear() + this.getFixCostsOneYear() + this.getOperatingCostsOneYear() + this.getMaintainingCostsOneYear();
    }

    this.getTotalCostsOneYearWithoutFuel = function() {
        return this.getLossInValueOneYear() + this.getFixCostsOneYear() + this.getOperatingCostsOneYearWithoutFuel() + this.getMaintainingCostsOneYear();
    }

    /** Calling this method only makes sense if behaveCommercial is true. */
    this.getVat4TotalCostsOneYear = function() {
        return this.getVat4LossInValueOneYear() + this.getVat4FixCostsOneYear() + this.getVat4OperatingCostsOneYear() + this.getVat4MaintainingCostsOneYear();
    }
}

var Model_array_sortByFunctions = {
    id: function(x,y) {
        return x.id - y.id;
    },
    fuelConsumption: function(x,y) {
        return x.fuelConsumption - y.fuelConsumption;
    },
    emission: function(x,y) {
        return x.emission - y.emission;
    },
    kw: function(x,y) {
        return x.kw - y.kw;
    }
// NOTE: This sort function could be extended from outside. For example the modelfinder
// defines it's own for the extra (calculated) field 'costDetails'.
};



/* The brand info domain model. */
function BrandInfo(id, website, hallIAA, standIAA) {
    this.id = id;
    this.website = website;
    this.hallIAA = hallIAA;
    this.standIAA = standIAA;
}

/* The Bosch info domain model. */
function BoschInfo(websiteURL, contactURL, imprintURL, dieselURL) {
    this.websiteURL = websiteURL;
    this.contactURL = contactURL;
    this.imprintURL = imprintURL;
    this.dieselURL = dieselURL;
}

/** The model calculation data domain model. */
function ModelCalculationData(wv, fix, bk, wk) {
    this.wv = wv; // Wertverlust
    this.fix = fix; // Fixkosten
    this.bk = bk; // Betriebskosten
    this.wk = wk; // Werkstattkosten
}

/** The fuel price domain model for a specific country. */
function FuelPrice(currency, euroExchangeRate, prices) {
    this.currency = currency;
    this.euroExchangeRate = euroExchangeRate;
    this.prices = prices;
}


function ServerConnector(){
    this.getBreakevens = function(graph1,graph2){
        var result='';
        jQuery.ajax({
            url:'getBreakEvens.htm',
            data:"graph1=" + JSON.stringify(graph1) + "&graph2=" + JSON.stringify(graph2),
            type:"GET",
            datatype:'json',
            async:false,
            success: function(get){
                result=JSON.parse(get);
            }
        });

        return result['values'];
    }
}
