if (Calculators == undefined) {
	var Calculators = {};
}
if (Calculators.loan == undefined) {
	Calculators.loan = {};
}
Calculators.loan.CarLoan = function CarLoan(price, salesTaxRate, fees, residualPercent, downPayment, terms, interestRate, rateOfReturn) {
	this.price = new Calculators.type.Money(price);
	this.downPayment = new Calculators.type.Money(downPayment);
	this.salesTaxRate = new Calculators.type.Rate(salesTaxRate);
	this.fees = new Calculators.type.Money(fees);
	this.residualPercent = new Calculators.type.Rate(residualPercent);
	this.terms = new Number(terms);
	this.interestRate = new Calculators.type.Rate(interestRate);
	this.rateOfReturn = new Calculators.type.Rate(rateOfReturn);

	this.statements = [];
	
	this.getPrice = function() {
		return this.price;
	}
	
	this.getDownPayment = function() {
		return this.downPayment;
	}
	
	this.getSalesTaxRate = function() {
		return this.salesTaxRate;
	}
	
	this.getFees = function() {
		return this.fees;
	}
	
	this.getResidualPercent = function() {
		return this.residualPercent;
	}
	
	this.getNumberOfTerms = function() {
		return this.terms;
	}
	
	this.getInterestRate = function() {
		return this.interestRate;
	}
	
	this.getRateOfReturn = function() {
		return this.rateOfReturn;
	}
	
	this.getStatements = function() {
		return this.statements;
	}
	
	this.getPurchasePrice = function() {
		var purchasePrice = this.price.subtract(this.downPayment).getAmount() + 
			(this.price.getAmount() * this.salesTaxRate.getAmount()) +
			this.fees.getAmount();
		return purchasePrice;
	}
	
	this.getLoanPayment = function() {
		var purchasePrice = this.getPurchasePrice();
		var formula = new Calculators.math.Formulas();
		var pmt = formula.pmt(this.interestRate.monthly(), this.terms, (-1 * purchasePrice), 0);
		return new Calculators.type.Money(pmt);
	}
	
	this.getTotalLoanPayments = function(expiredTerms) {
		var total = expiredTerms * this.getLoanPayment().getAmount();
		return new Calculators.type.Money(total);
	}
	
	this.getInterestLostOnDownPayment = function(expiredTerms) {
		// -FV((investment rate of return/12),periods,0,down payment)-down payment;
		var formula = new Calculators.math.Formulas();
		var value = (-1 * formula.fv(this.rateOfReturn.monthly(), expiredTerms, 0, this.downPayment.getAmount()) -
			this.downPayment.getAmount());
		return new Calculators.type.Money(value);
	}

	this.getInterestLostPerPayment = function(expiredTerms) {
		var pmt = this.getLoanPayment();
		var payments = this.getTotalLoanPayments(expiredTerms);
		var formula = new Calculators.math.Formulas();
		var value = (-1 * formula.fv(this.rateOfReturn.monthly(), expiredTerms, pmt, 0) -
			payments);
		return new Calculators.type.Money(value);
	}
	
	this.getEndingMarketValue = function() {
		var value = (this.price.getAmount() * this.residualPercent.getAmount());
		return new Calculators.type.Money(value);
	}
	
	this.getLoanBalance = function(expiredTerms) {
		return this.statements[expiredTerms].getBalance();
	}

	this.calculate = function() {
		var pmt = this.getLoanPayment();
		this.statements[0] = new Calculators.loan.Statement(this.getPurchasePrice(), 0.00, 0.00);
		this.statements[0].payment = pmt;
		for (var i=1; i<this.terms; i++) {
			var lastBalance = this.statements[i-1].getBalance().getAmount();
			var interest = (lastBalance * this.interestRate.monthly());
			var principal = (pmt.getAmount() - interest);
			var balance = (lastBalance - principal);
			var stmt = new Calculators.loan.Statement(balance, interest, principal);
			stmt.payment = pmt;
			this.statements[i] = stmt;
		}
	}
	
	this.getInterestLostOnPayments = function(expiredTerms) {
		//  C5 (priceWithTax) = price - downpayment + (price * sales tax) + other fees
		//  C14 (loanPayment) = PMT(interest.monthly, loan periods, -C5, 0)
		//  B14 (totalLoanPayments) = terms * ROUND(PMT(interest.monthly, terms, -C5, 0), 2)
		// (-FV(ror.monthly,terms,0,downpayment)-downpayment)
		//  + (-FV(ror.monthly, terms, C14, 0) - B14)
		var formula = new Calculators.math.Formulas();
		var priceWithTax = this.price.getAmount() - this.downPayment.getAmount() + 
			(this.price.getAmount() * this.salesTaxRate.getAmount()) + this.fees.getAmount();
		var loanPayment = formula.pmt(this.interestRate.monthly(), this.terms, (-1 * priceWithTax), 0);
		var totalLoanPayments = expiredTerms * formula.pmt(this.interestRate.monthly(), this.terms, (-1 * priceWithTax), 0);
		
		//alert("formula.fv(" + this.rateOfReturn.monthly() + ", " + expiredTerms + ", 0, " + 
			//this.downPayment.getAmount() + ") - " + this.downPayment.getAmount());
		var downPaymentFutureValue = formula.fv(this.rateOfReturn.monthly(), expiredTerms, 0, this.downPayment.getAmount());
		var value1 = (-1 * downPaymentFutureValue - this.downPayment.getAmount());
		
		//alert("formula.fv(" + this.rateOfReturn.monthly() + ", " + expiredTerms + ", " + loanPayment + ", 0) - " + totalLoanPayments);
		var paymentsFutureValue = formula.fv(this.rateOfReturn.monthly(), expiredTerms, loanPayment, 0);
		//alert("paymentsFutureValue = " + paymentsFutureValue);
		var value2 = (-1 * paymentsFutureValue - totalLoanPayments);
		
		//alert("" + downPaymentFutureValue + " : " + paymentsFutureValue + " : " + value1 + " : " + value2 + " : " + (value1 + value2));
		return new Calculators.type.Money(value1 + value2);
		
		
		// -FV((rate of return/12),periods,loan payment,0)-total loan payments
		var pmt = this.getLoanPayment().getAmount();
		var totalPmt = this.getTotalLoanPayments(expiredTerms).getAmount();
		var futureValue = formula.fv(this.rateOfReturn.monthly(), expiredTerms, pmt, 0);
		//alert("" + this.rateOfReturn.getAmount() + " : " + futureValue);
		var value = (-1 * futureValue - totalPmt);
		//alert("" + pmt + ", " + totalPmt + " + ");
		return new Calculators.type.Money(value);
	}
	
	this.getNetCost = function(expiredTerms) {
		// down payment + total monthly payments + lost interest on payments + current loan balance - ending market value
		var value = this.getDownPayment().getAmount();
		value += this.getTotalLoanPayments(expiredTerms).getAmount();
		value += this.getInterestLostOnPayments(expiredTerms).getAmount();
		value += this.getLoanBalance(expiredTerms).getAmount();
		value -= this.getEndingMarketValue().getAmount();
		/*
		alert("" + this.getDownPayment().formatted() + " + " + this.getTotalLoanPayments(expiredTerms).formatted() + " + " + 
			this.getInterestLostOnPayments(expiredTerms).formatted() + " + " + 
			this.getLoanBalance(expiredTerms).formatted() + " - " + 
			this.getEndingMarketValue().formatted());
			*/
		return new Calculators.type.Money(value);
	}
	
	this.calculate();
}
