//******************************************************************************
//    Last edited by:  $Id: mortgage.js,v 1.7 2002/12/23 19:14:40 soglesby Exp $
//          Filename:  $Source: /bbsrc/web/money/tools/scripts/RCS/mortgage.js,v $
//          Revision:  $Revision: 1.7 $
//******************************************************************************

function Mortgage()
{
	//Set up default values 
	this.principal = 250000.00; 	// Loan principal
	this.rate = 7;					// Interest rate expressed as %
	this.period = 30;				// Loan period in years
	this.points = 0;				// Points (if any)
	this.mnthlypayment = monthlyPayment(this.principal, 12, this.rate, this.period * 12);
	this.startdate = generateStartDate();
	this.prepayamt = 0;
	//this.prepayfreq = 'month';
	this.prepaystrt = generateStartDate();
	this.proceeds = this.principal;
	this.eff_rate = this.rate;
	this.amortize = false;
	this.width = "100%";
	
	this.set = MortgageValueSet;
	this.calculate = MortgageCalculate;
	this.showAmortization = MortgageShowAmortization;
	this.putMtgeInfo = MortgagePutMtgeInfo;
	this.compareTotals = MortgageCompareTotals;
	this.setWidth = MortgageSetWidth;
	//this.print = MtgeCalcPrintResult;
}

function MortgageSetWidth(w)
{
	this.width = w;
}

function generateStartDate()
{
	var d = new Date();
	var obj = new Object();
	obj.month = d.getMonth();
	obj.year = d.getYear();

	if (obj.year < 1000)
		obj.year += 1900;
		
	return obj;
}

function MortgageValueSet(obj)
{
	var fld = obj.name;
	var val = obj.value;

	//alert("val= "+ val+ "\nfld= "+fld);
	if (val == null)
		val = obj[obj.selectedIndex].value;

	if (typeof(val) == "string")
	{
		/* strip out any commas from the value */
		val = val.replace(/,/g, "");
	}
	
	if (fld == 'amortize')
	{
		this.amortize = obj.checked;
		return true;
	}
	else if (fld == 'prepayfreq')
	{
		this.prepayfreq = val;
		return true;
	}
	
	if (val == "")
		val = 0;

	if (isNaN(val) || val < 0)
	{
		alert('You must enter a positive numeric value in this field');
		obj.focus();
		return false;
	}
	
	if ((fld == 'rate' || fld == 'period') && val <= 0)
	{
		alert('Value must be greater than 0');
		obj.focus();
		return false;
	}
	if ((fld == 'rate') && val > 29)
	{
		alert('Interest Rate: Value must be less than 29');
		obj.focus();
		return false;
	}
	if ((fld == 'period') && val > 99)
	{
		alert('Loan Period: Value must be less than 99');
		obj.focus();
		return false;
	}
	if ((fld == 'points') && val > 12)
	{
		alert('Points: Value must be less than 12');
		obj.focus();
		return false;
	}
	switch (fld)
	{
	case 'principal':
	    if (val != 0)
		this.mnthlypayment = '';
	    else
		return true;
	    break;
	case 'mnthlypayment':
	    if (val != 0)
		this.principal = '';
	    else
		return true;
	    break;
	case 'start_month':
		this.startdate.month = val;
		return true;
	case 'start_year':
		this.startdate.year = val;
		return true;
	case 'ppm_month':
		this.prepaystrt.month = val;
		//alert("case-prepay-month= " + val);
		return;
	case 'ppm_year':
		this.prepaystrt.year = val;
		return;
	}
	
	this[fld] = val;
}

function MortgageCalculate()
{
	var points = Number(this.points); 	//convert/force to a integer;
	if (this.principal == ""){
	 	this.principal = calcAmortPrincipal(this.mnthlypayment, 12, this.rate, this.period * 12);
	}
	else{
	 	this.mnthlypayment = monthlyPayment(this.principal, 12, this.rate, this.period * 12);
	}
	this.proceeds = this.principal * (1 - (points / 100));
	

	this.eff_rate = calculateEffRate(this.mnthlypayment, this.proceeds, this.period);
}

function calculateEffRate(payment, amount, period){
//Calculate the effective rate, solution by Newton-Raphson Method

	var ee=0.01
	var X=0;
	var MAXGUESSES=100;
	var min_rate=.01;
	var max_rate=.2;
	var tmp1=0;
	var rate=0;
	var solution;
	
	for (var ii=0; ii<MAXGUESSES; ii++) {
		rate=min_rate + (max_rate - min_rate)/2;
		mon_rate=rate/12;
		tmp1=mon_rate*amount/(1-Math.pow(1+mon_rate,-1*period*12));
		X=payment - tmp1;
		if (X < 0){
			max_rate=rate;
		}else{
			min_rate=rate;
		}
		if (Math.abs(X) < ee) break;
	}
	solution = Math.round(rate*100000)/1000;
	return solution;
}


function MortgageShowAmortization()
{
    var principal = this.principal;
	var payment = Number(this.mnthlypayment);
	var interest = this.rate / 12 / 100;
	var periods = this.period * 12;
	var month = Number(this.startdate.month) + 1;
	var year = this.startdate.year;
	var beg_year = year;
	var end_year = year + this.period;
	var ppm_amount = this.prepayamt;
	var ppm_month = this.prepaystrt.month;
	//alert("prepaystrt.month= " + ppm_month);
	var ppm_year = this.prepaystrt.year;
	var ppm_freq = this.prepayfreq;
    var towardsPrincipal = new Object();
    var towardsInterest = new Object();
	var additionalPayment = new Array(periods);
	var paymentArray = new Object();
    var col_period = "";
    var col_payment = "";
    var col_interest = "";
    var col_principal = "";
    var year_payments = "";
	var body = "";
	var termpayments = 0;
	var terminterest = 0;
	var termprincipal = 0;
        body = '<TR>'
			 +     '<TD COLSPAN="4" ALIGN="center" bgcolor="#dee8f1">'
			 +        '<span class="storybold">Annualized Mortgage Payments</span>'
			 +     '</TD>'
			 +  '</TR>'
			 +  '<TR>'
			 +	   '<TD ALIGN="left" CLASS="story">'
			 +        '<STRONG><U>Period</U></STRONG>'
			 +     '</TD>'
			 +     '<TD ALIGN="right" CLASS="story">'
			 +        '<STRONG><U>Payments</U></STRONG>'
			 +     '</TD>'
			 +	   '<TD ALIGN="right" CLASS="story">'
			 +        '<STRONG><U>Interest</U></STRONG>'
			 +     '</TD>'
			 +     '<TD ALIGN="right" CLASS="story">'
			 +        '<STRONG><U>Principal</STRONG>'
			 +     '</TD>'
			 +   '</TR>'; 

	// set up prepayments
	// if the prepayments start on or before the mortgage, 
	// return an alert to the user.
	if ((ppm_year <= year) && (ppm_month < month)) { 
		ppm_month = month;
		ppm_year = year;
		if (ppm_amount != ""){
			alert("Note: Prepayment is prior to Mortgage Start date.\n Prepayment has been adjusted to Mortgage Payment Start Date.");
		}
	}
		
	if (ppm_freq == "year") {
		ppm_amount = ppm_amount / 12;
	}

	var a = new Object();
	var b = new Object();
	var c = new Object();
	
	// calculate the number of months without prepayment
	if (month == 12) 
	{
		if (ppm_year == year)
		{
			ppm_month = 0;
			ppm_year++;
		}
		month = 0;
		year++; beg_year++;
	}

	var tempmonth = month;
	var tmpstart=0;
	
	for (j = 0; j < periods; j++) {
		if ((year == ppm_year) && (tempmonth == ppm_month)) {
			break;
		}
		a[j] = payment;
		c[j] = principal * interest;
		b[j] = a[j] - c[j];
		principal = principal - b[j];
		termpayments += Number(a[j]);
		terminterest += c[j];
		termprincipal += b[j];
		paymentArray[year] = a;
		towardsPrincipal[year] = b;
		towardsInterest[year] = c;
		
		if (++tempmonth > 11) {
			tempmonth = 0;
			a = new Object();
			b = new Object();
			c = new Object();
			year++;
		}
		//alert("temp-month-endloop=  "+tempmonth +"j=" +j);
		
	}
	//set tmpstart to the last position of j
	//the next loop will start at this position
	tmpstart=j;

	// finish with prepayment, if any 
	var last = false;
	for (j = tmpstart; j < periods && !(last); j++) {
	    if (principal > (payment + Number(ppm_amount))) {
		a[j] = payment + Number(ppm_amount);
		c[j] = principal * interest;
		b[j] = a[j] - c[j];
		principal = principal - b[j];
	    } else {
		c[j] = principal * interest;
		a[j] = principal + c[j];
		b[j] = a[j] - c[j];
		principal = 0;
		last = true;
	    }
		termpayments += Number(a[j]);
	    terminterest += c[j];
	    termprincipal += b[j];
	    paymentArray[year] = a;
	    towardsPrincipal[year] = b;
	    towardsInterest[year] = c;
	    if (++tempmonth > 11) {
		a = new Object();
		b = new Object();
		c = new Object();
		year++;
		tempmonth = 0;
	    } 
		
	}
		
		
	year = beg_year;
        var totalInterest = 0;
        var totalPrincipal = 0;
        var year_payments = 0;
		var monthcount = 0;
        for (i in paymentArray) {
		  for (j in paymentArray[i]) {
                totalInterest += Number(towardsInterest[i][j]);
                totalPrincipal += Number(towardsPrincipal[i][j]);
                year_payments += Number(paymentArray[i][j]);
				if (month < 12) month++;
				monthcount++;
           }
		    //alert("loop-month= " + month +"\nmonthcount= "+monthcount);
           body += ('<TR><TD CLASS="story">' + month + "/" + year + '</TD><TD ALIGN="right" CLASS="story">' + toCurrency(year_payments) + '</TD><TD ALIGN="right" CLASS="story">' + toCurrency(totalInterest) + '</TD><TD ALIGN="right" CLASS="story">' + toCurrency(totalPrincipal) + '</TD></TR>');
           year_payments = 0;
           totalInterest = 0;
           totalPrincipal = 0;
           month = 0;
           year++;
        }
        body += ('<TR><TD COLSPAN="4"><HR></TD></TR><TR><TD CLASS="story"><STRONG>Totals:</STRONG></TD><TD ALIGN="right" CLASS="story">' + toCurrency(termpayments) + '</TD><TD ALIGN="right" CLASS="story">' + toCurrency(terminterest) + '</TD><TD ALIGN="right" CLASS="story">' + toCurrency(termprincipal) + '</TD></TR>');

	body = '<TABLE BORDER="0" CLASS="mtgeinfo" WIDTH="' + this.width + '">' + this.compareTotals(termpayments, monthcount) + body;
	body += '</TABLE>';
	return (body);

}

function MortgageCompareTotals(reported, mcount) {
	var principal = this.principal;
        var payment = Number(this.mnthlypayment);
        var interest = this.rate / 12 / 100;
        var periods = this.period * 12;
	var diffamount = 0;
	var diffterm = 0;

	diffamount = (payment * periods) - reported;
//alert( "mcount= " + mcount + "\n" + "payment= " + payment + "\n" + "periods= " + periods + "\n" + "reported= " + reported + "\n" + "diffamount= " + diffamount + "\n");
	if (diffamount > 1) {
		diffterm = periods - mcount;
		return ('<TR><TD COLSPAN="4" ALIGN="left" CLASS="story"><HR>Prepayments will result in a reduction of total interest by <FONT COLOR="red">$' + toCurrency(diffamount) + '</FONT>. The term of the loan will be reduced by ' + Math.floor(diffterm / 12) + ' years and ' + (diffterm % 12) + ' months');
	} else {
		return ('');
	}
} 

function PopulateForm(frm)
{
		// populate form with values contained/calculated by mtgecalc object 
		frm.principal.value = toCurrency(mtgecalc.principal);
		frm.rate.value = mtgecalc.rate;
		frm.mnthlypayment.value = toCurrency(mtgecalc.mnthlypayment);
		frm.period.value = mtgecalc.period;
		frm.points.value = mtgecalc.points;
		frm.start_month.selectedIndex = Number(mtgecalc.startdate.month);
		//BuildMonthDropDown(frm.start_month, mtgecalc.startdate.month);
		frm.start_year.value = mtgecalc.startdate.year;
		
		//initialize prepayment info
		//BuildPrepayDropDown(frm.prepayfreq, mtgecalc.prepayfreq);
		if (mtgecalc.prepayfreq == 'year') frm.prepayfreq.selectedIndex = 1;
		//BuildMonthDropDown(frm.ppm_month, mtgecalc.prepaystrt.month);
		frm.ppm_month.selectedIndex = Number(mtgecalc.prepaystrt.month);
		//alert("start-ppm-month=  "+frm.ppm_month.value);
		frm.prepayamt.value = mtgecalc.prepayamt;
		frm.ppm_year.value = mtgecalc.prepaystrt.year;
}
	
function MortgagePutMtgeInfo(type)
{
	var tmpstr = "";
	
	if (type == 'mtgform')
	{
		tmpstr = '<FORM>'
			+ '<TR>'
			+	'<TD ALIGN="center" COLSPAN="2" BGCOLOR="dee8f1">'
			+	  '<INPUT TYPE="button" VALUE="Recalculate" onClick="ShowForm()">'
		+	  '<INPUT TYPE="button" VALUE="PrintResults" onClick="PrintResult()">'
			+	'</TD>'
			+ '</TR>'
			+ '</FORM>';
	}
	
	if (type == 'print')
	{
		tmpstr = '<TR>'
			+	'<TD ALIGN="center" COLSPAN="2" bgcolor="#dee8f1">'
			+	  '<span class="storybold">Mortgage Calculator Results</span>'
			+	'</TD>'
			+ '</TR>';
	}
	
	return ('<TABLE BORDER="0" CELLSPACING="5" CELLPADDING="5" WIDTH="' + this.width + '">'
			+ tmpstr
			+ '<TR>'
			+ 	'<TD ALIGN="left" VALIGN="top" CLASS="storybold">'
			+	  'Proceeds :'
			+	'</TD>'
			+	'<TD ALIGN="right" VALIGN="top" CLASS="story">'
			+	  toCurrency(this.proceeds)
			+	'</TD>'
			+ '</TR>'
			+ '<TR>'
			+	'<TD ALIGN="left" VALIGN="top" CLASS="storybold">'
			+	  'Monthly Payment :'
			+	'</TD>'
			+	'<TD ALIGN="right" VALIGN="top" CLASS="story">'
			+	  toCurrency(this.mnthlypayment)
			+       '</TD>'
			+ '</TR>'
			+ '<TR>'
			+   	'<TD ALIGN="left" VALIGN="top" CLASS="storybold">'
			+	  'Effective Rate :'
			+	'</TD>'
			+	'<TD ALIGN="right" VALIGN="top" CLASS="story">'
			+	  this.eff_rate  + '%'
			+	'</TD>'
			+ '</TR>'
		    +'</TABLE>');
}


function ShowResult()
{
PopulateForm(document.mortgage);
var body1 = mtgecalc.putMtgeInfo('print');
var body2 = mtgecalc.showAmortization();
var tail = '<br><br>';
var all_results = body1 + body2 + tail;

if ((navigator.appName.indexOf("Netscape") != -1)&& (parseInt(navigator.appVersion) == 4)) {
			var reslayer = document.layers['mtgeres2'].document;
			reslayer.open();
			reslayer.write(all_results);
			reslayer.close();
     } 
	 else if ((navigator.appName.indexOf("Microsoft") != -1) || 
	 		  (parseInt(navigator.appVersion) >= 5)){
			document.getElementById("mtgeres").innerHTML = all_results;
    } 
	else {
		alert("This calculator can only be used in Netscape Navigator or Microsoft Internet Explorer, version 4 or greater");
}

}

function PrintResults()
{
	PopulateForm(document.mortgage);
	var winheight = 400;
	var newwin = window.open('', 'printable', 'height=' + winheight + ',width=' + (mtgecalc.width + 40) + ',toolbar,scrollbars,resizable');
	
	var head = '<html><head><title>Bloomberg - Mortgage Calculator</title></head><body>';
	var closewin = '<a href="javascript:window.close();">Close Window</a>';	
	var footer = '<br><font face="sans-serif, arial" size=-2>'
				+ '&copy;2002 Bloomberg L.P. All rights reserved. '
				+ '<a href="http://www.bloomberg.com/tos.html">Terms of Service</a>, '
				+ '<A HREF="http://www.bloomberg.com/privacy.html">Privacy Policy</A> '
				+ 'and <A HREF="http://www.bloomberg.com/trademarks.html">Trademarks</A>.</font>';
	var tail = '</body></html>';
	newwin.document.write(head);
	newwin.document.write('<LINK REL="stylesheet" TYPE="text/css" HREF="/money/stylesheets/money.css">');
	newwin.document.write(closewin);
	newwin.document.write(mtgecalc.putMtgeInfo('print'));
	newwin.document.write(mtgecalc.showAmortization());
	newwin.document.write(closewin);
	newwin.document.write(footer);
	newwin.document.write(tail);
	newwin.document.close();
	newwin.focus();

}

