

<!--


// initilize page variables

window.onerror=null

var bState = true;

var rec = 0;

var oTable = new Array();

var msg;

// the colors for the amortization table... you will need to search and replace on these codes for the HTML form.

var bColor = '#FFFFFF' // white

//var fColor = 'blue' //purple
var fColor = '#000808' //blue

// var fColor = '#000808' // green
// var bColor = 'WHITE'// '#FFFFFF' 
// var fColor = 'PURPLE' // 'blue'

// names for the collections (used for form validation)

oReq = new Collection("AMOUNT","RATE","YEARS","","","")

oVal = new Collection("AMOUNT","RATE","YEARS","","","")

oTst = new Collection("N","N","N","","","")


//============================================================================
// Gets called when the user pressed one of the buttons.
// oForm: 		form elements
// oBtn:		the name of the button that was pressed
// return value:	did we make it through?
//============================================================================
function controller(oForm, oBtn) {
while (bState) {
if (!Required(oForm))
break;
if (!Validate(oForm))
break;
if (!Create())
break;
if (!SetValue(oForm))
break;
if (!Amortize(oForm, oBtn))
break;
if (bState) {
bState = false
}
}
bState = true
}

//============================================================================
// Check if a form element is required by comparing the all of the form
// elements against a collection of required form control names.
// oView: 		form elements
// oReq		required elements
// return value:	did it pass the test?
//============================================================================
function Required(oView) {
for (i in oView ) {
for (j in oReq) {
if (i == oReq[j]) { 
if (isMissing(oView[i])) {
return(false)
}
}
} 
}
return(true)
}

//============================================================================
// Check if a form control is required and missing
// oView: 		a form control
// Return value:	do we have a problem?
//============================================================================
function isMissing(oCtrl) {
if (oCtrl.value == "") {
alert("You have left a required value blank. Please type a number");
oCtrl.focus();
oCtrl.select();
return(true)
}
else
{ 
return(false)
}
}

//============================================================================
// Check if a form element inputs need to be a certain type by
// comparing all of the form elements against a collection of 
// form controls that need specific types of input data.
// oView: 		form elements
// oReq		required elements
// return value:	did it pass the test?
//============================================================================
function Validate(oView) {
for (i in oView) {
for (j in oVal) {
if (i==oVal[j] && oTst[j]=="N") { 
if (isTest(oView[i], oTst[j])) {
return(false)
}
}
}
}
return(true)
}

//============================================================================
// Check if a form control input is the right type
// oView: 		a form control
// Return value:	do we have a problem?
//============================================================================
function isTest(oCtrl, oTest) {
if (oTest=="N" && !isNumber(oCtrl.value) ) {
alert(oCtrl.value+" contains an invalid character. Please type a number");
oCtrl.focus();
oCtrl.select();
return(true)
}
else
{ 
return(false)
}
}


//============================================================================
// Check if the result is a number
// input: 		a texbox value
// Return value:	true / false
//============================================================================
function isNumber(input) {
var result = ""
var nperiods = 0;
for (var i=0;i<input.length;i++) {
var ch = input.substring(i, i+1);
if (!isNaN(parseInt(ch))) {
result = result + ch
} 
if (ch==".") {
nperiods++;
}
if (nperiods==1){
result = result + ch
nperiods++;
}
}
if (result == ""){
return(false);
}
return(true)
}

//============================================================================
// Make a string input into a number
// input: 		a texbox value
// Return value:	a number
//============================================================================
function makeNumber(input) {
var result = "";
var nperiods = 0;
for (var i=0;i<input.length;i++) {
var ch = input.substring(i, i+1);
var flag = true;
if (!isNaN(parseInt(ch))) {
result = result + ch
}
if (ch==".") {
nperiods++;
}
if (nperiods==1){
result = result + ch
nperiods++;
}
}
return(result)
}

//============================================================================
// Create a default instance of the object
// parm1:	Amount	- required
// parm2:	Rate		- required
// parm3: 	Term		- required
// parm4:	Payment
// parm5:	Interest
// parm6:	Frequency	- required
// parm7:	Periods
// return value:	did we create the oebject?
//============================================================================
function Create() {
Mortgage = new Loan(50000, 8, 30, 0, 0, "Monthly", 0 );
return(true)
}

//============================================================================
// Set the properties of the object based on form inputs
// oView: 		form elements
// return value:	did it get and set the properties?
//============================================================================
function SetValue(oView) {
// get the properties mapped from the form
Mortgage.Amount = makeNumber(oView.AMOUNT.value);
oView.AMOUNT.value = calcRound(Mortgage.Amount);

Mortgage.Rate = makeNumber(oView.RATE.value);
//Mortgage.Rate = oView.RATE.value;

Mortgage.Term = makeNumber(oView.YEARS.value);
//Mortgage.Term = oView.YEARS.value;

Mortgage.Frequency = get_selection(oView.FREQUENCY);

// set the number of periods
Mortgage.calcPeriods();

// set the monthly payment
Mortgage.calcPayment();

// set the total interest due
Mortgage.calcInterest();

// update the form view
Show()

return(true)
}

//============================================================================
// Amortize is called at the end of the controler loop and checks to see
// if the amortize button was pushed
// oForm: 		form elements
// oBtn:		the name of the button that was pressed
// return value:	did we select the Amortize button?
//============================================================================
function Amortize(oForm, oBtn) {
if (oBtn.name == "cmdCalc") {
return(false)
}
if (confirm("An Amortization Table calculates the periodic payment breakdown for each specific category listed.")) {

// need to create the table before you can show it
createRecords();

// display the table
showAmortize(oForm);

return(true)

}
return(false)
}

//============================================================================
// create Records computes the values associated with the Amortzation of a Mortgage Loan and 
// adds those values to a record in the Amortization table container array
// return value:	did we calculate all values to display in the Amortization?
//============================================================================
function createRecords(){

// re-init the record counter and container array
rec = 0;
oTable = new Array();

// initialize variables
var currInt = 0;
var currPrin = 0;
prevBalance = Mortgage.Amount;
InterestRate = ( Mortgage.Rate /100) / Mortgage.Periods;
MonthlyPayment = Mortgage.Payment;

//currStart = '2000';
currStart = get_selection(document.MORTGAGE.START);

// let the loops begin
for(i=1;i<=Mortgage.Term;i++) {
for(j=1;j<=Mortgage.Periods;j++) {
periodInt = prevBalance * InterestRate;
periodPrin = MonthlyPayment - periodInt;
currBal = prevBalance - periodPrin;
currInt += periodInt;
currPrin += periodPrin;
prevBalance = currBal;
}
if( currBal <= 0 ){ 
currBal = 0;
}
 
// set the parameters
Year = currStart;
Interest = calcRound(currInt);
Principle = calcRound(currPrin);
Balance = calcRound(currBal);

// increment the container 
rec++

// add a record to the table
addRecord(Year, Interest, Principle, Balance);

// re-init the private variables
currInt = 0;
currPrin = 0;
currStart = parseInt(currStart);
currStart += 1;

// are we done?
if(currBal<=0) {
return(true)
}
}
return (true)
}

//============================================================================
// Build a text string with a header, the table and a footer in HTML then
// diplay the table in a new window with only the menu active.
// oForm: 		form elements
// return value:	did we display the Amortization?
//============================================================================
function showAmortize(oForm) {
// create the header
text = ("<HEAD><TITLE>Amortization Table</TITLE></HEAD>");
text = (text +"<BODY BGCOLOR ="+bColor+"><BR><BR>");
text = (text +"<H2 ALIGN=CENTER><FONT COLOR="+fColor+">Amortization Table</FONT></H2>");
text = (text +"<UL><FONT SIZE=-1>The following table is based on the information entered in the calculator form.</FONT></UL>");
text = (text +"<UL><FONT SIZE=+1 COLOR="+fColor+"> Mortgage Amount: </FONT>" + calcRound(Mortgage.Amount));
text = (text +"<BR><FONT SIZE=+1 COLOR="+fColor+">Interest Rate: </FONT>" + Mortgage.Rate+ " %");
text = (text +"<BR><FONT SIZE=+1 COLOR="+fColor+"> Mortgage Term: </FONT>" + Mortgage.Term + " Years");
text = (text +"<BR><FONT SIZE=+1 COLOR="+fColor+"> Payment Frequency: </FONT>" + Mortgage.Frequency + "</UL>");
text = (text +"<BR><FONT SIZE=+1 COLOR="+fColor+"></FONT>" + msg + "</UL>");
text = (text +"<BR><CENTER><table border='1' width='100%'>");
text = (text +"<TR><TD ALIGN=CENTER BGCOLOR="+fColor+"><FONT COLOR="+bColor+"><B>Year</B></FONT></TD><TD ALIGN=RIGHT BGCOLOR="+fColor+"><FONT COLOR="+bColor+"><B>Interest</B></FONT></TD><TD ALIGN=RIGHT BGCOLOR="+fColor+"><FONT COLOR="+bColor+"><B>Principal</B></FONT></TD><TD ALIGN=RIGHT BGCOLOR="+fColor+"><FONT COLOR="+bColor+"><B>Balance</B></FONT></TD></TR>\n");
// create the Amortization table text by looping through a CONTAINER ARRAY 

for (var q=1; q<oTable.length;q++) {
text = (text +"<TR><TD ALIGN=CENTER>"+ oTable[q].Year +"</TD><TD ALIGN=RIGHT>"+ oTable[q].Interest +"</TD><TD ALIGN=RIGHT>"+ oTable[q].Principle +"</TD><TD ALIGN=RIGHT>"+ oTable[q].Balance +"</TD></TR>");
}

// create the footer
text = (text +"</TABLE></CENTER>");

// Create a new window to display the results
oWindow=window.open("","displayWindow","toolbar=no,width=500,height=300,directories=no,status=no,scrollbars=yes,resize=no,menubar=yes");
oWindow.document.write(text);
oWindow.document.close();

return(true)
}


//============================================================================
// Collection Constructor, a custom object to act as an array but provide
// more flexibility in the future.
//============================================================================
function Collection(item1, item2, item3, item4, item5, item6) {
this.item1 = item1;
this.item2 = item2;
this.item3 = item3;
this.item4 = item4;
this.item5 = item5;
this.item6 = item6;
}


//============================================================================
// Loan Constructor, defines what the Loan object will look like
// and how it will behave. 
//============================================================================
function Loan(Amount, Rate, Term, Payment, Interest, Frequency, Periods ) {
this.Amount = Amount;
this.Rate = Rate;
this.Term = Term;
this.Payment = Payment;
this.Interest = Interest;
this.Frequency = Frequency;
this.Periods = Periods;
this.calcPeriods = calcPeriods;
this.calcPayment = calcPayment;
this.calcInterest = calcInterest;
}


//============================================================================
// Loan object method that calculates the monthly payment for a mortgage loan in the US
//============================================================================
function calcPayment() {

if (this.Rate > 0 ) {
this.Payment = (this.Amount*((this.Rate/(1200))/(1-(Math.pow(1+(this.Rate/(1200)),((this.Term*12)*-1))))));

//handle bi-weekly mortgage payment
if ( this.Periods == 26 ){
this.Payment = (this.Amount*((this.Rate/(2400))/(1-(Math.pow(1+(this.Rate/(2400)),((this.Term*24)*-1))))));
}
}

// handle zero percent financing
if (this.Rate == 0 ) {
this.Payment = ( this.Amount / ( this.Term*12) );
}

}

//============================================================================
// Loan object method that calculates the interest portion of a loan
//============================================================================
function calcInterest2() {
this.Interest = ((this.Payment*(this.Term*this.Periods))-this.Amount);
}


//============================================================================
// Method that calculatesthat calculates the interest portion of a loan.
//============================================================================
function calcInterest() {

var pmt1 = this.Payment;

if ( this.Periods == 26 ){
var pmt1 = this.Payment * 2;
var pmt2 = this.Payment;
}

var prin1 = this.Amount;
var prin2 = this.Amount;

var intPort1 = 0;
var intPort2 = 0;

var prinPort1 = 0;
var prinPort2 = 0;

var accumInt1 = 0;
var accumPrin1 = 0;

var accumInt2 = 0;
var accumPrin2 = 0;

var i = this.Rate;

if (i > 1.0) {
i = i / 100.0;
}

var i1= i/ 12;
var i2 = i / 26;

var count1 = 0;
var count2 = 0;

while(prin1 > 0) {
intPort1 = prin1 * i1;
prinPort1 = pmt1 - intPort1;
prin1 = prin1 - prinPort1;
accumPrin1 = accumPrin1 + prinPort1;
accumInt1 = accumInt1 + intPort1;
count1 = count1 + 1;

if(count1 > 600) {break; } else {continue; }

}

// if monthly
this.Interest = parseInt(accumInt1,10);
msg = "";

if ( this.Periods == 26 ){
while(prin2 > 0) {

intPort2 = prin2 * i2;
prinPort2 = pmt2 - intPort2;
prin2 = prin2 - prinPort2;
accumPrin2 = accumPrin2 + prinPort2;
accumInt2 = accumInt2 + intPort2;
count2 = count2 + 1;

if(count2 > 600) {break; } else {continue; }

}

// if Bi-Weekly
	this.Interest = parseInt(accumInt2,10);

// 
msg = "In essence, what you are really doing is adding a 13th payment to your annual number of payments, and splitting it up between 26 Bi-Weekly payments. Which in your case means that by paying an extra $" + parseInt(pmt1 / 26,10) + " every two weeks you will pay off your mortgage in " + parseInt(count2 /26*12,10) + " months instead of the current " + count1 + " months, and save $" + parseInt(accumInt1 - accumInt2) + " in mortgage interest in the process. ";
//
}
}


//============================================================================
// Loan object method that translates a selection drop down to a value
//============================================================================
function calcPeriods() {
if (this.Frequency=="Monthly") { this.Periods=12 } else { this.Periods=26 }
}

//============================================================================
// Loan object method that shows the calculated amounts
//============================================================================
function Show(oView) {
document.MORTGAGE.PAYMENT.value = calcRound(Mortgage.Payment)
document.MORTGAGE.INTEREST.value = calcRound(Mortgage.Interest)
}

//============================================================================
// oRecord Constructor, defines what the Amortzation record looks like 
//============================================================================
function oRecord(Year, Interest, Principle, Balance){
this.Year = Year;
this.Interest = Interest;
this.Principle = Principle;
this.Balance = Balance;
}

//============================================================================
// addRecord defines how a record gets added to the container array
//============================================================================
function addRecord(Year, Interest, Principle, Balance){
oTable[rec] = new oRecord(Year, Interest, Principle, Balance);
}

//============================================================================
// select_item Constructor, used to retrive the selected item from the dropdown 
// control on a form.
// name: 		form element name
// value:		the value of the options that was selected
// return value:	selected item
//============================================================================
function select_item(name, value) {
this.name = name;
this.value = value;
}

//============================================================================
// Common routine to retrieve the selected value from the drop down object
// select_object:	a drop down from control
// return value:	the selected objects name
//============================================================================
function get_selection(select_object) {
contents = new select_item();
for(var i=0;i<select_object.options.length;i++)
if(select_object.options[i].selected == true) {
contents.name = select_object.options[i].text;
contents.value = select_object.options[i].value;
}
return(contents.name)
}


//============================================================================
// Common routine for rounding that also formats the results into US currency
// num: 		a number
// return value:result is rounded and formated for currency $999,999.00
//============================================================================
function calcRound(num) {
result="$"+Math.floor(num)+"." ;
n = result.length;
if (num>1000 && num<999999) {
result="$"+result.substring(1,n-4)+","+result.substring(n-4,n);
}
if (num>1000000) {
result = "$"+result.substring(1,n-7)+","+result.substring(n-7,n-4)+","+result.substring(n-4,n);
}
var cents=100*(num-Math.floor(num))+0.5;
result += Math.floor(cents/10);
result += Math.floor(cents%10); 
// handle special case
n = result.length;
if ( n - result.indexOf('.') > 3 ){
result = "$"+result.substring(1,n-1);
}
return(result)
}


//============================================================================
// A page specific routine to set the initial state when the page is reloaded.
//============================================================================
function setfocus() {
document.MORTGAGE.AMOUNT.focus();
document.MORTGAGE.AMOUNT.select();
}

// unhide 
// -->

