/* JS for http://cgi.money.cnn.com/tools/mortgagecalc/
   MortgageCalc.init() is called first
   MortgageCalc.calculatePayment() is called when the form is submitted

   optional query string parameters = price, down, intrate, taxes, insurance
	ex. ?price=23.43&intrate=2.5&taxes=4&insurance=10&down=2
    -Results are automatically output if the price and intrate are given
*/
var MortgageCalc = {

	form : document.frmMortgage,
	loan_life : 30,
	frequency : 12,
	avg_tax_rate : 0.015,
	avg_pmi : 80,
	pmi_threshold : 0.20,
	periods : null, 

	calculatePayment: function() {
		var good, payment, taxins, pmi, total, dp_ratio;

		good = this.verifyInputs( this.form );
		if ( !good ) return;

		payment = this.getMortgagePayment();
		this.form.loanpayment.value = this.addThousandsCommasDecimal( payment );

		taxins = this.getPeriodicTaxesInsurance();
		this.form.taxinsurance.value = this.addThousandsCommasDecimal( taxins );

		// calculate the down payment to home price ratio and see if PMI kicks in
		dp_ratio = this.form.down.value / this.form.price.value;
		if ( dp_ratio < this.pmi_threshold ) {
			this.form.pmi.value = this.avg_pmi;
			pmi = this.avg_pmi;
		} else {
			this.form.pmi.value = 0;
			pmi = 0;
		}

		total = payment + taxins + pmi;
		this.form.total.value = this.addThousandsCommasDecimal( total );
	},

	getMortgagePayment : function() {
		var intrate, period_intrate, disc_factor, payment, principal;

		intrate = parseFloat( this.form.intrate.value );
		principal = this.form.price.value - this.form.down.value;
		period_intrate = intrate / (this.frequency * 100);
		disc_factor = ( Math.pow( 1 + period_intrate, this.periods ) - 1 )
									/
			( period_intrate *  Math.pow( 1 + period_intrate, this.periods ) )
		;
		payment = principal / disc_factor;
		return payment;
	},

	getPeriodicTaxesInsurance :function() {
		var str_taxes, str_ins, yearly_taxes, yearly_ins, periodic_txins;

		str_taxes = this.form.taxes.value;
		str_ins = this.form.insurance.value;
		if ( str_taxes == "" ) {
			yearly_taxes = 0;
		} else {
			yearly_taxes = parseFloat( str_taxes );
		}
		if ( str_ins == "" ) {
			yearly_ins = 0;
		} else {
			yearly_ins = parseFloat( str_ins );
		}
		periodic_txins = (yearly_taxes + yearly_ins) / this.frequency;

		return periodic_txins;
	},

	addThousandsCommas: function( number ){
		var T='', S = String(number), L = S.length-1, C, j;

		for ( j=0; j<=L; j++ ) {
			T += C = S.charAt(j);
			if ( (j<L) && ((L-j)%3 == 0) && (C!='-') )
				T+=',';
		}
		return T;
	},
	addThousandsCommasDecimal : function( number )
	{
		var number, whole, decimal, dec_str, formatted_number;

		if ( isNaN( number ) ) return number;

		// get the whole part
		whole = Math.floor( number );

		// get the decimal up to two places and remove "0." in the beginning
		decimal = number - whole;
		if ( decimal != 0 )
		{
			decimal = this.round2( decimal );
			dec_str = String( decimal );
			dec_str = "." + dec_str.substr( dec_str.indexOf(".") + 1 );
		} else {
			dec_str = "";
		}

		// merge the commas-formatted whole with the decimal
		formatted_number = this.addThousandsCommas( whole ) + dec_str;

		return formatted_number;
	},

	round2 : function( number )
	{
		if ( isNaN( number ) ) return number;
		return Math.round(number * 100) / 100;
	},

	process_price : function()
	{
		var price, tax;

		this.process_input( this.form.price );
		price = parseFloat( this.form.price.value );
		if ( isNaN( price ) ) return;

		// calculate the default tax for the home
		tax = price * this.avg_tax_rate;
		this.form.taxes.value = this.round2( tax );
	},

	process_input : function( field )
	{
		this.strip_number( field );
	},

	strip_number : function ( field )
	{
		var original_number = field.value;
		var stripped_number = "";
		var parsed_number;

		for ( var i=0; i<original_number.length; i++ )
		{
			var digit = original_number.charAt(i);
			if ( digit == '.' || !( digit < "0" || digit > "9" ) )
			{
				stripped_number = stripped_number + digit;
			}
		}

		// this will clean up more than one decimals
		if ( stripped_number )
		{
			parsed_number = parseFloat( stripped_number );
			if ( isNaN( parsed_number ) )
				field.value = "";
			else
				field.value = parsed_number;
		}
		else {
			field.value = "";
		}
	},

	clearFields : function() {
		this.form.price.value = "";
		this.form.down.value = "";
		this.form.intrate.value = "";
		this.form.taxes.value = "";
		this.form.insurance.value = "";
		this.form.loanpayment.value = "";
		this.form.taxinsurance.value = "";
		this.form.pmi.value = "";
		this.form.total.value = "";
	},

	parseQueryString : function(param) {
	  param = param.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	  var regexS = "[\\?&]"+param+"=([^&#]*)";
	  var regex = new RegExp( regexS );
	  var results = regex.exec( window.location.href );
	  if( results == null )
		return "";
	  else
		return results[1];
	},

	verifyInputs : function() {
		var val;

		val = this.form.price.value;
		if ( val == null || val == "" || isNaN( val ) || val <= 0 ) {
			alert( "You have to enter a valid, positive price for the home!" );
			this.form.price.focus();
			return false;
		}

		val = this.form.intrate.value;
		if ( val == null || val == "" || isNaN( val ) || val <= 0 ) {
			alert( "You have to enter a valid, positive interest rate!" );
			this.form.intrate.focus();
			return false;
		}

		return true;
	},

	prePopulate : function() {
		/*Fill in form values from the Query String*/
		var price = parseFloat(this.parseQueryString('price'));
		var down = parseFloat(this.parseQueryString('down'));
		var intrate = parseFloat(this.parseQueryString('intrate'));
		var taxes = parseFloat(this.parseQueryString('taxes'));
		var insurance = parseFloat(this.parseQueryString('insurance'));

		if( price != '' && price != null && isNaN(price) == false && price > 0 ) {
			this.form.price.value = price;
			this.process_price();
		}
		if( down != '' && down != null && isNaN(down) == false )
			this.form.down.value = down;
		if( intrate != '' && intrate != null && isNaN(intrate) == false && intrate > 0) 
			this.form.intrate.value = intrate;
		if( taxes != '' && taxes != null && isNaN(taxes) ==false )
			this.form.taxes.value = taxes;
		if( insurance != '' && insurance != null && isNaN(insurance) == false )
			this.form.insurance.value = insurance;	
		/*Run the Calculator*/
		if( this.form.price.value != '' && this.form.intrate.value != '')
			this.calculatePayment();
	},

	init : function() {
		this.periods = this.loan_life * this.frequency;
		this.prePopulate();
	}
}
try{ MortgageCalc.init();}catch(e){}
