// This library contains client-side functions used by the mortgage calculator.

// This function strips commas and dollar signs from a digit sequence.
function stripCommas(strIn)
{
	var nLen = strIn.length;
	var strOut = "";
	var i;
	for (i=0; i < nLen; i++)
	{
		var ch = strIn.charAt(i);
		if (ch != "," && ch != " ")
			strOut += ch;
	}

	return parseFloat(strOut);
}

// This function will format a string containing a value by stuffing commas into it
// every three characters to the left of the decimal.
function placeCommas(strIn)
{
	var nPos = strIn.indexOf(".");
	if (nPos < 0)
		nPos = strIn.length;

	var strOut = strIn.substr(nPos);
	for (; nPos > 3; nPos -= 3)
	{
		strOut = "," + strIn.substr(nPos-3, 3) + strOut;
	}
	strOut = strIn.substr(0, nPos) + strOut;

	return strOut;
}

// Checks the term of the loan
function checkTerm(strIn)
{
	var nTerm = parseInt(strIn);
	if (isNaN(nTerm) || nTerm < 1 || nTerm > 50)
		return 0;

	return nTerm * 12;		// We want terms in months
}

// Checks the interest rate
function checkInterest(strIn)
{
	var nRate = parseFloat(strIn);
	if (isNaN(nRate) || nRate < 0.0 || nRate > 30.0)
		return -1;

	return nRate;
}

function appendTrailingZeroes(strIn)
{
	var nDecPos = strIn.indexOf(".", 0);

	if (nDecPos < 0)
		strIn += ".00";
	else if (nDecPos + 3 > strIn.length)
		strIn += "0";
	else
		strIn = strIn.substr(0, nDecPos + 3);

	return strIn;
}

// This function is called when the calculate button is pushed on the mortgage
// form. It will compute the payment amount and put the results in the Payment field.
// This function assumes the calculator form contains the following fields:
// Amount, Interest, Term, AnnualTaxes, CondoFee, Utilities, Payment, ReqIncome
function computePayment(frm)
{
	// If any one of the three fields are blank, do nothing
	if (frm.Amount.value   == "" ||
		frm.Interest.value == "" ||
		frm.Term.value	  == "")
	{
		return;
	}

	var L = stripCommas(frm.Amount.value);
	var r = checkInterest(frm.Interest.value);
	var n = checkTerm(frm.Term.value);

	if (isNaN(L) || L < 1)
	{
		alert("Amount must be a valid number greater than 1.0");
		frm.Amount.focus();
		return;
	}

	if (n < 1)
	{
		alert("Term must be between 1 and 50.");
		frm.Term.focus();
		return;
	}

	if (r < 0)
	{
		alert("Interest rate must be between 0.0 and 30.0");
		frm.Interest.focus();
		return;
	}

	var r2  = 1 + r / 1200;
	var tmp = Math.pow(r2,n);
	var Pmt = L * r * tmp / (1200 * (tmp - 1))

	if (r == 0.0)
		Pmt = L / n;

	var annualTaxes = stripCommas(frm.AnnualTaxes.value);
	var condoFee	= stripCommas(frm.CondoFee.value);
	var utilities   = stripCommas(frm.Utilities.value);

	var monthlyExpense = 0;
	var totalExpense   = 0;

	// Only want to show the first two decimal places, so pretty up the result.
	var strPmt		 = "";
	var strReqIncome = "";
	var strTaxes     = "";
	var strExpenses  = "0";
	var strTotalExp  = "";
	var strAnnualTax = "";

	if (isNaN(annualTaxes) || annualTaxes < 1)
	{
		strTaxes = "0";
		strAnnualTax = "0";
	}
	else
	{
		var monthlyTax = annualTaxes / 12;
		totalExpense = totalExpense + monthlyTax;

		strTaxes = monthlyTax.toString();
		strAnnualTax = annualTaxes.toString();
	}

	if (isNaN(condoFee) || condoFee < 1)
		condoFee = 0;
	else
		monthlyExpense = monthlyExpense + condoFee;

	if (isNaN(utilities) || utilities < 1)
		utilities = 0;
	else
		monthlyExpense = monthlyExpense + utilities;

	if (isNaN(Pmt)) {
		strPmt		 = "0";
		strReqIncome = "0";
	} else {
		strPmt = Pmt.toString();

		var ReqIncome = Pmt * 37.5;     // Pmt cannot exceed 32% of gross income, so Pmt / 0.32 * 12 = Income
		strReqIncome = ReqIncome.toString();

		totalExpense = totalExpense + Pmt;
	}

	if (monthlyExpense > 0)
	{
		totalExpense = totalExpense + monthlyExpense;
		strExpenses  = monthlyExpense.toString();
	}

	if (totalExpense > 0)
		strTotalExp  = totalExpense.toString();

	strPmt       = appendTrailingZeroes(strPmt);
	strReqIncome = appendTrailingZeroes(strReqIncome);
	strTotalExp  = appendTrailingZeroes(strTotalExp);
	strTaxes     = appendTrailingZeroes(strTaxes);
	strExpenses  = appendTrailingZeroes(strExpenses);

	var strLoan  = placeCommas(L.toString());
	strPmt		 = placeCommas(strPmt);
	strReqIncome = placeCommas(strReqIncome);
	strTotalExp  = placeCommas(strTotalExp);
	strTaxes     = placeCommas(strTaxes);
	strExpenses  = placeCommas(strExpenses);
	strAnnualTax = placeCommas(strAnnualTax);
	
	frm.Amount.value		= strLoan;
	frm.Payment.value		= strPmt;
	frm.AnnualTaxes.value   = strAnnualTax;
	frm.Taxes.value			= strTaxes;
	frm.Expenses.value		= strExpenses;
	frm.TotalExpenses.value = strTotalExp;
	frm.ReqIncome.value		= strReqIncome;
	return;
}

// This function is called when the Reverse calculate button is pushed on the mortgage
// form. It will compute the payment amount based on income and put the results in the
// Payment field.  This function assumes the calculator form contains the following fields:
// Income, RevInterest, RevTerm, MtgAmount, MtgPayment
function computeRevPayment(frm)
{
	// If any one of the three fields are blank, do nothing
	if (frm.Income.value   == "" ||
		frm.RevInterest.value == "" ||
		frm.RevTerm.value	  == "")
	{
		return;
	}

	var I = stripCommas(frm.Income.value);
	var r = checkInterest(frm.RevInterest.value);
	var n = checkTerm(frm.RevTerm.value);

	if (isNaN(I) || I < 1)
	{
		alert("Income must be a valid number greater than 1.0");
		frm.Income.focus();
		return;
	}

	if (n < 1)
	{
		alert("Term must be between 1 and 50.");
		frm.RevTerm.focus();
		return;
	}

	if (r < 0)
	{
		alert("Interest rate must be between 0.0 and 30.0");
		frm.RevInterest.focus();
		return;
	}

	var r2  = 1 + r / 1200;
	var tmp = Math.pow(r2,n);
	var Pmt = I / 12 * 0.32;
	var tmp2 = r * tmp / (1200 * (tmp - 1));
	var L = Pmt / tmp2;

	if (r == 0.0)
		L = Pmt *  n;

	// Only want to show the first two decimal places, so pretty up the result.
	var strAmount = "";
	var strPmt    = "";

	if (isNaN(Pmt)) {
		strPmt    = "0";
		strAmount = "0";
	} else {
		strPmt    = Pmt.toString();
		strAmount = L.toString();
	}

	strPmt    = appendTrailingZeroes(strPmt);
	strAmount = appendTrailingZeroes(strAmount);

	var strIncome = placeCommas(I.toString());
	strPmt		  = placeCommas(strPmt);
	strAmount     = placeCommas(strAmount);

	frm.Income.value     = strIncome;
	frm.MtgPayment.value = strPmt;
	frm.MtgAmount.value  = strAmount;
	return;
}