// JavaScript Document

//Within this file lives the constructor, the calculate, and the accessor 
//methods for AmortScheduleCalculator

//Define Global Variables
var MAX_TERM = new Number(360);
var COLUMN_DELIMITER = "\t";
var ROW_DELIMITER = "\r\n";
var HEADER= "paymentNumber" + COLUMN_DELIMITER + "month" + COLUMN_DELIMITER +
            "year" + COLUMN_DELIMITER + "principal" + COLUMN_DELIMITER +
            "interest" + COLUMN_DELIMITER + "beginningBalance" + COLUMN_DELIMITER +
            "endingBalance" + COLUMN_DELIMITER + "rate" + COLUMN_DELIMITER +
            "prepaidPrincipal" + COLUMN_DELIMITER + "prepaidInterest" + COLUMN_DELIMITER +
            "prepaidBeginBalance" + COLUMN_DELIMITER + "prepaidEndBalance" + COLUMN_DELIMITER +
            "taxSavings" + COLUMN_DELIMITER + "PMI" + ROW_DELIMITER;



//accessor methods for the AmortScheduleCalculator

//accessor method for Index Range
function checkIndexRange(index)
{        
  if (index > (this.payCount-1))
    {
      return false;
    }
  else
    {
      return true;
    }
}	    

//accessor method for payCount
function getPaymentCount()
{
  return (this.payCount);
}

//accessor method for month
function getMonth(index)
{
  if(this.checkIndexRange(index))
    {
      return (month[index]);
    }
  else return 0;
}

//accessor method for year
function getYear(index)
{
  if(this.checkIndexRange(index))
    {
      return (year[index]);
    }
  else return 0;
}

//accessor method for principal
function getPrincipal(index)
{
  if(this.checkIndexRange(index))
    {
      return (principal[index]);
    }
  else return 0;
}

//accessor method for interest
function getInterest(index)
{
  if(this.checkIndexRange(index))
    {
      return (this.interest[index]);
    }
  else return 0;
}

//accessor method for interestRate
function getInterestRate(index)
{
  if(this.checkIndexRange(index))
    {
      return (this.interestRate[index]);
    }
  else return 0;
}

//accessor method for Beginning Balance
function getBeginningBalance(index)
{
  if(this.checkIndexRange(index))
    {
      return (this.beginningBalance[index]);
    }
  else return 0;
}

//accessor method for Ending Balance
function getEndingBalance(index)
{
  if(this.checkIndexRange(index))
    {
      return (this.endingBalance[index]);
    }
  else return 0;
}
    
//accessor method for prepaidPrincipal
function getPrepaidPrincipal(index)
{
  if(this.checkIndexRange(index))
    {
      return (this.prepaidPrincipal[index]);
    }
  else return 0;
}

//accessor method for prepaidInterest
function getPrepaidInterest(index)
{
  if(this.checkIndexRange(index))
    {
      return (this.prepaidInterest[index]);
    }
  else return 0;
}

//accessor method for prepaidBeginBalance
function getPrepaidBeginBalance(index)
{
  if(this.checkIndexRange(index))
    {
      return (this.prepaidBeginBalance[index]);
    }
  else return 0;
}

//accessor method for prepaidEndBalance
function getPrepaidEndBalance(index)
{
  if(this.checkIndexRange(index))
    {
      return (this.prepaidEndBalance[index]);
    }
  else return 0;
}

//accessor method for totalNormalPrincipal
function getTotalNormalPrincipal()
{
  return (this.totalNormalPrincipal);
}

//accessor method for totalNormalInterest
function getTotalNormalInterest()
{
  return (this.totalNormalInterest);
}

//accessor method for taxSavings
function getTaxSavings(index)
{
  if(this.checkIndexRange(index))
    {
      return (this.taxSavings[index]);
    }
  else return 0;
}

//accessor method for totalOwnershipSavings
function getTotalOwnershipSavings()
{
  return (this.totalOwnershipSavings);
}

//accessor method for totalPMI
function getTotalPMI()
{
  return (this.totalPMI);
}
    
//accessor method for monthlyPayment
function getMonthlyPayments()
{
  return (this.monthlyPayment);
}    

//accessor method for totalTaxSavings
function getTotalTaxSavings()
{
  return (this.totalTaxSavings);
}

//accessor method for totalPrepaidSavings
function getTotalPrepaidSavings()
{
  return (this.totalPrepaidSavings);
}

//accessor method for PMI
function getPMI(index)
{
  if(this.checkIndexRange(index))
    {
      return (this.PMI[index]);
    }
  else return 0;
}	        

//accessor method for paymentNumber
function getPaymentNumber(index)
{
  if(this.checkIndexRange(index))
    {
      return (this.paymentNumber[index]);
    }
  else return 0;
}	        

//accessor method for HEADER
function getHeader()
{        
  return HEADER;
}

//accessor method for Schedule
function getSchedule()
{        
  var tempBuffer = "";
  var i = 0;

  for (i = 0; i < payCount; i++)
    {
      tempBuffer += (this.paymentNumber[i] + COLUMN_DELIMITER +
      		     this.month[i] + COLUMN_DELIMITER +
                     this.year[i] + COLUMN_DELIMITER +
                     this.principal[i] + COLUMN_DELIMITER +
                     this.interest[i] + COLUMN_DELIMITER +
                     this.beginningBalance[i] + COLUMN_DELIMITER +
                     this.endingBalance[i] + COLUMN_DELIMITER +
                     this.interestRate[i] + COLUMN_DELIMITER +
                     this.prepaidPrincipal[i] + COLUMN_DELIMITER +
                     this.prepaidInterest[i] + COLUMN_DELIMITER +
                     this.prepaidBeginBalance[i] + COLUMN_DELIMITER +
                     this.prepaidEndBalance[i] + COLUMN_DELIMITER +
                     this.taxSavings[i] + COLUMN_DELIMITER +
                     this.PMI[i] + COLUMN_DELIMITER);
                                
       tempBuffer += ROW_DELIMITER;
     }
       
  return tempBuffer;
}	        
    
//this method is the new AmortScheduleCalculator object constructor
function AmortScheduleCalculator()
{
  //Arrays
  this.paymentNumber = new Array();
  this.month = new Array();
  this.year = new Array();
  this.principal = new Array();
  this.interest = new Array();
  this.beginningBalance = new Array();
  this.endingBalance = new Array();
  this.interestRate = new Array();
  this.prepaidPrincipal = new Array();
  this.prepaidInterest = new Array();
  this.prepaidBeginBalance = new Array();
  this.prepaidEndBalance = new Array();
  this.taxSavings = new Array();
  this.PMI = new Array();
  this.monthlyPayment = new Array();

  //Numbers
  this.payCount = new Number();
  this.totalTaxSavings = new Number();
  this.totalNormalPrincipal = new Number();
  this.totalNormalInterest = new Number();
  this.totalPMI = new Number();
  this.totalPrepaidSavings = new Number();

  //ID
  this.className = "AmortScheduleCalculator";

  //Accessor Methods
  this.checkIndexRange = checkIndexRange;
  this.getPaymentCount = getPaymentCount;
  this.getMonth = getMonth;
  this.getYear = getYear;
  this.getPrincipal = getPrincipal;
  this.getInterest = getInterest;
  this.getInterestRate = getInterestRate;
  this.getBeginningBalance = getBeginningBalance;
  this.getEndingBalance = getEndingBalance;
  this.getPrepaidPrincipal = getPrepaidPrincipal;
  this.getPrepaidInterest = getPrepaidInterest;
  this.getPrepaidBeginBalance = getPrepaidBeginBalance;
  this.getPrepaidEndBalance = getPrepaidEndBalance;
  this.getTotalNormalPrincipal = getTotalNormalPrincipal;
  this.getTotalNormalInterest = getTotalNormalInterest;
  this.getTaxSavings = getTaxSavings;
  this.getTotalOwnershipSavings = getTotalOwnershipSavings;
  this.getTotalPMI = getTotalPMI;
  this.getMonthlyPayments = getMonthlyPayments;
  this.getTotalTaxSavings = getTotalTaxSavings;
  this.getTotalPrepaidSavings = getTotalPrepaidSavings;
  this.getPMI = getPMI;
  this.getPaymentNumber = getPaymentNumber;
  this.getHeader = getHeader;
  this.getSchedule = getSchedule;
  this.calculate = AmortScheduleCalculatorCalculate;

  return this;
}

function getARMPayments(totalLoanAmt, initialRate, loanTerm, firstTerm, recurringTerm, rateCap1, rateCap2, marginRate, indexRate, payments, rates) 
{
  //Declare Local Variables
  var currentChange = new Number(0);
  var currentPeriod = new Number(0); 
  var remainingTerm = new Number(0);
  var totalChanges = new Number(0);
  var remainingBalance = new Number(0);
  var monthlyPI = new Nnmber(0);
  var monthlyRate = new Number(0);
  var rateCap = new Number(0);

  monthlyRate = initialRate/12;
  remainingBalance = totalLoanAmt;

  monthlyPI = getMonthlyPayment(loanTerm,initialRate,remainingBalance);

  var li = 0;

  // First set of payments
  for(li = 0; li < firstTerm; li++)
    {
      payments[li] = monthlyPI;
      rates[li] = monthlyRate;
      remainingBalance = remainingBalance - (monthlyPI-((monthlyRate)* remainingBalance));
    }

  // Make adjustment for every subsequent change

  remainingTerm = loanTerm - firstTerm;
  totalChanges = remainingTerm / recurringTerm;
  currentPeriod = firstTerm - 1;

  // Determine remaining payments
  for(currentChange=0; currentChange < totalChanges; currentChange++)
    {
      if (currentChange == 0 )
        {
	  rateCap = rateCap1;
	}
      else
        {
	  rateCap = rateCap2;
	}

      monthlyRate = (monthlyRate * 12 + rateCap) / 12 ;

      // Cannot exceed the index + margin
      if (monthlyRate > ( indexRate + marginRate ) / 12 )
        {
	  monthlyRate = ( indexRate + marginRate ) / 12;
        }

      // Call the external function 
      remainingTerm = loanTerm - currentPeriod - 1;

      monthlyPI = getMonthlyPayment(remainingTerm, monthlyRate*1200, remainingBalance);

      // Second set of payments
      for (li=0; li < recurringTerm; li++)
        {
	  currentPeriod = currentPeriod + 1;
	  payments[fisrtTerm + li] = monthlyPI;
	  rates[firstTerm = li] = monthlyRate;
	  remainingBalance = remainingBalance - (monthlyPI-((monthlyRate)*remainingBalance));

	  if((remainingBalance < 0)||(remainingBalance == 0))
	    {
	      remainingBalance = 0;
	      monthlyPI = 0;
	    }
        }
    }	        
}    


//this method is the transliteration of the AmortScheduleCalculator calculate method
function AmortScheduleCalculatorCalculate(totalLoanAmt, propertyValue, startingInterestRate, startingMonth, startingYear, periodStart, periodEnd, monthlyPrepaidAmt, yearlyPrepaidAmt, lumpSumPrepaidAmt, lumpSumPrepaidMonth, federalTaxRate, monthlyMI, isARM, scheduleTerm, actualTerm, firstTerm, recurringTerm, rateCap1, rateCap2, marginRate, indexRate)
{

  //Declare local variables
  var payCounter = new Number(0);
  var hasPMI = false;
  var prepaying = false;
  var normalBeginningBalance = new Number(0.0);
  var prepaidBeginningBalance = new Number(0.0);
  var normalEndingBalance = new Number(0.0);
  var prepaidEndingBalance = new Number(0.0);
  var normalInterest = new Number(0.0);
  var prepaidInterest = new Number(0.0);
  var normalPrincipal = new Number(0.0);
  var prepaidPrincipal = new Number(0.0);
  var normalPI = new Number(0.0);
  var monthlyPI = new Number(0.0);
  var monthlyPMI = new Number(0.0);
  var currMonthPMI = new Number(0.0);
  var LTV = new Number(0.0);
  var monthlyRate = new Number(0.0);
  var taxSavings = new Number(0.0);
  var tempMonthlyRate = new Number(0.0);
  var currentMonth = new Number(startingMonth); 
  var currentYear = new Number(startingYear); 
  var className = "AmortScheduleCalculator";

  var payments = new Array();
  var rates = new Array();        

  var amortSchedule = new AmortScheduleCalculator();

  var LTV = new Number (0.0);
  var monthlyRate = new Number (0.0);
  var taxSavings = new Number(0.0);
  var tempMonthlyRate = new Number(0.0);
  var paymentNumber = new Number();

  var payments = new Array();
  var rates = new Array();

  var today = new Date();


  if (actualTerm == 0)
    {
      actualTerm = scheduleTerm;
    }

  //Automatically correct the ending month if it is calculated to be greater than the loan term
  if ((periodEnd > 0) && (periodEnd > actualTerm))
    {
      periodEnd = actualTerm;
    }

  //Check for prepay information
  prepaying = (lumpSumPrepaidAmt + yearlyPrepaidAmt + monthlyPrepaidAmt) > 0;

  //DETERMINE THE MONTHLY P&I PAYMENTS
  monthlyRate = (startingInterestRate / 12);

  //Check for an Adjustable Program
  if (isARM)
    {
      getARMPayments(totalLoanAmt,startingInterestRate, scheduleTerm,firstTerm,recurringTerm,rateCap1,rateCap2,marginRate,indexRate,payments,rates);
    }
  else
    {
      //It is a fixed interestRate
      //Get the fixed monthly payments
      monthlyPI = getMonthlyPayment(scheduleTerm, startingInterestRate, totalLoanAmt);
    }

  //Loop through each payment to create the AmortScheduleCalculator 
  for (paymentNumber = 1; ((paymentNumber < actualTerm)||(paymentNumber == actualTerm)); paymentNumber++)
  {                        
    if (paymentNumber == 1)
      {
        normalBeginningBalance = totalLoanAmt;
        prepaidBeginningBalance = totalLoanAmt;
      
        //If we have a propertyValue add PMI to the monthly payment 
        if ((propertyValue > 0) && (totalLoanAmt > 0) && (monthlyMI > 0))
          {
            //Only calculate PMI if we get a propertyValue and PMI
            LTV = totalLoanAmt / propertyValue;
            currMonthPMI = (LTV > 0.80)?monthlyMI:0.0;
          }

        if (currentMonth == 0)
          {
            // Get the current month
            currentMonth = today.getMonth() + 1;
          }

        if (currentYear == 0)
          {
            // Get the current year
            currentYear = today.getFullYear;
          }
      }
    else
      {
        normalBeginningBalance = normalEndingBalance;
        prepaidBeginningBalance = prepaidEndingBalance;
                
        if ((propertyValue > 0) && (normalBeginningBalance > 0) && (monthlyMI > 0))
          { 
            //Only calculate PMI if we get a propertyValue 
	    LTV = normalBeginningBalance / propertyValue;
            currMonthPMI = (LTV > 0.80)?monthlyMI:0.0;
          }

        currentMonth++;

        if (currentMonth > 12)
          {
            currentMonth = 1;
            currentYear++;
          }
      }

    //Check for fixed or variable 
    if (monthlyPI > 0 || (payments.length == 0))
      {
        normalPI = monthlyPI;
        tempMonthlyRate = monthlyRate;
      }
    else
      {
        normalPI = payments[paymentNumber-1];
        tempMonthlyRate = rates[paymentNumber-1];
      }

    if (Math.round(normalBeginningBalance) == 0)
      {
        normalInterest = 0;
        normalPrincipal = 0;
      }
    else
      {
        normalInterest = normalBeginningBalance * tempMonthlyRate;
        normalPrincipal = normalPI - normalInterest;
        //Start calculating tax savings per month 
        if (federalTaxRate > 0)
          {
            taxSavings = normalInterest * federalTaxRate;
          }

        if (Math.round(prepaidBeginningBalance) == 0 )
          {
            prepaidInterest = 0;
            prepaidPrincipal = 0;
          }
        else
          {
            prepaidInterest = prepaidBeginningBalance * tempMonthlyRate;
            
            //Add any monthly Prepayment 
            prepaidPrincipal = normalPI + monthlyPrepaidAmt - prepaidInterest;

            //Add any yearly Prepayment 
            if (yearlyPrepaidAmt > 0 && paymentNumber % 12 == 0)
              {
                prepaidPrincipal = prepaidPrincipal + yearlyPrepaidAmt; 
              }

            //Add any Lump Sum Payment 
            if (lumpSumPrepaidMonth == paymentNumber)
              {
                prepaidPrincipal = prepaidPrincipal + lumpSumPrepaidAmt;
              }

            // Make sure we stop after the loan has been paid off
            if (prepaidPrincipal > prepaidBeginningBalance)
              {
                prepaidPrincipal = prepaidBeginningBalance;
              }
          }
      }

    normalEndingBalance = normalBeginningBalance - normalPrincipal;
    prepaidEndingBalance = prepaidBeginningBalance - prepaidPrincipal;

    if (Math.round(normalEndingBalance) == 0 )
      {
        normalEndingBalance = 0;
      }

    if (Math.round(prepaidEndingBalance) == 0 )
      {
        prepaidEndingBalance = 0;
      }
      
    if (!prepaying)
      {
        prepaidPrincipal = 0;
        prepaidInterest = 0;
        prepaidBeginningBalance = 0;
        prepaidEndingBalance = 0;
      }
            
      //Only send back result set requested by user
      if ((paymentNumber < periodStart) || (paymentNumber > periodEnd))
        {
          continue;
        }
      else
        {
          //Build an object of named arrays as the result 
          amortSchedule.paymentNumber[payCounter] = paymentNumber;
          amortSchedule.month[payCounter] = currentMonth;
          amortSchedule.year[payCounter] = currentYear;
          amortSchedule.principal[payCounter] = normalPrincipal;
          amortSchedule.interest[payCounter] = normalInterest;
          amortSchedule.beginningBalance[payCounter] = normalBeginningBalance;
          amortSchedule.endingBalance[payCounter] = normalEndingBalance;
          amortSchedule.interestRate[payCounter] = tempMonthlyRate * 12;
          amortSchedule.prepaidPrincipal[payCounter] = prepaidPrincipal;
          amortSchedule.prepaidInterest[payCounter] = prepaidInterest;
          amortSchedule.prepaidBeginBalance[payCounter] = prepaidBeginningBalance;
          amortSchedule.prepaidEndBalance[payCounter] = prepaidEndingBalance;
          amortSchedule.taxSavings[payCounter] = taxSavings;
          amortSchedule.PMI[payCounter] = currMonthPMI;
          amortSchedule.monthlyPayment[payCounter] = normalPrincipal + normalInterest + currMonthPMI;

          amortSchedule.payCount = ++payCounter;
          amortSchedule.totalTaxSavings += taxSavings;
          amortSchedule.totalNormalPrincipal += normalPrincipal; 
          amortSchedule.totalNormalInterest += normalInterest; 
          amortSchedule.totalPMI += currMonthPMI;
          amortSchedule.totalPrepaidSavings += (normalPrincipal + normalInterest) - (prepaidPrincipal + prepaidInterest);
        }            
    }
                
  return amortSchedule;        
}

//Send this function a string and if it needs comman and zeroes appropriately
//it will send them back with commas and decimals

function commasDecimals(fixit)
{

var tempString = "";

  //MAKE SURE THAT THE LAST 3 DIGITS = ".00"
  if ((fixit.indexOf('.') == (fixit.length - 2))&&(fixit.length != 1))
    {
      fixit += "0";
    }
  else if ((fixit.indexOf('.') == (fixit.length - 1))&&(fixit.length != 1))
    {
      fixit += "00";
    }
  else if (fixit.indexOf('.') == -1 )
    {
      fixit += ".00";
    }

  //Now, Add commas
  if (fixit.substring(fixit.indexOf('.'),0).length > 3)
    {
      //Add first comma, based on length of number from decimal
      tempString = fixit.substring(fixit.indexOf('.')-3,0) + "," + fixit.substring(fixit.length,fixit.indexOf('.')-3);
      fixit = tempString;

      //Now add more commas while necessary, based on length of number from first visible comma in the string
      while (fixit.indexOf(",") > 3)
        {
          tempString = fixit.substring(fixit.indexOf(',')-3,0) + "," + fixit.substring(fixit.length,fixit.indexOf(',')-3);
          fixit = tempString;
        }
    }

  //remove potential error "-," for negative numbers a multiple of 3 digits in length
  if ((fixit.indexOf('-') == 0)&&(fixit.indexOf(',') == 1))
    {
      tempString = "-" + (fixit.substring(fixit.length,fixit.indexOf(',')+1));
      fixit = tempString;
    }

  //Fix requested by Jennifer Kohl - remove everything decimal and after - this is what is done in the application
  tempString = fixit.substring(0,fixit.indexOf('.'));
  fixit = tempString;

    return fixit;
}

//Within this file lives the constructor, the calculate, and the accessor 
//methods for EstimatedClosingCosts
//Note:  I DID NOT overload the calculate function

function EstimatedClosingCosts()
{
  //Define variables
  this.className = "EstimatedClosingCosts";

  this.calculate = EstimatedClosingCostCalculate;

  return this;
}

function EstimatedClosingCostCalculate(loanAmt, loanTerm, interestRate, programPoints, downPaymentAmt, closingDate)
{

  //Define Local Variables
  var TAXSERVICEFEE = new Number(75);
  var FEETOCHARGE = new Number (350);
  var CREDITREPORTFEE = new Number(20.7);
  var APPRAISALFEE = new Number(300);
  var FLOODCERTFEE = new Number(15.5);
  var DEFAULTRATE = new Number(0.08);
  var DEFAULTLOANAMT = new Number(100000);
  var DEFAULTTERM = new Number(360);
  var DEFAULTINTERESTDAYS = new Number(15);

  var today = new Date();

  //Approximate the Loan Amount, if none passed in
  if (loanAmt == null)
    {
      var loanAmt = new Number(DEFAULTLOANAMT);
    }        
  
  //Determine LoanType and Term, if possible
  if (loanTerm == null)
    {
      var loanTerm = new Number(DEFAULTTERM);
    }
    
  //Determine Mortgage Insurance, based on LTV
  if (downPaymentAmt == null)
    {
      var downPaymentAmt = new Number(0);
    }

  if (interestRate == null)
    {
      var interestRate = new Number(DEFAULTRATE);
    }
  
  // Calculate any MI
  var monthlyMI = new Number(PMICalculator(loanAmt,downPaymentAmt));

  // 2 months prepaid MI
  var MIFee = new Number(2*monthlyMI);

  var interestDays = DEFAULTINTERESTDAYS;

  if (closingDate != null)
    {            
      interestDays = today.getDate();
    }

  var prePaidInterest = new Number(interestRate/365 * loanAmt * interestDays);
  
  // determine origination fee
  var originationFee = new Number(0);
  if (programPoints == null)
    {
      programPoints = new Number(0);
    }
  else if ((programPoints > 0.01)||(programPoints == 0.01))
    {
      originationFee = 0.01 * loanAmt;
    }

  // determine discount points
  var discountPoints = new Number(0);
  if (programPoints > .01)
    {
      discountPoints = (programPoints - 0.01) * loanAmt;
    }
  else if ((programPoints > 0)&&(programPoints < 0.01))
    {
      discountPoints = programPoints * loanAmt;
    }

  var paidByLender = new Number(0);
  if (programPoints < 0.0)
    {
      paidByLender = programPoints * loanAmt;
    }

  return (TAXSERVICEFEE + FEETOCHARGE + CREDITREPORTFEE + APPRAISALFEE + FLOODCERTFEE + paidByLender + discountPoints + originationFee + prePaidInterest + MIFee);

}


//Send this a number, and this function will return the number
//to two significant decimal places.

function floor(number)
{
  return Math.floor(number*Math.pow(10,2))/Math.pow(10,2);
}

//Send this a term, interestRate (a decimal), and a balance and this function
// will return a monthly payment

function getMonthlyPayment(scheduleTerm, startingInterestRate, totalLoanAmt)
{
  return (totalLoanAmt*(startingInterestRate/12))/(1-Math.pow((1+(startingInterestRate/12)),(-1*scheduleTerm)));
}

function getLoanAmountFromMonthlyPayment(scheduleTerm, startingInterestRate)
{
	var irrate = eval(startingInterestRate/1200);
  return (irrate+(irrate/(Math.pow((1+irrate),scheduleTerm)-1)))*1000;
}

//Send this function a loan amount and a down Payment, ant it will return
//your monthlyMI

function PMICalculator (loanAmt, downPaymentAmt)
{
  var loanAmount = new Number(loanAmt);
  var salesPrice = new Number(loanAmount + downPaymentAmt);
  var LTV = loanAmount/salesPrice;
  var PMIRate = true;
  var LTVThreshold = 0.8;
  var monthlyMI = new Number(0.0);

  if (LTV < LTVThreshold)
	{
        PMIRate = false;
    }

  if (PMIRate)
	 {
		if ((LTV < 0.85)||(LTV == 0.85))
		  {
			PMIRate = 0.0032;
		  }
		else if ((LTV < 0.90)||(LTV == 0.90))
		  {
			PMIRate = 0.0052;
		  }
		else if ((LTV < 0.95)||(LTV == 0.95))
		  {
			PMIRate = 0.0078;
		  }
		else
		  {
			PMIRate = 0.0090;
		  }

        monthlyMI = loanAmt * PMIRate/12;
	}

  return monthlyMI;
}

//This is the constructor, the calculate method and the accessor methods
//for the RentVsBuyCalculator

//Define global variables
var DEFAULT_INVESTMENT_RATE = new Number(0.08);

//ownership benefit accessor method
function getOwnershipBenefit()
{
  if ((this.rentingCost - this.ownershipCost) >0)
    {
      return (this.rentingCost - this.ownershipCost);
    }
  else
    {
      return 0;
    }
}

//renting cost accessor method
function getRentingCost()
{
  return this.rentingCost;
}

//ownership cost accessor method
function getOwnershipCost()
{
  return this.ownershipCost;
}

//tax savings accessor method
function getTaxSavings()
{
  return this.taxSavings;
}

//closing costs accessor method
function getClosingCosts()
{
  return this.closingCosts;
}

//gross costs accessor method
function getGrossCosts()
{
  return this.grossCosts;
}

//equity earned accessor method
function getEquityEarned()
{
  return this.equityEarned;
}

//potential savings accessor method
function getPotentialSavings()
{
  return ((this.rentingCost - this.ownershipCost) * DEFAULT_INVESTMENT_RATE);
}

//this method is the new AmortScheduleCalculator object constructor
function RentVsBuyCalculator()
{
  //variables
  this.rentingCost = new Number();
  this.ownershipCost = new Number();
  this.taxSavings = new Number();
  this.closingCosts = new Number();
  this.equityEarned = new Number();
  this.grossCosts = new Number();
  this.className = "RentVsBuyCalculator";

  //methods
  this.getOwnershipBenefit = getOwnershipBenefit;
  this.getRentingCost = getRentingCost;
  this.getTaxSavings = getTaxSavings;
  this.getClosingCosts = getClosingCosts;
  this.getGrossCosts = getGrossCosts;
  this.getEquityEarned = getEquityEarned;
  this.getPotentialSavings = getPotentialSavings;
  this.calculate = RentVsBuyCalculatorCalculate;
  
  return this;
}



// this is the calculate method
function RentVsBuyCalculatorCalculate (salesPrice, interestRate, loanAmt, loanTerm, monthlyMI, federalTaxRate, appreciationRate, discountPoints, expectedYearsToOwn, monthlyRent, annualRentIncrease, annualPropertyTax, annualMiscOwnershipFees, annualMiscRentalFees)
{
  var totalAppreciation = new Number(0);
  var totalPrincipalPaid = new Number(0);
  var totalInterestPaid = new Number(0);
  var totalPMI = new Number(0);
  var year = new Number(0);

  var rvb = new RentVsBuyCalculator();

  var amort = new AmortScheduleCalculator();
  amort = amort.calculate(loanAmt,salesPrice,interestRate,0,0,1,expectedYearsToOwn*12,0,0,0,0,federalTaxRate,monthlyMI,false,loanTerm,loanTerm,0,0,0,0,0,0);

  totalPrincipalPaid = amort.getTotalNormalPrincipal();        
  totalInterestPaid = amort.getTotalNormalInterest();        
  totalPMI = amort.getTotalPMI();        
  var annualRent = monthlyRent * 12;

  // Forcast appreciation/increases
    for (year = 0; year < expectedYearsToOwn; year++)
      {
        // Calculate all of the rental costs for the term expected
        rvb.rentingCost += annualRent;
        annualRent += annualRent * annualRentIncrease;
                 
        // Calculate the annual appreciation in equity
        if (year > 0)
          {
            totalAppreciation += salesPrice * appreciationRate;
          }
      }

  rvb.rentingCost += (annualMiscRentalFees * expectedYearsToOwn);

  rvb.equityEarned = (salesPrice + totalAppreciation + totalPrincipalPaid - loanAmt);


  // Calculate annual property tax if not passed, use 1.5% as default
  //   if (annualPropertyTax == 0)
  //       annualPropertyTax = ( salesPrice * DEFAULT_PROPERTY_TAX_RATE );

  // Calculate total tax savings (interest, property tax, closing costs)
  var totalPropertyTax = new Number(annualPropertyTax * expectedYearsToOwn);

  rvb.taxSavings = amort.getTotalTaxSavings() + (totalPropertyTax * federalTaxRate) + (discountPoints * loanAmt * federalTaxRate);

  // Get closing costs
  var closingTemp = new EstimatedClosingCosts();
  
  rvb.closingCosts = closingTemp.calculate(loanAmt, loanTerm, interestRate, discountPoints, (salesPrice - loanAmt));

  rvb.ownershipCost = (totalInterestPaid + totalPrincipalPaid + totalPMI + totalPropertyTax + rvb.closingCosts + (annualMiscOwnershipFees * expectedYearsToOwn)) - (rvb.taxSavings + rvb.equityEarned);
                                
  rvb.grossCosts= (totalInterestPaid + totalPrincipalPaid + totalPMI + totalPropertyTax + rvb.closingCosts + (annualMiscOwnershipFees * expectedYearsToOwn));

  return rvb;
}









//Affordability Calculator
//RESULTS VARIABLES
var moPay, loanAmt, purPrice, downPymt, closCosts, LoanAmount, debtRatio, x = "";

//GLOBAL VARIABLES
var i, ii, iii = 0;

function Affordcalculate() {

     var i = eval(document.affordability.afford_interest.value) * 100;
		 var t = eval(document.affordability.term.value*12);
		 var ii = getLoanAmountFromMonthlyPayment(t, i)

/*

     if ((i >= 6.0) && ( i < 6.25 )) {
         ii = 6.0
         iii = 8.44
     }
     if ((i >= 6.0) && ( i < 6.25 )) {
         ii = 6.0
         iii = 8.44
     }
     if ((i >= 6.0) && ( i < 6.25 )) {
         ii = 6.0
         iii = 8.44
     }
     if ((i >= 6.0) && ( i < 6.25 )) {
         ii = 6.0
         iii = 8.44
     }


     if ((i >= 6.0) && ( i < 6.25 )) {
         ii = 6.0
         iii = 8.44
     }
     if ((i >= 6.0) && ( i < 6.25 )) {
         ii = 6.0
         iii = 8.44
     }
     if ((i >= 6.0) && ( i < 6.25 )) {
         ii = 6.0
         iii = 8.44
     }
     if ((i >= 6.0) && ( i < 6.25 )) {
         ii = 6.0
         iii = 8.44
     }


     if ((i >= 6.0) && ( i < 6.25 )) {
         i40 = 6.0
         i30 = 6.0
         i20 = 6.0
         i15 = 8.44
     }
     if ((i >= 6.25) && ( i < 6.5 )) {
         i40 = 6.16
         i30 = 6.16
         i20 = 6.16
         i15 = 8.57
     }
     if ((i >= 6.50) && ( i < 6.75 )) {
         i40 = 6.32
         i30 = 6.32
         i20 = 6.32
         i15 = 8.71
     }
     if ((i >= 6.75) && ( i <7.0 )) {
         i30 = 6.49
         i15 = 8.85
     }
     if ((i >= 7.0) && ( i < 7.25 )) {
         i30 = 6.65
         i15 = 8.99
     }
     if ((i >= 7.25) && ( i < 7.5 )) {
         i30 = 6.82
         i15 = 9.13
     }
     if ((i >= 7.50) && ( i < 7.75 )) {
         i30 = 6.99
         i15 = 9.27
     }
     if ((i >= 7.75) && ( i < 8.0 )) {
         i30 = 7.16
         i15 = 9.41
     }
     if ((i >= 8.0) && ( i < 8.25 )) {
         i30 = 7.34
         i15 = 9.56
     }
     if ((i >= 8.25) && ( i < 8.5 )) {
         i30 = 7.51
         i15 = 9.70
     }
     if ((i >= 8.50) && ( i < 8.75 )) {
         i30 = 7.69
         i15 = 9.85
     }
     if ((i >= 8.75) && ( i < 9.0 )) {
         i30 = 7.87
         i15 = 9.99
     }
     if ((i >= 9.0) && ( i < 9.25 )) {
         i30 = 8.05
         i15 = 10.14
     }
     if ((i >= 9.25) && ( i < 9.5 )) {
         i30 = 8.23
         i15 = 10.29
     }
     if ((i >=9.50) && ( i < 9.75 )) {
         i30 = 8.41
         i15 = 10.44
     }
     if ((i >= 9.75) && ( i < 10.0 )) {
         i30 = 8.59
         i15 = 10.59
     }
     if ((i >= 10.0) && ( i < 10.25 )) {
         i30 = 8.78
         i15 = 10.75
         IntDisp = 10.0
     }
     if ((i >= 10.25) && ( i < 10.5 )) {
         i30 = 8.96
         i15 = 10.90
     }
     if ((i >=10.50) && ( i < 10.75 )) {
         i30 = 9.15
         i15 = 11.05
         IntDisp = 10.5
     }
     if ((i >= 10.75) && ( i < 11.0 )) {
         i30 = 9.33
         i15 = 11.21
     }
     if ((i >= 11.0) && ( i < 11.25 )) {
         i30 = 9.53
         i15 = 11.37
         IntDisp = 11.0
     }
     if ((i >= 11.25) && ( i < 11.5 )) {
         i30 = 9.72
         i15 = 11.53
     }
     if ((i >=11.50) && ( i < 11.75 )) {
          i30 = 9.91
          i15 = 11.69
     }
     if ((i >= 11.75) && ( i < 12.0 )) {
           i30 = 10.10
           i15 = 11.85
     }
     if ((i >= 12.0) && ( i < 12.25 )) {
            i30 = 10.29
            i15 = 12.01
     }
     if ((i >= 12.25) && ( i < 12.5 )) {
            i30 = 10.48
            i15 = 12.17
     }
     if ((i >=12.50) && ( i < 12.75 )) {
            i30 = 10.68
            i15 = 12.33
    }
     if ((i >= 12.75) && ( i < 13.0 )) {
            i30 = 10.87
            i15 = 12.49
    }*/

     var DebtAmount = document.affordability.afford_debt.value;

     //represents max monthly debt allowed at 35% back ratio
     var moIncome = document.affordability.afford_income.value / 12;
     var y = moIncome * .36;

     //verifies the debt to income ratio
     var debtRatio = y - DebtAmount;
         if (debtRatio < 0) {
             alert ("Prior to performing calculations, this calculator verifies that your debt does not exceed 35% of your income.  The amounts you entered exceed this debt-to-income ratio and therefore we are unable to present you with a maximum loan amount.  Please check that you have not included housing costs in your monthly debts.")
            return false;
        }
        else
        {
            debtRatio = debtRatio;
        }

    //calculates monthly closing cost amount at 2.5%
     var closMoAmt = debtRatio * .25;

     //max P&I allowed after closing and .35 ratio are backed out
     var IncCalc = debtRatio - closMoAmt;

     moPay = IncCalc.toString();

        //if (document.affordability.term.value == "40" ) {
            var LoanAmount = IncCalc / ii;
        //}
				/*
        if (document.affordability.term.value == "30" ) {
            var LoanAmount = IncCalc / i30;
        }
        if (document.affordability.term.value == "20" ) {
            var LoanAmount = IncCalc / i20;
        }
        if (document.affordability.term.value == "15" ) {
            var LoanAmount = IncCalc / i15;
        }*/
    LoanAmount = floor(LoanAmount * 1000);
    var x = eval(document.affordability.afford_closing.value);
     var SalesPrice = floor(LoanAmount + x);
    var purClos = SalesPrice * .025;

    //if funds available are less than closing costs do not show down payment amount
    var downPayment = floor(document.affordability.afford_closing.value - purClos);
    if (downPayment < 0) {
            downPayment = 0;
            purPrice = SalesPrice.toString();
        }
        else
        {
            downPayment = downPayment;
            purPrice = floor(SalesPrice - purClos).toString();
    }

    loanAmt = LoanAmount.toString();
    //closing cost is the home purch price * estimated 2.5% closing costs
    downPymt = downPayment.toString();
    closCost = purClos.toString();
}

//Browsercheck
var ie = document.all?1:0;
var n = document.layers?1:0;

//This checks for Netscape 6.2 or Greater
var gecko = ((navigator.appName == "Netscape")&&((navigator.appVersion.substring(0,3)==5)||(navigator.appVersion.substring(0,3)>5)))?1:0;

function makeChangeResultsObj(obj)
{
    this.writeref = (n) ? eval('document.'+ obj +'.document') : eval(obj);
    this.writeIt = b_writeIt;
}

function b_writeIt(text)
{
  if(n)
    {
      this.writeref.write(text);
      this.writeref.close();
    }
  else if(ie)
    {
     this.writeref.innerHTML=text;
    }

//ADDED FOR 6.X COMPLIANCE - NEW CHANGE METHOD
  else if(gecko)
    {
     this.innerHTML=text;
    }
}

function AffordshowResults()
{
  moPay = commasDecimals(moPay);
  loanAmt = commasDecimals(loanAmt);
  purPrice = commasDecimals(purPrice);
  downPymt = commasDecimals(downPymt);
  closCost = commasDecimals(closCost);

    //BUILDS RESULTS
    var changeMsg =
    "<table id='affordability_result'>" +
    "  <tr>" +
    "    <th colspan=\"2\">Your results:</th>" +
		"  </tr>" +	
    "  <tr>" +
    "    <td colspan=\"2\">We estimate the maximum amount you can afford to be:</th>" +
		"  </tr>" +	
    "  <tr>" +
		"		 <td>Monthly payment</td><td class='result'>$" + moPay +"</td>" +
    "  </tr>" +
    "  <tr>" +
		"    <td>Loan amount</td><td class='result'>$" + loanAmt + "</td>" +
		"	 </tr>" +
    "  <tr>" +
		"		 <td>Home purchase price</td><td class='result'>$" + purPrice + "</td>" +
    "  </tr>" +
    "  <tr>" +
		"		 <td>Down payment</td><td class='result'>$" + downPymt + "</td>" +
    "  </tr>" +
    "  <tr>" +
		"		 <td>Closing costs</td><td class='result'>$" + closCost + "</td>" +
    "  </tr>" +
    "  <tr>" +
		"		 <td colspan=\"2\"><B>Note:</B> <i>Estimates are computed using 2.5% estimated closing costs.  To determine funds needed to close, you will need to combine the down payment and closing costs amounts indicated.</i></td>" +
    "  </tr>" +
    "</TABLE>";

    if(ie || n)
    {
      oMessage=new makeChangeResultsObj('objResults');
      oMessage.writeIt(changeMsg);
    }

      //ADDED FOR 6.X COMPLIANCE - NEW CHANGE METHOD
    else if (gecko)
    {
      var results = document.getElementById("objResults");
      results.writeIt = b_writeIt;
      results.writeIt(changeMsg);
    }
}

function isBlank(data)
{
  if (data.length == 0)
      return 1;

  for (i = 0; i < (data.length); i++)
    {
      if (data.charAt(i) != " ")
        return 0;
    }

  return 1;
}

function isNumOnly(data)
{
  var i = new Number(data.length);
  var j = new Number(0);
  var k = new Number();

  for (j=0; j < i; j++) {
      if ((isNaN(data.charAt(j)) == true))
        return 0;
    }
    return 1;
}

function isInvalidCharacter(data)
{
  for (i=0; i < data.length; i++) {
      if ((data.charAt(i)=="~")||(data.charAt(i)=="!")||(data.charAt(i)=="@")||(data.charAt(i)=="#")
        ||(data.charAt(i)=="$")||(data.charAt(i)=="%")||(data.charAt(i)=="^")||(data.charAt(i)=="&")
        ||(data.charAt(i)=="*")||(data.charAt(i)=="(")||(data.charAt(i)==")")||(data.charAt(i)=="_")
        ||(data.charAt(i)=="+")||(data.charAt(i)=="=")||(data.charAt(i)=="{")||(data.charAt(i)=="[")
        ||(data.charAt(i)=="|")||(data.charAt(i)=="<")||(data.charAt(i)==",")||(data.charAt(i)==">")
        ||(data.charAt(i)=="}")||(data.charAt(i)=="]")||(data.charAt(i)=="?")||(data.charAt(i)=="/"))
        {
          return 1;
        }
    }
  return 0;
}

function isAlphaOnly(data, characterTest, spaceTest)
{
  i = new Number(data.length);
  j = new Number(0);

  if (characterTest == 0)
    {
      if (isInvalidCharacter(data) == 1)
          return 0;
    }

  if (spaceTest == 0)
    {
      for (j=0; j < i; j++)
        {
          if (data.charAt(j) == " ")
              return 0;
        }
    }

  for (j=0; j < i; j++)
    {
      if (isNaN(data.charAt(j)) == false)
      return 0;
    }
  if ((j==i)&&(i!=0))
      return 1;
}

function isExactLength(data, num)
{

  var howLong = new Number(data.length);
  var rightLength = new Number(num);

  return ((howLong < rightLength)||(howLong > rightLength));
}

function isMinAndMaxLength(data, min, max)
{
  var minimum = new Number(min);
  var maximum = new Number(max);

  return ((data.length < minimum) || (data.length > maximum));
}

function isBetweenMinAndMax(data, min, max)
{
  return ((data < min)||(data > max));
}

function AffordcheckForm(form)
{
  var errorMsg = "";
  var i;
  var message = new Array();
  var inputs = new Array(form.length);

  var income, debt, closing = "";

  for (i = 0; i < form.length; i++)
    {
       inputs[i] = form.elements[i].name;
    }

  for (i = 0; i < form.length; i++)
    {
      if (inputs[i] == "afford_income")
          income = i;
      else if (inputs[i] == "afford_debt")
          debt = i;
      else if (inputs[i] == "afford_closing")
          closing = i;
    }

  message[0] = "Please enter your annual income.\n";
  message[1] = "The amount entered for your annual income should be free of special characters or letters.\n";
  message[2] = "Your annual income should be $0 or more and less than $1,000,000.\n"
  message[3] = "Please enter the amount of total monthly debt.\n";
  message[4] = "The amount for total monthly debt should be free of special characters or letters.\n";
  message[5] = "The amount for total monthly debt should be $0 or more and less than $1,000,000.\n";
  message[6] = "Please enter the amount of cash down and downpayment.\n";
  message[7] = "The amount for cash down and downpayment should be free of special characters or letters.\n";
  message[8] = "The value for cash down and downpayment should be between $0 and $1,000,000.\n"

  if (isBlank(form.elements[income].value) == 1)
      errorMsg += message[0];
  else if (isNaN(form.elements[income].value) == true)
      errorMsg += message[1];
  else if ((form.elements[income].value < 0)||(form.elements[income].value >= 1000000))
      errorMsg += message[2];

  if (isBlank(form.elements[debt].value) == 1)
      errorMsg += message[3];
  else if (isNaN(form.elements[debt].value) == true)
      errorMsg += message[4];
  else if ((form.elements[debt].value < 0)||(form.elements[debt].value >= 1000000))
      errorMsg += message[5];

  if (isBlank(form.elements[closing].value) == 1)
      errorMsg += message[6];
  else if (isNaN(form.elements[closing].value) == true)
      errorMsg += message[7];
  else if ((form.elements[closing].value <= 0)||(form.elements[closing].value >= 1000000))
      errorMsg += message[8];

//No need to return anything here
  if (errorMsg.length == 0)
    {
//If there's no error message, calculate
      Affordcalculate();
      AffordshowResults();
    }
  else
    {
//If there's an error message, just show it
      alert("Before continuing, the following fields require attention:\n\n" + errorMsg);
    }
}





// Monthly Payment Calculator

//RESULTS VARIABLES
var principalInterest, monthlyMI, monthlyTax, monthlyInsurance, monthlyPayment, homeownDues = "";

function MonthlyPaycalculate() {
  var downPayment = document.monthlypayments.monthly_payments_home_price.value - document.monthlypayments.monthly_payments_loan_amount.value;
  var LTV = document.monthlypayments.monthly_payments_loan_amount.value/document.monthlypayments.monthly_payments_home_price.value;
  var PMIRate = true;
  var LTVThreshold = 0.8;

	if (LTV < LTVThreshold)
	{
        PMIRate = false;
    }

	if (PMIRate)
	 {
		if ((LTV < 0.85)||(LTV == 0.85))
		{
			PMIRate = 0.0032;
		}
		else if ((LTV < 0.90)||(LTV == 0.90))
		{
			PMIRate = 0.0052;
		}
		else if ((LTV < 0.95)||(LTV == 0.95))
		{
			PMIRate = 0.0078;
		}
		else
		{
			PMIRate = 0.0090;
		}
	}

  var mi = document.monthlypayments.monthly_payments_interest_rate.value / 1200;
  var base = 1;
  var mbase = 1 + mi;

  for (i=0; i<document.monthlypayments.monthly_payments_loan_term.value * 12; i++)
  {
    base = base * mbase
  }

  //These calculations make the same changes, but apply the values to JavaScript variables (as strings)
  principalInterest = floor(document.monthlypayments.monthly_payments_loan_amount.value * mi / ( 1 - (1/base)) + 0.5).toString();
  monthlyMI = floor(document.monthlypayments.monthly_payments_loan_amount.value * (PMIRate / 12)).toString();
  monthlyTax = floor(document.monthlypayments.monthly_payments_property_taxes.value / 12).toString();
  monthlyInsurance = floor(document.monthlypayments.monthly_payments_hazard_insurance.value / 12).toString();
  var dasum = document.monthlypayments.monthly_payments_loan_amount.value * mi / ( 1 - (1/base)) + document.monthlypayments.monthly_payments_property_taxes.value / 12 + document.monthlypayments.monthly_payments_hoa_dues.value / 12 + document.monthlypayments.monthly_payments_loan_amount.value * (PMIRate / 12) + document.monthlypayments.monthly_payments_hazard_insurance.value / 12;
  monthlyPayment = floor(dasum).toString();
  homeownDues = floor(document.monthlypayments.monthly_payments_hoa_dues.value / 12).toString();

}

//Browsercheck
var ie = document.all?1:0;
var n = document.layers?1:0;
//This checks for Netscape 6.2 or Greater
var gecko = ((navigator.appName == "Netscape")&&((navigator.appVersion.substring(0,3)==5)||(navigator.appVersion.substring(0,3)>5)))?1:0;

function makeChangeResultsObj(obj)
{
    this.writeref = (n) ? eval('document.'+ obj +'.document') : eval(obj);
    this.writeIt = b_writeIt;
}

function b_writeIt(text)
{
  if(n)
    {
      this.writeref.write(text);
      this.writeref.close();
    }
  else if(ie)
    {
     this.writeref.innerHTML=text;
    }

  //ADDED FOR 6.X COMPLIANCE - NEW CHANGE METHOD
  else if(gecko)
    {
     this.innerHTML=text;
    }
}

function MonthlyPayshowResults()
{
  principalInterest = commasDecimals(principalInterest);
  monthlyMI = commasDecimals(monthlyMI);
  monthlyTax = commasDecimals(monthlyTax);
  monthlyPayment = commasDecimals(monthlyPayment);
  monthlyInsurance = commasDecimals(monthlyInsurance);
  homeownDues = commasDecimals(homeownDues);

	//BUILDS RESULTS
	var changeMsg =
    "<table id='monthlypayment_result'>" +
    "  <tr>" +
    "    <th colspan=\"2\">Your results:</th>" +
		"  </tr>" +	
    "  <tr>" +
		"		 <td>Your estimated monthly principal and interest payment is</td><td class='result'>$" + principalInterest +"</td>" +
    "  </tr>" +
    "  <tr>" +
		"    <td>Your estimated monthly private mortgage insurance payment is</td><td class='result'>$" + monthlyMI + "</td>" +
		"	 </tr>" +
    "  <tr>" +
		"		 <td>Your estimated monthly property tax payment is</td><td class='result'>$" + monthlyTax + "</td>" +
    "  </tr>" +
    "  <tr>" +
		"		 <td>Hazard Insurance</td><td class='result'>$" + monthlyInsurance + "</td>" +
    "  </tr>" +
    "  <tr>" +
		"		 <td>Homeowner's Association Dues</td><td class='result'>$" + homeownDues + "</td>" +
    "  </tr>" +
    "  <tr>" +
		"		 <td>Your total estimated monthly payment is</td><td class='result'>$" + monthlyPayment + "</td>" +
    "  </tr>" +
    "</TABLE>";


    if(ie || n)
    {
      oMessage=new makeChangeResultsObj('MonthlyobjResults');
      oMessage.writeIt(changeMsg);
    }

      //ADDED FOR 6.X COMPLIANCE - NEW CHANGE METHOD
    else if (gecko)
    {
      var results = document.getElementById("MonthlyobjResults");
      results.writeIt = b_writeIt;
      results.writeIt(changeMsg);
    }
}

function isBlank(data)
{
  if (data.length == 0)
      return 1;

  for (i = 0; i < (data.length); i++)
    {
      if (data.charAt(i) != " ")
        return 0;
    }

  return 1;
}

function isNumOnly(data)
{
  var i = new Number(data.length);
  var j = new Number(0);
  var k = new Number();

  for (j=0; j<i; j++)
    {
      if ((isNaN(data.charAt(j)) == true))
	    return 0;
    }
    return 1;
}

function isInvalidCharacter(data)
{
  for (i=0; i<data.length; i++)
    {
      if ((data.charAt(i)=="~")||(data.charAt(i)=="!")||(data.charAt(i)=="@")||(data.charAt(i)=="#")
        ||(data.charAt(i)=="$")||(data.charAt(i)=="%")||(data.charAt(i)=="^")||(data.charAt(i)=="&")
        ||(data.charAt(i)=="*")||(data.charAt(i)=="(")||(data.charAt(i)==")")||(data.charAt(i)=="_")
        ||(data.charAt(i)=="+")||(data.charAt(i)=="=")||(data.charAt(i)=="{")||(data.charAt(i)=="[")
        ||(data.charAt(i)=="|")||(data.charAt(i)=="<")||(data.charAt(i)==",")||(data.charAt(i)==">")
        ||(data.charAt(i)=="}")||(data.charAt(i)=="]")||(data.charAt(i)=="?")||(data.charAt(i)=="/"))
        {
          return 1;
        }
    }
  return 0;
}

function isAlphaOnly(data, characterTest, spaceTest)
{
  i = new Number(data.length);
  j = new Number(0);

  if (characterTest == 0)
    {
      if (isInvalidCharacter(data) == 1)
          return 0;
    }

  if (spaceTest == 0)
    {
      for (j=0; j<i; j++)
        {
          if (data.charAt(j) == " ")
              return 0;
        }
    }

  for (j=0; j<i; j++)
    {
      if (isNaN(data.charAt(j)) == false)
	  return 0;
    }
  if ((j==i)&&(i!=0))
      return 1;
}

function isExactLength(data, num)
{

  var howLong = new Number(data.length);
  var rightLength = new Number(num);

  return ((howLong < rightLength)||(howLong > rightLength));
}

function isMinAndMaxLength(data, min, max)
{
  var minimum = new Number(min);
  var maximum = new Number(max);

  return ((data.length < minimum) || (data.length > maximum));
}

function isBetweenMinAndMax(data, min, max)
{
  return ((data < min)||(data > max));
}

function checkForm(form)
{
  var errorMsg = "";
  var i;
  var message = new Array();
  var inputs = new Array(form.length);

  var interestrate, loanamount, propertytaxes, hazardinsurance, hoadues = "";

  var homeprice = "";

  for (i = 0; i < form.length; i++)
    {

       inputs[i] = form.elements[i].name;
    }

  for (i = 0; i < form.length; i++)
    {
      if (inputs[i] == "monthly_payments_interest_rate")
          interestrate = i;
      else if (inputs[i] == "monthly_payments_loan_amount")
          loanamount = i;
      else if (inputs[i] == "monthly_payments_home_price")
          homeprice = i;
      else if (inputs[i] == "monthly_payments_property_taxes")
          propertytaxes = i;
      else if (inputs[i] == "monthly_payments_hazard_insurance")
          hazardinsurance = i;
      else if (inputs[i] == "monthly_payments_hoa_dues")
          hoadues = i;
    }


  message[0] = "Please enter your interest rate.\n";

  message[1] = "The value for interest rate should be free of special characters or letters.\n";
  message[2] = "The value for interest rate should be greater than 0% and less than 51%.\n";
  message[3] = "Please enter your loan amount.\n";
  message[4] = "Your loan amount should be free of special characters or letters.\n";
  message[5] = "Your loan amount should be greater than $20000 and less than $1,000,000,000.\n";
  message[6] = "Your property taxes value should be free of special characters or letters.\n";
  message[7] = "Your property taxes value should be a minimum of $0 and less than $1,000,000,000.\n";
  message[8] = "Your hazard insurance value should be free of special characters or letters.\n";
  message[9] = "Your hazard insurance value should be a minimum of $0 and less than $1,000,000,000.\n";
  message[10] = "Your homeowner's association dues value should be free of special characters\n" +
                "or letters.\n";
  message[11] = "Your homeowner's association dues value should be a minimum of $0 and less than $1,000,000,000.\n";
  message[12] = "Please enter the sales price of the home.\n";
  message[13] = "The sales price or the estimated value of the home should be free of special\n characters or letters.\n";
  message[14] = "The sales price or the estimated value of the home should be\n" +
                "greater than $0 and less than $1,000,000,000.\n";
  message[15] = "The loan amount cannot be greater than the\n" +
                "expected sales price/estimated value of the home\n";


  if (isBlank(form.elements[interestrate].value) == 1)
      errorMsg += message[0];
  else if (isNaN(form.elements[interestrate].value) == true)
      errorMsg += message[1];
  else if ((form.elements[interestrate].value <= 0)||(form.elements[interestrate].value >= 51))
      errorMsg += message[2];

  if (isBlank(form.elements[loanamount].value) == 1)
      errorMsg += message[3];
  else if (isNaN(form.elements[loanamount].value) == true)
      errorMsg += message[4];
  else if ((form.elements[loanamount].value <= 20000)||(form.elements[loanamount].value >= 1000000000))
      errorMsg += message[5];
  else
      var lamount = new Number(form.elements[loanamount].value);

  if (isBlank(form.elements[homeprice].value) == 1)
      errorMsg += message[12];
  else if (isNaN(form.elements[homeprice].value) == true)
      errorMsg += message[13];
  else if ((form.elements[homeprice].value <= 0)||(form.elements[homeprice].value >= 1000000000))
      errorMsg += message[14];
  else
      var hprice = new Number(form.elements[homeprice].value);

  if (lamount > hprice)
      errorMsg += message[15];

  if (isBlank(form.elements[propertytaxes].value) == 0)
    {
      if (isNaN(form.elements[propertytaxes].value) == true)
          errorMsg += message[6];
      else if ((form.elements[propertytaxes].value < 0) || (form.elements[propertytaxes].value >= 1000000000))
          errorMsg += message[7];
    }

  if (isBlank(form.elements[hazardinsurance].value) == 0)
    {
      if (isNaN(form.elements[hazardinsurance].value) == true)
          errorMsg += message[8];
      else if ((form.elements[hazardinsurance].value < 0) || (form.elements[hazardinsurance].value >= 1000000000))
          errorMsg += message[9];
    }

  if (isBlank(form.elements[hoadues].value) == 0)
    {
      if (isNaN(form.elements[hoadues].value) == true)
          errorMsg += message[10];
      else if ((form.elements[hoadues].value < 0) || (form.elements[hoadues].value >= 1000000000))
          errorMsg += message[11];
    }

//No need to return anything here
  if (errorMsg.length == 0)
    {
//If there's no error message, calculate
      MonthlyPaycalculate();
      MonthlyPayshowResults();
    }
  else
    {
//If there's an error message, just show it
      alert("Before continuing, the following fields require attention:\n\n" + errorMsg);
    }
}