/* MortGadget: calculator.js - arithmetic handled by calculate_all() */

var calc_flds = new Array('loan_amount','sale_price','dp_percent','dp_amount',
	'interest_percent','interest_percent2','interest_percent3','percent2_start_year',
	'percent3_start_year','fixed_percent','property_tax_percent','pmi_percent',
	'year_term','loan_life','tax_rate','home_insurance_percent',
	'floating_on','closing');


// fires on every incremental change of the active field
function updateslide(offsetFromStart) { 
	
	var myStartVal = 2;
	var myScale = .1;
	
	lastus = this.id.lastIndexOf('_');
	field_name = this.id.substring(0,lastus);
	
	formatWhole = false;
	if (field_name == 'year_term' || field_name == 'loan_life' || field_name == 'percent2_start_year' || field_name == 'percent3_start_year') {
		myScale = 1;
		formatWhole = true;
	}
	format_dollar = false;
	
	if (field_name == 'sale_price') {
		myScale = 10000;
		format_dollar = true;
	}
	if (field_name == 'closing') {
		myScale = 100;
		format_dollar = true;
	}
	if (field_name == 'dp_percent' || field_name == 'tax_rate') {
		myScale = 1;
	}
	
	// determine the actual value from the offset 
	var newVal = (offsetFromStart + myStartVal) * myScale;
	
	if (formatWhole) {
		newVal = newVal;
	} else {
		newVal = newVal.toFixed(2);
	}
	
	if (format_dollar) {			
    	$(field_name).value = formatNumber(newVal,',','.',true,0);
    } else {
    	$(field_name).value = newVal;
    }
   
}	
	
	
function formatCurrency(n) {
	return '$' + formatNumber(n,',','.',true,2);
}

// round parameter can be negative for decimal, precision has to be postive
function formatNumber(n, num_grp_sep, dec_sep, round, precision) {
  if(typeof num_grp_sep == 'undefined' || typeof dec_sep == 'undefined') return n;
  n = n.toString();
  if(n.split) n = n.split('.');
  else return n;

  if(n.length > 2) return n.join('.'); // that's not a num!
  // round
  if(typeof round != 'undefined') {
    if(round > 0 && n.length > 1) { // round to decimal
      n[1] = parseFloat('0.' + n[1]);
      n[1] = Math.round(n[1] * Math.pow(10, round)) / Math.pow(10, round);
      n[1] = n[1].toString().split('.')[1];
    }
    if(round <= 0) { // round to whole number
      n[0] = Math.round(parseInt(n[0]) * Math.pow(10, round)) / Math.pow(10, round);
      n[1] = '';
    }
  }

  if(typeof precision != 'undefined' && precision >= 0) {
    if(n.length > 1 && typeof n[1] != 'undefined') n[1] = n[1].substring(0, precision); // cut off precision
	else n[1] = '';
    if(n[1].length < precision) {
      for(var wp = n[1].length; wp < precision; wp++) n[1] += '0';
    }
  }

  regex = /(\d+)(\d{3})/;
  while(regex.test(n[0])) n[0] = n[0].replace(regex, '$1' + num_grp_sep + '$2');
  return n[0] + (n.length > 1 && n[1] != '' ? dec_sep + n[1] : '');
}

// format and unformat numbers
function unformatNumber(n, num_grp_sep, dec_sep) {
	var x=unformatNumberNoParse(n, num_grp_sep, dec_sep);
	x=x.toString();
	if(x.length > 0) {
		return parseFloat(x);
	}
	return '';
}

function unformatNumberNoParse(n, num_grp_sep, dec_sep) {
	if(typeof num_grp_sep == 'undefined' || typeof dec_sep == 'undefined') return n;
	n = n.toString();
	if(n.length > 0) {
		n = n.replace(new RegExp(RegExp.escape(num_grp_sep), 'g'), '').replace(new RegExp(RegExp.escape(dec_sep)), '.');
		return n;
	}
	return '';
}
// escapes regular expression characters
RegExp.escape = function(text) { // http://simon.incutio.com/archive/2006/01/20/escape
  if (!arguments.callee.sRE) {
    var specials = ['/', '.', '*', '+', '?', '|','(', ')', '[', ']', '{', '}', '\\'];
    arguments.callee.sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
  }
  return text.replace(arguments.callee.sRE, '\\$1');
}

function calc_dp(elem) {
	percent_fld = $('dp_percent');
	amount_fld = $('dp_amount');
	sale_fld =  $('sale_price');
	loan_fld =  $('loan_amount');
	
	if (elem.name == 'dp_amount') {
		percent = unformatNumber(amount_fld.value,',','.') / unformatNumber(sale_fld.value,',','.');
		percent_fld.value = percent.toFixed(2) * 100;
	} else {
		amount = unformatNumber(sale_fld.value,','	,'.') * percent_fld.value / 100;
		amount_fld.value = formatNumber(amount.toFixed(2),',','.',true,0);
	}
	n = unformatNumber(sale_fld.value,',','.') - unformatNumber(amount_fld.value,','	,'.');
	loan_fld.value = formatNumber(n,',','.',true,0);
}

function updateStartYear(elem) {
	year2 = $("percent2_start_year");
	year3 = $("percent3_start_year");	
	
	
	if (elem.id == "percent2_start_year") {
		if (year2.value > year3.value ) {
			year3.value = year2.value + 1
		} 
	} else {
		if (year2.value < year3.value ) {
			year2.value = year3.value - 1
		}
	}
}

// This function does the actual mortgage calculations
// by plotting a PVIFA (Present Value Interest Factor of Annuity)
// table...
function get_interest_factor(year_term, monthly_interest_rate) {
	 
	var i;
	factor      = 0;
	base_rate   = 1 + monthly_interest_rate;
	denominator = base_rate;
	for (i=0; i < (year_term * 12); i++) {
		factor += (1 / denominator);
		denominator *= base_rate;
	}
	return factor;
}

function calculate_all() {

	calc_dp($('dp_percent'));

	loan_amount				= $('loan_amount').value;
	sale_price				= $('sale_price').value;
	dp_percent				= $('dp_percent').value;
	dp_amount				= $('dp_amount').value;
	closing					= $('closing').value;
	interest_percent		= $('interest_percent').value;
	interest_percent2       = $('interest_percent2').value;
	interest_percent3       = $('interest_percent3').value;
	percent2_start_year    	= $('percent2_start_year').value;
	percent3_start_year    	= $('percent3_start_year').value;
	fixed_percent 			= $('fixed_percent').value;
	property_tax_percent	= $('property_tax_percent').value;
	pmi_percent				= $('pmi_percent').value;	
	year_term				= $('year_term').value;
	loan_life				= $('loan_life').value;
	tax_rate				= $('tax_rate').value / 100;
	home_insurance_rate		= $('home_insurance_percent').value / 100;
	
	
	floating_on				= $('floating_on').checked ? 1:0;
	
	loan_amount				= unformatNumber(loan_amount,',','.');
	sale_price				= unformatNumber(sale_price,',','.');
	interest_percent		= unformatNumber(interest_percent,',','.');
	year_term				= unformatNumber(year_term,',','.');
	property_tax_percent	= unformatNumber(property_tax_percent,',','.');
	pmi_percent				= unformatNumber(pmi_percent,',','.');
	dp_amount				= unformatNumber(dp_amount,',','.');
	closing					= unformatNumber(closing,',','.');
		
	if (year_term < 1) {
		year_term = 1;
	}
	
	if(loan_life > year_term) {
		loan_life = year_term;
	}
	
	year_term2 = year_term - percent2_start_year + 1;
	year_term3 = year_term - percent3_start_year + 1;
	
	month_term               = year_term * 12;
	biweekly_term            = year_term * 26;
	
	
	month_life               = loan_life * 12;
	biweekly_life            = loan_life * 26;
	
	interest_rate     		= interest_percent / 100;
	interest_rate_fixed 	= fixed_percent / 100;
	pmi_rate          		= pmi_percent / 100;
	pmi                     = pmi_rate * loan_amount;
	monthly_pmi             = pmi / 12;
	biweekly_pmi			= pmi / 26;
	property_tax_rate 		= property_tax_percent / 100;
	property_tax			= property_tax_rate * sale_price;
	monthly_property_tax	= property_tax / 12;
	biweekly_property_tax	= property_tax / 26;
	monthly_interest_rate	= interest_rate / 12;
	monthly_interest_rate_fixed = interest_rate_fixed /12;
	biweekly_interest_rate	= interest_rate / 26;
	financing_price			= loan_amount
	monthly_factor			= get_interest_factor(year_term, monthly_interest_rate);
	monthly_payment			= financing_price / monthly_factor;
	biweekly_payment		= monthly_payment  / 2;
	
	interest_rate2     = interest_percent2 / 100;
	interest_rate3     = interest_percent3 / 100;
	
	monthly_interest_rate2    = interest_rate2 / 12;
	monthly_interest_rate3    = interest_rate3 / 12;
	
	monthly_factor2           = get_interest_factor(year_term2, monthly_interest_rate2);
	monthly_factor3           = get_interest_factor(year_term3, monthly_interest_rate3);
	
	
	monthly_payment_all = monthly_payment + monthly_property_tax + monthly_pmi;
	biweekly_payment_all = biweekly_payment + biweekly_property_tax + biweekly_pmi;
	
	
	total_closing = dp_amount + closing;
	
	
	//PMI phases out at 20 or 22 percent
	monthly_payment_all_nonpmi = monthly_payment + monthly_property_tax;
	biweekly_payment_all_nonpmi = biweekly_payment + biweekly_property_tax;
	
	
	monthly_interest_rate_arr = new Array();
	
	r_balance = loan_amount;
	r_interest = 0;
	r_principal = 0;
	
	biweekly_term = monthly_term = 0;
	month_term_pmi = -1; // total months paying PMI
	
	for(i=1; i<=loan_life; i++) 	{
		rt_Interest = 0;
		rt_principal = 0;
	
		for(y=1; y<=26; y+=1)
		{
			r_interest  = r_balance * biweekly_interest_rate;
			r_principal = biweekly_payment - r_interest;
			r_balance = r_balance - r_principal;
				
			rt_principal += r_principal;
			rt_Interest += r_interest;
				
			biweekly_term += 1;
	
		}
	
		r_balance = Math.round(r_balance);
		if(r_balance <= 0)	{
			r_balance = 0;
			break;
		}
	
	}
	
	
	total_biweekly_interest = rt_Interest;
	
	
	r_balance = loan_amount;
	r_interest = 0;
	r_principal = 0;
	month_term_tmp=-1;
	
	for(i=1; i<=loan_life; i+=1) 	{
	
		for(y=1; y<=12; y+=1) 	{
					
			r_interest  = r_balance * monthly_interest_rate;
			r_principal = monthly_payment - r_interest;
			r_balance = r_balance - r_principal;
				
			rt_principal += r_principal;
			rt_Interest += r_interest;
				
			
			month_term_tmp += 1;
			
			// for PMI cancelation
			if ((r_balance / sale_price) < .78 && month_term_pmi == -1) {
				month_term_pmi = month_term_tmp;
			}
			//echo "<br>LTV: " . (r_balance / loan_amount);
			
			p = i * y;
			cur_monthly_interest_rate = monthly_interest_rate;
			if (i < percent2_start_year && floating_on) 
				cur_monthly_interest_rate = monthly_interest_rate;
			
			if (i >= percent2_start_year && i < percent3_start_year && floating_on) 
				cur_monthly_interest_rate = monthly_interest_rate2;
			
			if (i>=percent3_start_year && floating_on) 
				cur_monthly_interest_rate = monthly_interest_rate3;
			
			monthly_interest_rate_arr[p] = cur_monthly_interest_rate;
			
		}
		
		r_balance = Math.round(r_balance);
		if(r_balance <= 0) 	{
			r_balance = 0;
			break;
		}
	
	}

	
	month_term_nonpmi = month_life - month_term_pmi;
	
	total_payments_all = (month_term_nonpmi * monthly_payment_all_nonpmi) + ( month_term_pmi * monthly_payment_all_nonpmi);
	total_payments = month_life * monthly_payment;

	g_total_Interest  = rt_Interest;
	g_total_tax      = property_tax * loan_life;
	g_total_pmi      = monthly_pmi * month_term_pmi;
	g_total          = g_total_Interest + g_total_tax + g_total_pmi + loan_amount;
	
	r_balance = r_balance_fixed =loan_amount;
	r_interest = r_interest_fixed = 0;
	r_principal = r_principal_fixed = 0;
	z = m = 0;

	last_rate=0;
	
	monthly_home_insurance = (sale_price * home_insurance_rate) /12;
	
	equity = sale_price - loan_amount;
		
	// savings
	monthly_factor_fixed = get_interest_factor(year_term, monthly_interest_rate_fixed);
	monthly_payment_fixed = r_balance / monthly_factor_fixed;
	
	
	clearTable();
	
	new_g_total_interest =  new_g_total_other = new_g_total = 0;
	new_g_total_principal_paid = 0;
	
	for(i=1; i<=loan_life; i++) {
		
		rt_Interest = 0;
		rt_principal = 0;
		rt_Interest_fixed = 0;
		rt_principal_fixed = 0;
		

		for(y=1; y<=12; y+=1)
		{
			
			if (last_rate != monthly_interest_rate_arr[i]) {
				monthly_factor = get_interest_factor(year_term-i+1, monthly_interest_rate_arr[i]);
				monthly_payment = r_balance / monthly_factor;
				last_rate = monthly_interest_rate_arr[i];
			}	
			r_interest  = r_balance * monthly_interest_rate_arr[i];
			r_principal = monthly_payment - r_interest;
			r_balance = r_balance - r_principal;
			
			r_interest_fixed  = r_balance_fixed * monthly_interest_rate_fixed;
			r_principal_fixed = monthly_payment_fixed - r_interest_fixed;
			r_balance_fixed = r_balance_fixed - r_principal_fixed;
			
			

			rt_principal += r_principal;
			rt_Interest += r_interest;
			rt_principal_fixed += r_principal_fixed;
			rt_Interest_fixed += r_interest_fixed;
			
			m++;
		} 
		
		//PT+PMI+HI
		other_payments = monthly_property_tax + monthly_home_insurance;
	
		if (m < month_term_pmi) {
			other_payments += monthly_pmi;
		}
		other_payments_total = other_payments * 12;
		tax_savings = rt_Interest * tax_rate;
		tax_savings_fixed = rt_Interest_fixed * tax_rate;
		net_housing = other_payments_total + rt_Interest + rt_principal - tax_savings;
		
		new_g_total += rt_Interest + other_payments_total + rt_principal;
		new_g_total_other += other_payments_total;
		new_g_total_interest += rt_Interest;
		new_g_total_principal_paid += rt_principal;
		
		equity += rt_principal;
		
		rate_savings = ((monthly_payment_fixed - monthly_payment) * 12) - (tax_savings_fixed - tax_savings);
		
		net_housing = net_housing /12;
		tax_savings = tax_savings /12;
		rate_savings = rate_savings /12
		
		showCents = false;
		fixed=0;
		if (showCents) fixed = 2;
		
		var data = {year:i,
			rt_Interest_disp:rt_Interest.toFixed(fixed),
			rt_principal_disp:rt_principal.toFixed(fixed),
			r_balance_disp:parseFloat(r_balance.toFixed(fixed)),
			monthly_payment_disp:monthly_payment.toFixed(fixed),
			tax_savings_disp:tax_savings.toFixed(fixed),
			other_payments_disp:other_payments.toFixed(fixed),
			net_housing_disp:net_housing.toFixed(fixed),
			rate_savings_disp:rate_savings.toFixed(fixed),
			equity_disp:equity.toFixed(fixed)
        };
        
         var balanceRow = YAHOO.widget.DataTable._cloneObject(data);
         balanceRow.row = i;
         
         balanceRows.push(balanceRow);
         
	}
	
	balanceDataTable.addRows(balanceRows);
	
	balanceDataSource.liveData = balanceRows;
	balanceChart.refreshData();
	
	
	// Pie chart
	
	var pieChartHeader = $('pieChartHeader');
	pieChartHeader.innerHTML = "Total Payment BreakDown";
	
	principal_percent = new_g_total_principal_paid  / new_g_total * 100;
	other_percent	= new_g_total_other / new_g_total * 100;
	interest_percent = new_g_total_interest / new_g_total * 100;
		
	loanBreakdown =
	[
		{ portion: "Principal", value: new_g_total_principal_paid.toFixed(2), percent: principal_percent.toFixed(2) },
		{ portion: "Other: \nTax, PMI, \nHome Ins.", value: new_g_total_other.toFixed(2), percent: other_percent.toFixed(2) },
		{ portion: "Interest", value: new_g_total_interest.toFixed(2), percent: interest_percent.toFixed(2)},
		
	]
	loanBreakdownData.liveData = loanBreakdown;
	breakdownChart.refreshData();
	
	$('monthly_payment_all_out').innerHTML = formatCurrency(monthly_payment_all);
	
	$('total_pmi_out').innerHTML = formatCurrency(g_total_pmi);
	$('total_tax_out').innerHTML = formatCurrency(g_total_tax);
	$('total_interest_out').innerHTML = formatCurrency(g_total_Interest);
	$('month_term_pmi_out').innerHTML = month_term_pmi;
	$('monthly_pmi_out').innerHTML = formatCurrency(monthly_pmi);
	$('down_payment').innerHTML = formatCurrency(dp_amount);
	$('total_closing_costs').innerHTML = formatCurrency(total_closing);
	
	$('balanceChartHeader').innerHTML = "Balance Graph For " + loan_life + " Years";
}



