//Copyright Sam & Andy Inc.
//Description: Mortgage Calculator
//Created By: Andy Prochazka
//Created On: 4/11/2003
//Last Changed On: 4/11/2003
//Version: v1.0

// Call the args_init () function to set up the args [] array:

(function(){
	var listPrice;
	var utilities;
	var propTax;
	var conFees;
	var downPay;
	var downPay_perc;
	var amort;
	var amort_years;
	var intRate;
	var payFreq;
	var date;
	
	var t_Mortgage = 0;
	var t_TotalMortgagePayment = 0;
	
	var principal;
	var interest;
	var lbl1;
	var principalPaid;
	var interestPaid;
	var lbl2;
	
	var graph1 = null;
	var graph2 = null;

	var config;

	//Fires on first load
	$.MortgageCalc = function(options){
	
		var mCalc = $.MortgageCalc;
		
		mCalc.defaultOptions = {
			region : "0"  //0 - Canada, 1 or anything else - USA
		}
		
		// initialize
		config = jQuery.extend({}, $.MortgageCalc.defaultOptions, options || {});

	// save values initialized on load
		listPrice = parseFloat($("#listPrice").val());
		utilities = parseFloat($("#utilities").val());
		propTax = parseFloat($("#propTax").val());
		conFees = parseFloat($("#conFees").val());
		downPay = parseFloat($("#downPay").val());
		downPay_perc = parseFloat($("#downPay_perc").val());
		amort = parseFloat($("#amort").val());
		amort_years = parseFloat($("#amort_years").val());
		intRate = parseFloat($("#intRate").val());
		payFreq = parseFloat($("#payFreq").val());

		//updateDownPayment();  //populate Down Payment input box with percentage specified in drop-down
		$("#downPay").val(toCurrency((parseFloat($("#downPay_perc").val()) * parseFloat($("#listPrice").val())))/100);
		//Unbind on page exit
		MortgageCalc_Calculate();
		$("#listPrice, #utilities, #propTax, #conFees").change(function(){
			MortgageCalc_Calculate();
		});
		$("#downPay").change(function(){updateDownPaymentPercent();});
		$("#downPay_perc").change(function(){updateDownPayment();});
		$("#amort, #intRate").change(function(){
			MortgageCalc_Calculate();
		});
		$("#amort_years").change(function(){
			$('#amort').val($("#amort_years").val());
			MortgageCalc_Calculate();
		});
		$("#payFreq").change(function(){MortgageCalc_Calculate();});
	}
	
	function MortgageCalc_RefreshForm(price, propertyTax){  //TO DO DO
		document.MortgageCalc.ListPrice.value = price;
		document.MortgageCalc.PropertyTax.value = propertyTax;
		document.MortgageCalc.DownPayment.value = 0.1*price;
		MortgageCalc_Calculate();
	}
	
	//--------------------------------Math & Formatting Utilities--------------------------------//
	function floor(number){
		return Math.floor(number*Math.pow(10,2))/Math.pow(10,2);
	}

	function toCurrency(value){
		if(typeof value == "number"){
			return new Number(value.toFixed(2));
		}else{
			return new Number(parseFloat(value).toFixed(2));
		}
	}
	//--------------------------------Math & Formatting Utilities--------------------------------//
	
	//--------------------Auto-Populate Functions for Down Payment fields---------------------//
	//Fires on change of drop-down
	function updateDownPayment(){
	// change downpayment value
		$("#downPay").val(toCurrency((parseFloat($("#downPay_perc").val()) * parseFloat($("#listPrice").val())))/100);
	// update form
		MortgageCalc_Calculate();
	}
	
	//Fires on change of input box
	function updateDownPaymentPercent(){
	// change list value
		var percent = parseFloat($("#downPay").val()) / parseFloat($("#listPrice").val())*100;
		percent = percent.toFixed(0);
		$("#downPay_perc").append("<option value=\"" + percent + "\">" + percent + "</option>").val(percent);
	// update form
		MortgageCalc_Calculate();
	}
	//--------------------Auto-Populate Functions for Down Payment fields---------------------//

	//--------------------------------Mortgage & Graph Calculations--------------------------------//
	//Calculates interest rate based on CMHC and amortization
	function MortgageCalc_insuranceRate(){
		var temp = $("#downPay").val()/$("#listPrice").val();
		var tempAmortization = $("#amort_years").val();
		var iRate = 0;
		
		if(config.region == "0"){ //Canada
			//Standard Insurance (CMHC) up to and including 25 years amortization.
			if( temp < 0.05 ){iRate = 0.0310;}else
			if( temp < 0.10 ){iRate = 0.0275;}else
			if( temp < 0.15 ){iRate = 0.0200;}else
			if( temp < 0.20 ){iRate = 0.0175;}else
			if( temp < 0.25 ){iRate = 0;}
			
			//Insurance surcharge based on mortgage over 25 years.
			if ( tempAmortization > 35 && iRate != 0)  { iRate += 0.0060 } else
			if ( tempAmortization > 30 && iRate != 0)  { iRate += 0.0040 } else
			if ( tempAmortization > 25 && iRate != 0)  { iRate += 0.0020 }
			
		}else{  //USA
			//Get Payments Per Year 			
			iRate = (parseFloat($("#intRate").val())/100) / 12;
		}
		return iRate;
	}
	/** Calculates the periodic mortgage payment for the specified conditions. 
	  * Formulas taken from: http://en.wikipedia.org/wiki/Amortization_calculator, though it appears that
	  * the periodic interest formula there is not correct. Below we are using a slightly modified version:
	  * 	i = (1+iann/compoundingPeriods)^compoundingPeriods/yearlyPayments - 1
	  * instead of
	  *	i = (1+iann/yearlyPayments)^compoundingPeriods/yearlyPayments - 1
	  *
	  * Results varified by: http://www.1stop-mortgagecalculator.com/mortgage-calculator-code-part3.htm
	  *
	  * @param yearlyPayments = number of payments to be made within a year
	  * @param annualInterestRate (in %)
	  * @param principal
	  * @param amortizationYears
	  */
	function setPeriodicPayment(yearlyPayments, annualInterestRate, principal, amortizationYears){

		// calculate periodic interest rate
		var periodicInterest;		// periodic interest
		var compoundingPeriods;		// compounding periods/yr (12 in US, 2 in Canada)
		
		// set compounding periods
		if(config.region == "0")
			compoundingPeriods = 2;
		else
			compoundingPeriods = 12;
		
		// get periodic interest
		config.periodicInterest = Math.pow((1 + annualInterestRate/compoundingPeriods), compoundingPeriods/yearlyPayments) - 1;
		
		// calculate and set periodic payment
		config.periodicPayment = (principal * config.periodicInterest)/(1 - Math.pow((1+config.periodicInterest), ((-1) * amortizationYears*yearlyPayments)));
	}

	function MortgageCalc_Calculate(){
		
		// determine insurance stuff
		var insuranceRate = MortgageCalc_insuranceRate();
		
		// get temporary values
		var temp_mortgageAmount = parseFloat($("#listPrice").val()) - parseFloat($("#downPay").val());
		var temp_insurance = temp_mortgageAmount * insuranceRate;
		var temp_PropertyTax = parseFloat($("#propTax").val()) / $("#payFreq").val();
		var temp_CondoFees = parseFloat($("#conFees").val());
		var temp_UtilityCosts = parseFloat($("#utilities").val());

		// set global parameters
		config.yearlyPayments = $("#payFreq").val();
		config.annualInterestRate = parseFloat($("#intRate").val())/100;
		config.amortizationYears = $('#amort').val();
		config.principal = temp_insurance + temp_mortgageAmount;

		// set the periodic payment
		setPeriodicPayment(config.yearlyPayments, config.annualInterestRate, config.principal, config.amortizationYears);

		// set the monthly equivalent payment
		this.t_TotalMortgagePayment = config.periodicPayment*config.yearlyPayments/12;
		var temp_TotalMonthly = temp_UtilityCosts + temp_CondoFees + temp_PropertyTax + this.t_TotalMortgagePayment;

		// prepare report
		$('#report_Price').html("$" + toCurrency($("#listPrice").val()));
		$('#report_MortgageAmount').html("$" + toCurrency(temp_mortgageAmount));
		$('#report_Insurance').html("$" + toCurrency(temp_insurance));
		$('#report_TotalMortgage').html("$" + toCurrency(config.principal));
		$('#report_InsuranceRate').html((insuranceRate*100).toFixed(2));

		$('#report_TotalMortgagePayment').html("$" + toCurrency(this.t_TotalMortgagePayment));
		$('#report_PropertyTax').html("$" + toCurrency(temp_PropertyTax));
		$('#report_CondoFees').html("$" + toCurrency(temp_CondoFees));
		$('#report_UtilityCosts').html("$" + toCurrency(temp_UtilityCosts));
		$('#report_TotalMonthly').html("$" + toCurrency(temp_TotalMonthly));
		
		MortgageCalc_graphs();
	}
	
	/** Generates the mortgage graphs
	  *
	  */
	function MortgageCalc_graphs(){
		// create value storage objects
		var principalPortion = new Array();
		var interestPortion = new Array();
		var principalAccumulated = new Array();
		var interestAccumulated = new Array();
		var xTicks = new Array();
		
		// create temporary variables
		var tempPrincipalPortion = 0;
		var tempInterestPortion = 0;
		var tempPrincipalAccumulated = 0;
		var tempInterestAccumulated = 0;

		// create an amortization table based on the periodic payment.
		var outstandingPrincipal = config.principal;
		var lastInterestAccululated = 0;
		var years = 0;
		for(var i = 0; i < config.yearlyPayments * config.amortizationYears; i++){
			if(config.amortizationYears > 25){
				if(i % (config.yearlyPayments*2) == 0){
					xTicks.push([i, years]);
					years +=2;
				}
			}else{
				if(i % config.yearlyPayments == 0){
					xTicks.push([i, years]);
					years++;
				}
			}

			interestPortion[i] = [i, outstandingPrincipal * config.periodicInterest];
			principalPortion[i] = [i, config.periodicPayment - interestPortion[i][1]];

			interestAccumulated[i] = [i, interestPortion[i][1] + tempInterestAccumulated];
			tempInterestAccumulated = interestAccumulated[i][1];

			principalAccumulated[i] = [i, principalPortion[i][1] + tempPrincipalAccumulated];
			tempPrincipalAccumulated = principalAccumulated[i][1];

			outstandingPrincipal = outstandingPrincipal - principalPortion[i][1];
		}
		
		// add the final xTick
		xTicks.push([config.yearlyPayments * config.amortizationYears-1, years]);


		$("#gLeg1").empty();
		$("#gLeg2").empty();

		if(graph1 != null){
			graph1 = null;
		}

		//place arrays into flot object and plot graph - first graph
		graph1 = $.plot($("#int_pri"), [
        		{
		        	data: interestPortion,
		        	label: "Interest",
		        	lines: { show: true }
        		},
        		{
		        	data: principalPortion,
		        	label: "Principal",
		        	lines: { show: true }
        		}
		],
		{
			xaxis: {
				ticks: xTicks
			},
			yaxis: {
				tickFormatter: function(val, axis){
					return $.formatAsCurrency(val);
				}
			},
			legend: {
				container: $("#gLeg1"),
				//position:"ne",
				backgroundOpacity:0.4
			}
		});


		if(graph2 != null){
			graph2 = null;
		}


		//place arrays into flot object and plot graph - first graph
		graph = $.plot($("#int_pri_acc"), [
        		{
		        	data: interestAccumulated,
		        	label: "Interest",
		        	lines: { show: true }
        		},
        		{
		        	data: principalAccumulated,
		        	label: "Principal",
		        	lines: { show: true }
        		}
		],
		{
			xaxis: {
				ticks: xTicks
			},
			yaxis: {
				tickFormatter: function(val, axis){
					return $.formatAsCurrency(val, false);
				}
			},
        		legend: {
					container: $("#gLeg2"),
					//position:"ne",
         			backgroundOpacity:0.4
        		}
       		});
       	}
})();