/* Calculator Object
	filename: mortgageCalc.js
		08/09/2007		initially coded - brad street

 This script uses the mootools framework for various functions, and at a minimum requires:
	Core.js
	Class.js
	Class.Extras.js
	Number.js
*/

var MortgageCalculator = new Class({
	initialize: function(loanAmount,apr,yrs,downPayment,upfrontPoints,discountPoints){
		var min_APR = 0.00;						// do NOT set lower than 0
		var max_APR = 9.00;						
		var min_downPayment = 0.00;				// do NOT set lower than 0
												// max down payment is set to amount of loan
		var min_upfrontPoints = 0.00;			// do NOT set lower than 0
		var max_upfrontPoints = 9.00;
		var min_discountPoints = 0.00;			// do NOT set lower than 0
												// max discount points is set to apr
		
		// Setup default values							**  Properties of this.  **
		this.loanAmount = 200000.00;			// loanAmount = 			default amount of loan used in loan calculations
												// originalLoanAmount =		original amount of this loan
		this.apr = 7.00;						// apr = 					default annual percentage rate used in loan calculations
												// originalAPR	=			original APR of loan
		this.termYears = 30;					// termYears =				default term of loan in years
												// termMonths = 			term of loan in months
		this.downPayment = 0.00;				// downPayment = 			amount of down payment
		this.upfrontPoints = 0.00;				// upfrontPoints = 			number of points to be paid at start of loan
		this.discountPoints = 0.00;				// discountPoints = 		number of points discounted from APR for length of loan
												// upfrontPointsCost =		total cost of discount points at start of loan
												// discountPointsSavings = 	total savings by discounting points
												// paymentTotal = 			total of all payments (principal & interest)
												// paymentMonthly =			monthly payment amount
												// interestTotal =			total of interest payments
												// interestMonthly =		monthly interest rate
												// interestFactor =			factor used to compute monthly payments
												
												/*        **     Methods of this.    **
												   getInerestFactor(term of loan in months, monthly interest)
												   		private function called by this.calculate()
												   		returns : monthly factor that, when divided into loan amount, will tell monthly payment
												   		
												   	calculate()
												   		public function - given the properties of the calculator object, calculates totals
												   		returns: object containing the totals and such
												 */
		
		//Do some validation and set the properties
		if(loanAmount != undefined)
			{ this.loanAmount = loanAmount.toFloat().limit(1000,50000000).toFixed(0); }
		this.originalLoanAmount = this.loanAmount;
		
		if(apr != undefined)
			{ this.apr = apr.toFloat().limit(min_APR,max_APR).toFixed(4); }
		this.originalAPR = this.apr;

		if(yrs != undefined && (yrs == 15) || (yrs == 30))
			{ this.termYears = yrs.toInt(); }
		this.termMonths = this.termYears * 12;
		
		if(downPayment != undefined)
			{ this.downPayment = downPayment.toFloat().limit(0,this.loanAmount).toFixed(0); }

		if(this.downPayment > 0)
		{
			this.loanAmount = (this.loanAmount - this.downPayment).toFixed(0);
		}
		
		if(upfrontPoints != undefined)
			{ this.upfrontPoints = upfrontPoints.toFloat().limit(min_upfrontPoints,max_upfrontPoints).round(4).toFixed(4); }
		if(this.upfrontPoints > 0 )
		{
			this.upfrontPointsCost = (this.upfrontPoints / 100) * this.loanAmount;
			this.upfrontPointsCost = this.upfrontPointsCost.toFixed(0);
		}
		else
		{ this.upfrontPointsCost = 0.00; }

		if(discountPoints != undefined)
			{ this.discountPoints = discountPoints.toFloat().limit(min_discountPoints,this.apr).toFixed(4); }
		if(this.discountPoints > 0 && (this.discountPoints <= this.apr))
			{ this.apr = (this.apr - this.discountPoints).toFixed(4); }
		this.interestMonthly = this.apr / 1200;
		this.interestTotal = 0;
		this.interestFactor = 0;
		this.paymentMonthly = 0;
		this.paymentTotal = 0;
		this.discountPointsSavings = 0;
	},

	getInterestFactor: function(termmonths,monthlyinterest)
	{
		var factor = 0;
		var base_rate = 1 + monthlyinterest;
		var denominator = base_rate;
		for (var i=0; i < termmonths; i++)
		{
			factor += (1 / denominator);
			denominator *= base_rate;
	    }
	    return factor;
	},

	calculate: function()
	{
		this.interestFactor = this.getInterestFactor(this.termMonths,this.interestMonthly);
		
		if(this.loanAmount > 0)
		{
			this.paymentMonthly = (this.loanAmount / this.interestFactor).toFixed(0);
		}
		else
		{
			this.paymentMonthly = 0.00;
		}
		
		this.paymentTotal = (this.paymentMonthly * this.termMonths).toFixed(0);
		
		if (this.paymentTotal == 0)
		{
			this.interestTotal = 0.00;
		}
		else
		{
			this.interestTotal = (this.paymentTotal - this.loanAmount).toFixed(0);
		}
		
		if(this.discountPoints > 0 && this.discountPoints <= this.originalAPR)
		{
			var temp = this.getInterestFactor(this.termMonths,(this.discountPoints / 1200));
			this.discountPointsSavings = ((this.loanAmount / temp).round(2).toFixed(2) * this.termMonths - this.loanAmount).toFixed(0);
		}
		else
		{
			this.discountPointsSavings = 0.00;
		}
	}
});

/*  Sample usage:

var cal = new MortgageCalculator(225000,18,30,2000,2,1);
calc.calculate();
alert('Total of all payments: $'+calc.paymentTotal+'\nTotal Interest: $'+calc.interestTotal+'\nLoan Amount: $'+calc.loanAmount+'\nOriginal Loan: $'+calc.originalLoanAmount+'\nDown Payment: $'+calc.downPayment);

Result:
	Total of all payments: $589064.40 
	Total Interest: $366064.4 
	Loan Amount: $223000 
	Original Loan: $225000.00 
	Down Payment: $2000.00
*/

//var calc = new MortgageCalculator(225000,7,30,0,2,7);
//calc.calculate();
//alert('Total of all payments: $'+calc.paymentTotal+'\nTotal Interest: $'+calc.interestTotal+'\nLoan Amount: $'+calc.loanAmount+'\nOriginal Loan: $'+calc.originalLoanAmount+
//'\nDown Payment: $'+calc.downPayment+'\n\nOriginal APR: '+calc.originalAPR+'\nDiscount Points: '+calc.discountPoints+'\nAPR: '+calc.apr+'\n\n Upfront Points: '+calc.upfrontPoints+
//'\nCost of Upfront Points: '+calc.upfrontPointsCost+'\n\nDiscount Points Savings: '+calc.discountPointsSavings+'\n\nMonthly Payment: $'+calc.paymentMonthly);