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;
    
    var title = '<TR>'
       +     '<TD COLSPAN="4" ALIGN="left" bgcolor="#cccccc">'
       +        '&nbsp;<b>Annualized Mortgage Payments</b>'
       +     '</TD>'
       +  '</TR>';
  var header = '<TR bgcolor="#ffffff">'
       +     '<TD ALIGN="left">'
       +        '<span class="style4">Period</span>'
       +     '</TD>'
       +     '<TD ALIGN="right">'
       +        '<span class="style4">Payments</span>'
       +     '</TD>'
       +     '<TD ALIGN="right">'
       +        '<span class="style4">Interest</span>'
       +     '</TD>'
       +     '<TD ALIGN="right">'
       +        '<span class="style4">Principal</span>'
       +     '</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;
    var datarows = '';
        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);
           datarows += '<TR bgcolor="#ffffff"><TD >'
          + '' 
        + month + "/" + year + '</TD><TD ALIGN="right" >' 
        + toCurrency(year_payments) 
        + '</TD><TD ALIGN="right" >' 
        + toCurrency(totalInterest) + '</TD><TD ALIGN="right" >' 
        + toCurrency(totalPrincipal) 
        + ''
        + '</TD></TR>';
           year_payments = 0;
           totalInterest = 0;
           totalPrincipal = 0;
           month = 0;
           year++;
        }
        var totals = ''
      + '<TR bgcolor="#eeeeee"><TD CLASS="style4">'
      + ''
      + 'Totals:</TD><TD ALIGN="right" >' + toCurrency(termpayments) 
      + '</TD><TD ALIGN="right" >' 
      + toCurrency(terminterest) + '</TD><TD ALIGN="right" >' 
      + toCurrency(termprincipal) 
      + ''
      + '</TD></TR><TR bgcolor="#eeeeee"><TD COLSPAN="4">'
      + ''
      + '</TD></TR>';
  var prepaymt_results = this.compareTotals(termpayments, monthcount);
  var table = '<table width="100%" cellpadding="0" border="1" cellspacing="2" bordercolor="#cccccc" align=right>' 
      + title + prepaymt_results + header + datarows + totals + '</TABLE>';
  return (table);

}

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;
  var results;

  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;
    results = '<TR bgcolor="#eeeeee">'
        + '<TD COLSPAN="4" ALIGN="left" >'
        + '<br>&nbsp;'
        + 'Prepayments in the amount of ' + toCurrency(this.prepayamt) 
        + ' will result in a reduction of total<br>&nbsp;'
        + 'interest by <FONT COLOR="red">$' + toCurrency(diffamount) 
        + '</FONT>. The term of the loan will be reduced by ' 
        + Math.floor(diffterm / 12) + ' years<br>&nbsp;and ' 
        + (diffterm % 12) + ' months. <br><br></TD></TR>';
    return (results);
  } 
  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="CCCC99">'
      +   '<INPUT TYPE="button" VALUE="Recalculate" onClick="ShowForm()">'
    +   '<INPUT TYPE="button" VALUE="PrintResults" onClick="PrintResult()">'
      + '</TD>'
      + '</TR>'
      + '</FORM>';
  }
  
  if (type == 'print')
  {
    tmpstr = '<TR>'
      + '<TD ALIGN="left" COLSPAN="2" bgcolor="#cccccc">'
      +   '&nbsp;<b>Calculator Results</b>'
      + '</TD>'
      + '</TR>';
  }
  
  return ('<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0" width="175">'
      + tmpstr
      + '<TR bgcolor="#eeeeee">'
      +   '<TD ALIGN="left" VALIGN="top" >'
      +   '<b>Proceeds :</b>'
      + '<br>&nbsp;$'
      +   toCurrency(this.proceeds)
      + '</TD>'
      + '</TR>'
      + '<TR bgcolor="#eeeeee">'
      + '<TD ALIGN="left" VALIGN="top" >'
      +   '<b>Monthly Payment :</b>'
      + '<br>&nbsp;$'
      +   toCurrency(this.mnthlypayment)
      +       '</TD>'
      + '</TR>'
      + '<TR bgcolor="#eeeeee">'
      +     '<TD ALIGN="left" VALIGN="top" >'
      +   '<b>Effective Rate :</b>'
      + '<br>&nbsp;'
      +   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 = '<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td valign="top">' 
        + body1 + '</td><td valign="top">' + body2 + '</td></tr></table>';

  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 body1 = mtgecalc.putMtgeInfo('print');
  var body2 = mtgecalc.showAmortization();
  var results = '<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td valign="top" align="left">' 
        + body1 + '</td><td valign="top" align="right">' + body2 + '</td></tr></table>';

  var head = '<html><head><title>Mortgage Calculator</title></head><body>';
  var styles = ''
        + '';
  var print_link = '<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td align="left" valign="top">'
          + '&nbsp;<br>'
          + '<span class="style4">Mortgage Calculator</span><br><br></td>'
          + '<td align="right" valign="top"><a href="javascript:window.print()">'
          + '&nbsp;</a>'
          + '<a href="javascript:window.print()" class="style4">Print</a></td></tr></table>';
  var closewin = '<a href="javascript:window.close();">Close Window</a>'; 
  var footer = '<br>&nbsp;';
  var tail = '</body></html>';
  newwin.document.write(head);
  newwin.document.write(styles);
  newwin.document.write(print_link);
  newwin.document.write(results);
  newwin.document.write(footer);
  newwin.document.write(tail);
  newwin.document.close();
  newwin.focus();

}


