var Calculators = Calculators || {};
Calculators.planning = Calculators.planning || {};

Calculators.planning.BecomeMillionaireSnapshot = function BecomeMillionaireSnapshot(period, periodInvestment, periodYield, accumulatedSavings) {
	this.period = new Number(period);
	this.periodInvestment = new Calculators.type.Money(periodInvestment);
	this.periodYield = new Calculators.type.Money(periodYield);
	this.accumulatedSavings = new Calculators.type.Money(accumulatedSavings);
	
	this.getPeriodNumber = function() {
		return this.period;
	}
	
	this.getPeriodInvestment = function() {
		return this.periodInvestment;
	}

	this.getPeriodYield = function() {
		return this.periodYield;
	}

	this.getAccumulatedSavings = function() {
		return this.accumulatedSavings;
	}
	
	this.add = function(becomeMillionaireSnapshot) {
		this.periodInvestment = new Calculators.type.Money(this.periodInvestment.getAmount() + becomeMillionaireSnapshot.getPeriodInvestment().getAmount());
		this.periodYield = new Calculators.type.Money(this.periodYield.getAmount() + becomeMillionaireSnapshot.getPeriodYield().getAmount());
		this.accumulatedSavings = becomeMillionaireSnapshot.getAccumulatedSavings();
	}
}

Calculators.planning.BecomeMillionaire = function BecomeMillionaire(initialInvestment, monthlyInvestment, annualRate, yearsDesired) {
	this.initialInvestment = new Calculators.type.Money(initialInvestment);
	this.monthlyInvestment = new Calculators.type.Money(monthlyInvestment);	
	this.annualRate = new Calculators.type.Rate(annualRate);
	this.yearsDesired = new Number(yearsDesired);
	this.monthlySchedule = [];
	this.yearlySchedule = [];
	
	this.getInitialInvestment = function() {
		return this.initialInvestment;
	}
	
	this.getMonthlyInvestment = function() {
		return this.monthlyInvestment;
	}
	
	this.getAnnualRate = function() {
		return this.annualRate;
	}
	
	this.getYearsDesired = function() {
		return this.yearsDesired;
	}
	
	this.getPeriodsToBecomeMillionaire = function() {
		var formula = new Calculators.math.Formulas();
		var periods = formula.nper(this.annualRate.getAmount() / 12, -1 * this.monthlyInvestment.getAmount(), -1 * this.initialInvestment.getAmount(), 1000000);
		return Math.ceil(periods);
	}
	
	this.getYearsToBecomeMillionaire = function(){
		var formula = new Calculators.math.Formulas();
		var years = this.getPeriodsToBecomeMillionaire()/12;
		return (Math.round(years * 10) / 10);
	}
	
	this.getAmountAtDesiredYears = function() {
		var formula = new Calculators.math.Formulas();
		var amount = formula.fv(this.annualRate.getAmount() / 12, this.yearsDesired * 12, -1 * this.monthlyInvestment.getAmount(), -1 * this.initialInvestment.getAmount());
		return new Calculators.type.Money(amount);
	}
	
	this.getRecommendedInitialInvestment = function() {
		var formula = new Calculators.math.Formulas();
		var amount = formula.pv(this.annualRate.getAmount() / 12, this.yearsDesired * 12, 0, (1000000 - this.getAmountAtDesiredYears().getAmount())) + this.initialInvestment.getAmount();
		return new Calculators.type.Money(amount);
	}	
	
	this.getRecommendedMonthlyInvestment = function() {
		var formula = new Calculators.math.Formulas();
		var amount = -1 * formula.pmt(this.annualRate.getAmount() / 12, this.yearsDesired * 12, 0, (1000000 - this.getAmountAtDesiredYears().getAmount())) + this.monthlyInvestment.getAmount();		
		return new Calculators.type.Money(amount);
	}
	
	this.getRecommendedRate = function() {
		var formula = new Calculators.math.Formulas();
		var rate = formula.rate(this.yearsDesired * 12, this.monthlyInvestment.getAmount(), this.initialInvestment.getAmount(), 1000000) * 12;
		return new Calculators.type.Rate(rate);		
	}
	
	this.calculateSchedules = function() {
		var tmpMonthlySnapshot;
		for(var i = 0; i <= this.getPeriodsToBecomeMillionaire(); i++) {
			if (i == 0) {
				tmpMonthlySnapshot = new Calculators.planning.BecomeMillionaireSnapshot(i, 0, 0, this.initialInvestment);						
			} else {
				var periodYield = this.monthlySchedule[i-1].getAccumulatedSavings().getAmount() * (this.annualRate.getAmount() / 12);
				tmpMonthlySnapshot = new Calculators.planning.BecomeMillionaireSnapshot(i, this.monthlyInvestment, periodYield , this.monthlySchedule[i-1].getAccumulatedSavings().getAmount() + periodYield + this.monthlyInvestment.getAmount());
				if(!this.yearlySchedule[Math.ceil(i/12) - 1]) {
					// create new year
					this.yearlySchedule[Math.ceil(i/12) - 1] = new Calculators.planning.BecomeMillionaireSnapshot(Math.floor(i/12) + 1, tmpMonthlySnapshot.getPeriodInvestment(), tmpMonthlySnapshot.getPeriodYield(), tmpMonthlySnapshot.getAccumulatedSavings());
				} else {
					this.yearlySchedule[Math.ceil(i/12) - 1].add(tmpMonthlySnapshot);
				}				
			}
			this.monthlySchedule[i] = tmpMonthlySnapshot;
		}
	}
	
	this.getMonthlySchedule = function() {
		if(this.monthlySchedule.length == 0)
			this.calculateSchedules();
		return this.monthlySchedule;
	}
	
	this.getYearlySchedule = function() {
		if(this.yearlySchedule.length == 0)
			this.calculateSchedules();
		return this.yearlySchedule;
	}
}

