if (Calculators == undefined) {
	var Calculators = {};
}
if (Calculators.loan == undefined) {
	Calculators.loan = {};
}
Calculators.loan.CreditCardLoanSnapshot = function CreditCardLoanSnapshot(payment, interest, charges, balance) {
	this.payment = new Calculators.type.Money(payment);
	this.interest = new Calculators.type.Money(interest);
	this.charges = new Calculators.type.Money(charges);
	this.balance = new Calculators.type.Money(balance);

	this.getPayment = function(){
		return this.payment;
	}
	this.getInterest = function(){
		return this.interest;
	}
	this.getCharges = function(){
		return this.charges;
	}
	this.getBalance = function(){
		return this.balance;
	}
}

Calculators.loan.CreditCardLoan = function CreditCardLoan(rate, periods, presentValue, monthlyPayments, monthlyPurchases, annualFee, purchaseAmt1, purchaseMonth1, purchaseAmt2, purchaseMonth2){

	this.MONTHS = 12;
	
	this.rate = new Calculators.type.Rate(rate);
	this.periods = new Number(periods);
	this.presentValue = new Calculators.type.Money(presentValue);
	this.monthlyPayments = new Calculators.type.Money(monthlyPayments);
	this.monthlyPurchases = new Calculators.type.Money(monthlyPurchases);
	this.purchaseAmt1 = new Calculators.type.Money(purchaseAmt1);
	this.purchaseMonth1 = new Number(purchaseMonth1);
	this.purchaseAmt2 = new Calculators.type.Money(purchaseAmt2);
	this.purchaseMonth2 = new Number(purchaseMonth2);
	this.annualFee = new Calculators.type.Money(annualFee);
	this.statementsCurrent = [];
	this.currentMonthlyPayment = new Calculators.type.Money(0.00);
	this.statementsPayoffGoal = [];
	
	this.getInterest = function(balance, rate){
		return new Calculators.type.Money(rate.monthly() * balance).rounded();
	}
	
	this.getPrincipal = function(payment, interest){
		return new Calculators.type.Money(payment - interest).rounded();
	}
	
	this.getRemainingBalance = function(balance, principal){
		return new Calculators.type.Money(balance - principal).rounded();
	}
	
	this.getMonthlyNper = function(){
		return this.nper / this.MONTHS;
	}
	
	this.getPayoffMonthlyPayment = function(numberOfPeriods){
		// Go month by month keeping track of how much is owed / how many periods remain.
		// In the end, take an average of all the amounts
		var balance = this.presentValue.getAmount();
		
		var remainingMonths = numberOfPeriods;
		//var runningTotalOfPayments = (balance + interest)/ remainingMonths;
		//alert("runningTotalOfPayments = " + runningTotalOfPayments);
		var totalAnnualFees = this.annualFee.getAmount() *
			Math.floor((numberOfPeriods / 12) +
			(((numberOfPeriods % 12) != 0) ? 1 : 0));
		var totalAdditionalPurchases = this.purchaseAmt1.getAmount() + this.purchaseAmt2.getAmount() +
		(this.monthlyPurchases.getAmount() * numberOfPeriods);
		var totalToPayOff = balance + totalAnnualFees + totalAdditionalPurchases;
		var formula = new Calculators.math.Formulas();
		runningTotalOfPayments = (-1 * formula.pmt(this.rate.monthly(), remainingMonths, balance, totalToPayOff, true));
		
		for (var month = 1; month < numberOfPeriods + 1; ++month) {
		
			var charges = this.monthlyPurchases.getAmount();
			// Add any major purchases
			if ((this.purchaseMonth1) == month) {
				charges = charges + this.purchaseAmt1.getAmount();
			}
			if ((this.purchaseMonth2) == month) {
				charges = charges + this.purchaseAmt2.getAmount();
			}
			
			// Add annual fee
			if ((month > 0) && ((month % 12) == 0)) {
				balance = balance + this.annualFee.getAmount();
			}
			balance = balance + charges;
			
			// Calculate and add interest
			var interest = this.getInterest(balance, this.rate);
			balance = balance + interest;
			
			monthlyPayment = (-1 * formula.pmt(this.rate.monthly(), remainingMonths, balance, balance, true));
			// Calculate montly payment
			var totalAnnualFees = this.annualFee.getAmount() *
				Math.floor(((remainingMonths) / 12) +
				(((remainingMonths % 12) != 0) ? 1 : 0));
			var totalAdditionalPurchases = this.monthlyPurchases.getAmount() * (remainingMonths - 1);
			if (this.purchaseMonth1 > month) {
				totalAdditionalPurchases = totalAdditionalPurchases + this.purchaseAmt1.getAmount();
			}
			if (this.purchaseMonth2 > month) {
				totalAdditionalPurchases = totalAdditionalPurchases + this.purchaseAmt2.getAmount();
			}
			var totalToPayOff = balance + totalAnnualFees + totalAdditionalPurchases;
			//monthlyPayment = (-1 * formula.pmt(this.rate.monthly(), remainingMonths, balance, totalToPayOff, true));
			
			// If the calculated montly payment is larger than the balance, use the balance.
			if (monthlyPayment > balance) {
				monthlyPayment = balance;
			}
			balance = balance - monthlyPayment;
			
			runningTotalOfPayments = runningTotalOfPayments + monthlyPayment;
			remainingMonths--;
		}
		
		return new Calculators.type.Money(runningTotalOfPayments / (numberOfPeriods + 1));
		//var forumula = new Calculators.math.Formulas();
		//var value = formula.required_deposits(runningTotalOfPayments, this.rate.monthly(), numberOfPeriods);
		//return new Calculators.type.Money(value);
	}

	this.getPayoffMonthlyPaymentUsingFormulas = function(numberOfPeriods) {
		var formula = new Calculators.math.Formulas();

		// Get the pmt for the beginning balance
		var payment = (-1 * formula.pmt(this.rate.monthly(), numberOfPeriods, this.presentValue.getAmount(), 0, false));

		// Additional monthly purchases
		// additional charges + interest on additional charges per month
		if (this.monthlyPurchases.getAmount() > 0) {
			payment += (this.monthlyPurchases.getAmount() * (1 + this.rate.monthly()));
		}
		
		// Annual fees
		if (this.annualFee.getAmount() > 0) {
			payment += (this.annualFee.getAmount() / formula.MONTHLY);
		}
		
		// Major purchases
		if (this.purchaseAmt1.getAmount() > 0) {
			// Get an approximation of the monthly payment required for the purchase
			var majorPayment1 = this.purchaseAmt1.getAmount() / numberOfPeriods;
			// Calculate the amount paid that many times
			var months = this.purchaseMonth1 - 1;
			var totalPaid = (majorPayment1 * months);
			totalPaid = totalPaid * (1 - this.rate.monthly());
			
			// Calculate the initial beginning balance payment
			majorPayment1 = -1 * formula.pmt(this.rate.monthly(), numberOfPeriods, this.presentValue.getAmount(), 0, false);
			// Calculate the pro-rated major purchase payment
			majorPayment1 += (-1 * formula.pmt(this.rate.monthly(), (numberOfPeriods - months), (this.purchaseAmt1.getAmount() - totalPaid), 0, false));
			
			payment += majorPayment1;
		}

		if (this.purchaseAmt2.getAmount() > 0) {
			// Get an approximation of the monthly payment required for the purchase
			var majorPayment2 = this.purchaseAmt2.getAmount() / numberOfPeriods;
			// Calculate the amount paid that many times
			var months = this.purchaseMonth2 - 1;
			var totalPaid = (majorPayment2 * months);
			totalPaid = totalPaid * (1 - this.rate.monthly());
			
			// Calculate the initial beginning balance payment
			majorPayment2 = -1 * formula.pmt(this.rate.monthly(), numberOfPeriods, this.presentValue.getAmount(), 0, false);
			// Calculate the pro-rated major purchase payment
			majorPayment2 += (-1 * formula.pmt(this.rate.monthly(), (numberOfPeriods - months), (this.purchaseAmt2.getAmount() - totalPaid), 0, false));
			
			payment += majorPayment2;
		}
		
		return new Calculators.type.Money(payment);
	}
	
	
	this.calculateMonthlySnapshots = function(numberOfPeriods) {
		var balance = this.presentValue.getAmount();
		var interest = 0.0;
		var principal = 0.0;
		var paymentPerPeriod = this.getPayoffMonthlyPaymentUsingFormulas(numberOfPeriods);
		
		var statements = [];
		
		statements[0] = new Calculators.loan.CreditCardLoanSnapshot(0, 0, 0, balance);
		
		for (var month = 1; month < numberOfPeriods; ++month) {
		
			var charges = this.monthlyPurchases.getAmount();
			// Add any major purchases
			if ((this.purchaseMonth1) == month) {
				charges = charges + this.purchaseAmt1.getAmount();
			}
			if ((this.purchaseMonth2) == month) {
				charges = charges + this.purchaseAmt2.getAmount();
			}
			
			// Add annual fee
			if ((month > 0) && ((month % 12) == 0)) {
				balance = balance + this.annualFee.getAmount();
			}
			balance = balance + charges;
			
			var interest = this.getInterest(balance, this.rate);
			balance = balance + interest - paymentPerPeriod.getAmount();
			
			statements[month] = new Calculators.loan.CreditCardLoanSnapshot(paymentPerPeriod, interest, charges, balance);
		}
		return statements;
	}
	
	this.calculateMonthlySchedule = function(numberOfPeriods) {
		var balance = this.presentValue.getAmount();
		var interest = 0.0;
		var principal = 0.0;
		var paymentPerPeriod = 0.00;
		
		var total = null;
		if (numberOfPeriods == 0) {
			total = 121;
			paymentPerPeriod = this.monthlyPayments;
		}
		else {
			paymentPerPeriod = this.getPayoffMonthlyPaymentUsingFormulas(numberOfPeriods);

			total = numberOfPeriods + 1;
			//paymentPerPeriod = this.getPayoffMonthlyPayment(numberOfPeriods);
		}

		var statements = [];
		
		statements[0] = new Calculators.loan.CreditCardLoanSnapshot(0, 0, 0, balance);
		
		for (var month = 1; month < total; ++month) {
		
			var charges = this.monthlyPurchases.getAmount();
			// Add any major purchases
			if ((this.purchaseMonth1) == month) {
				charges = charges + this.purchaseAmt1.getAmount();
			}
			if ((this.purchaseMonth2) == month) {
				charges = charges + this.purchaseAmt2.getAmount();
			}
			
			// Add annual fee
			if ((month > 0) && ((month % 12) == 0)) {
				balance = balance + this.annualFee.getAmount();
			}
			balance = balance + charges;
			
			var interest = this.getInterest(balance, this.rate);
			balance = balance + interest - paymentPerPeriod.getAmount();
			
			statements[month] = new Calculators.loan.CreditCardLoanSnapshot(paymentPerPeriod, interest, charges, balance);
		}
		return statements;
	}
	
	this.statementsCurrent = this.calculateMonthlySchedule(0);
	
	this.getCurrentMonthlyStatement = function(month){
		var statements = null;
		statements = this.statementsCurrent[month];
		return statements;
	}
	
	this.getScenarioMonthlyStatement = function(numberOfPeriods, month){
		var statements = null;
		statements = this.calculateMonthlySnapshots(numberOfPeriods);
		return statements[month];
	}
	
	this.getMonthlyPayment = function(type){
		var payment = null;
		if (type == 0) {
			payment = this.monthlyPayments;
		}
		else {
			payment = this.payoffGoalMonthlyPayment;
		}
		return payment;
	}
	
	this.getCurrentStatements = function(){
		return this.statementsCurrent;
	}
	
	this.getInterestRate = function(){
		return this.rate;
	}
	
	this.getBalance = function(){
		return this.presentValue;
	}
	
	this.getPayment = function(){
		return this.monthlyPayments;
	}
	
	this.getMonthlyCharges = function(){
		return this.monthlyPurchases;
	}
	
	this.getAnnualFee = function() {
		return this.annualFee;
	}
	
	this.getPayoffGoal = function() {
		return this.periods;
	}
	
	this.getMajorPurchaseAmountOne = function() {
		return this.purchaseAmt1;
	}
	
	this.getMajorPurchaseMonthOne = function() {
		return this.purchaseMonth1;
	}
	
	this.getMajorPurchaseAmountTwo = function() {
		return this.purchaseAmt2;
	}
	
	this.getMajorPurchaseMonthTwo = function() {
		return this.purchaseMonth2;
	}
}
