
// PMT Function
function parseNumber(value){
  //force to be a string
  value = ""+value;

  //trim leading and trailing whitespace
  value = value.replace(/^\s+/g,"");
  value = value.replace(/\s+$/g,"");

  //remove any spaces and commas
  value = value.replace(/[\s,]/g,"");

  //trim leading zeros
  value = value.replace(/^0+/g,"");
  value = value.replace(/\s+$/g,"");

  //confirm that result looks like a number
  if( value.match( /^\d*(\.\d*)?$/ ) ){
    //parse float
    try{
      var num = parseFloat(value);
      if(isNaN(num)) {
         return 0.0;
      }
      return num;
   }catch(err){
      return 0.0;
   }
  }
  //otherwise return 0.0
  return 0.0
}
var TestA = "Test A";
TestB = "Test B";
var MortgageCalculator = {
  MINIMUM_PAYMENT : 0.0,
  MAXIMUM_PAYMENT : 1.0E9,
  MINIMUM_TERM : 0.0,
  MAXIMUM_TERM : 100.0,
  MINIMUM_INTEREST : 0.0,
  MAXIMUM_INTEREST : 100.0,
  INCOME_MULTIPLIER : 3.33333333333333,
  INCOME_PREQUALIFIER_MULTIPLIER : 3.0,
  SAMPLE_PURCHASE_PRICE : 1000000.0,
  DEFAULT_INTEREST_RATE : 12.989999999999998,
  DEFAULT_TERM : 25.0,
  DEFAULT_DEPOSIT_RATE : 0.15,
  DEFAULT_CLOSING_RATE : 0.15,
  DEFAULT_TERM_PERIODS : 12.0,
  DEFAULT_LOAN_RATIO : 0.9,
  LOWER_PAYMENT_LOAN_TO_PRICE_RATIO : 0.91,
  HIGHER_PAYMENT_LOAN_TO_PRICE_RATIO : 0.95,
  LOWEST_PAYMENT_MULTIPLIER : 3.33333333333333,
  MIDDLE_PAYMENT_MULTIPLIER : 5.0,
  HIGHEST_PAYMENT_MULTIPLIER : 5.0,
  doubleValue: function(value){
     return parseNumber(value);
  }
};
var mc = MortgageCalculator; /* To allow for access by either name. */

var StringFormats = {
    INT_FORMAT     : "%.0f",
    MONEY_FORMAT   : "%,.0f",
    PERCENT_FORMAT : "%1.2f%%",
    FLOAT_FORMAT   : "%1.2f",
    intFormat      : function(value){ return printf(this.INT_FORMAT, value); },
    moneyFormat    : function(value){ return printf(this.MONEY_FORMAT, value); },
    percentFormat  : function(value){ return printf(this.PERCENT_FORMAT,value); },
    numberFormat   : function(value){ return printf(this.FLOAT_FORMAT, value); }
};

function PMT(rate, nper, pv) {
  var Z = 1.0 / (1.0 + rate);
  var amt = ((1.0 - Z) * pv) / (Z * (1.0 - (Math.pow(Z,nper))));
  return amt;
}

function PV(rate, nper, pa) {
  var X  = Math.pow((1 + rate),-nper);
  var amt = pa * ((1 - X) / rate);
  return amt;
}


// Duplicates of JSP mortgage calculator functions

function samplePurchasePrice(){ return MortgageCalculator.SAMPLE_PURCHASE_PRICE; }
function defaultInterestRate(){ return MortgageCalculator.DEFAULT_INTEREST_RATE; }
function defaultLoanTerm(){ return MortgageCalculator.DEFAULT_TERM; }
function defaultDepositRate(){ return MortgageCalculator.DEFAULT_DEPOSIT_RATE; }
function defaultClosingRate(){ return MortgageCalculator.DEFAULT_CLOSING_RATE; }
function defaultTermPeriods(){ return MortgageCalculator.DEFAULT_TERM_PERIODS; }
function defaultLoanRatio(){ return MortgageCalculator.DEFAULT_LOAN_RATIO; }
function defaultIncomeMultiplier(){ return MortgageCalculator.INCOME_MULTIPLIER; }
function defaultIncomePreQualifierMultiplier(){ return MortgageCalculator.INCOME_PREQUALIFIER_MULTIPLIER; }

function estimatedRequiredDeposit(purchasePrice){
  return purchasePrice * defaultDepositRate();
}
function estimatedLoanAmount(purchasePrice){
  return purchasePrice * defaultLoanRatio();
}
function estimatedMonthlyPayments(purchasePrice, termYears, interestRate){
  return loanPayment(purchasePrice, termYears, interestRate);
}
function estimatedMonthlyPaymentMultiplier(purchasePrice, loanAmount){
  ratio = loanAmount / purchasePrice;
  if(ratio < MortgageCalculator.LOWER_PAYMENT_LOAN_TO_PRICE_RATIO){
     return MortgageCalculator.LOWEST_PAYMENT_MULTIPLIER;
  }else if(ratio < MortgageCalculator.HIGHER_PAYMENT_LOAN_TO_PRICE_RATIO){
     return MortgageCalculator.MIDDLE_PAYMENT_MULTIPLIER;
  }else{
      return MortgageCalculator.HIGHEST_PAYMENT_MULTIPLIER;
  }
}
function estimatedRequiredGrossMonthlyIncome(purchasePrice, loanAmount, termYears, interestRate){
  return estimatedMonthlyPaymentMultiplier(purchasePrice, loanAmount) * estimatedMonthlyPayments(loanAmount, termYears, interestRate);
}
function estimatedClosingCosts(purchasePrice){
  return purchasePrice * defaultClosingRate();
}
function incomePreQualifier(loanAmount, termYears, interestRate){
  return defaultIncomePreQualifierMultiplier() * loanPayment(loanAmount, termYears, interestRate);
}
/* Pending */
function principalPreQualifier(monthlyIncome, termYears, interestRate){
  n = defaultTermPeriods();
  incomePreQualifierMultiplier = defaultIncomePreQualifierMultiplier();
  return PV(interestRate/n,termYears*n,monthlyIncome/incomePreQualifierMultiplier);
}
function installmentsPreQualifier(loanAmount, termYears, interestRate){
  return loanPayment(loanAmount, termYears, interestRate);
}
function loanPayment(loanAmount, termYears, interestRate){
  n = defaultTermPeriods();
  return PMT(interestRate/n,termYears*n, loanAmount);
}

function validLoanAmount(loanAmount){
    return !(loanAmount <= MortgageCalculator.MINIMUM_PAYMENT || loanAmount >= MortgageCalculator.MAXIMUM_PAYMENT);
}
function validLoanTerm(loanTerm){
    return !(loanTerm <= MortgageCalculator.MINIMUM_TERM || loanTerm >= MortgageCalculator.MAXIMUM_TERM);
}
function validInterestRate(interestRate){
    return !(interestRate <= MortgageCalculator.MINIMUM_INTEREST || interestRate >= MortgageCalculator.MAXIMUM_INTEREST);
}


/* Support functions */
var currencySymbols = {"GBP": "&pound;", "JMD": "$", "USD": "$" };

function resetCurrency(frm){
	if(frm["currencyCode"]) {
		var symbol = ''+currencySymbols[frm.currencyCode.value];

		var els = getElementsByClass('currency',frm, 'span');
		var len = els.length;
		for(i=0; i<len; i++){
			els[i].innerHTML = symbol;
		}
	}
}
/* From http://www.dustindiaz.com/getelementsbyclass/ */
function getElementsByClass(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("\\b"+searchClass+"\\b");
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}
/* Function printf(format_string,arguments...)
 * Javascript emulation of the C printf function (modifiers and argument types 
 *    "p" and "n" are not supported due to language restrictions)
 *
 * Copyright 2003 K&L Productions. All rights reserved
 * http://www.klproductions.com 
 *
 * Terms of use: This function can be used free of charge IF this header is not
 *               modified and remains with the function code.
 * 
 * Legal: Use this code at your own risk. K&L Productions assumes NO resposibility
 *        for anything.
 ********************************************************************************/
function printf(fstring)
  { var pad = function(str,ch,len)
      { var ps='';
        for(var i=0; i<Math.abs(len); i++) ps+=ch;
        return len>0?str+ps:ps+str;
      }
    var addCommas = function(arg)
      { var argArr = arg.split(".");
	var iPart = argArr[0];
	var dPart = (argArr.length > 1) ? "." + argArr[1] : "";
	for(var i=iPart.length-3; i>0; i-=3) iPart= iPart.substring(0,i) + "," + iPart.substring(i);
	return iPart + dPart;
      }
    var processFlags = function(flags,width,rs,arg)
      { var pn = function(flags,arg,rs)
          { if(arg>=0)
              { if(flags.indexOf(' ')>=0) rs = ' ' + rs;
                else if(flags.indexOf('+')>=0) rs = '+' + rs;
              }
            else
                rs = '-' + rs;
            return rs;
          }
        var iWidth = parseInt(width,10);
        if(width.charAt(0) == '0')
          { var ec=0;
            if(flags.indexOf(' ')>=0 || flags.indexOf('+')>=0) ec++;
            if(rs.length<(iWidth-ec)) rs = pad(rs,'0',rs.length-(iWidth-ec));
            return pn(flags,arg,rs);
          }
        rs = pn(flags,arg,rs);
        if(rs.length<iWidth)
          { if(flags.indexOf('-')<0) rs = pad(rs,' ',rs.length-iWidth);
            else rs = pad(rs,' ',iWidth - rs.length);
          }    
        return rs;
      }
    var converters = new Array();
    converters['c'] = function(flags,width,precision,arg)
      { if(typeof(arg) == 'number') return String.fromCharCode(arg);
        if(typeof(arg) == 'string') return arg.charAt(0);
        return '';
      }
    converters['d'] = function(flags,width,precision,arg)
      { return converters['i'](flags,width,precision,arg); 
      }
    converters['u'] = function(flags,width,precision,arg)
      { return converters['i'](flags,width,precision,Math.abs(arg)); 
      }
    converters['i'] =  function(flags,width,precision,arg)
      { var iPrecision=parseInt(precision);
        var rs = ((Math.abs(arg)).toString().split('.'))[0];
        if(rs.length<iPrecision) rs=pad(rs,' ',iPrecision - rs.length);
        return processFlags(flags,width,rs,arg); 
      }
    converters['E'] = function(flags,width,precision,arg) 
      { return (converters['e'](flags,width,precision,arg)).toUpperCase();
      }
    converters['e'] =  function(flags,width,precision,arg)
      { iPrecision = parseInt(precision);
        if(isNaN(iPrecision)) iPrecision = 6;
        rs = (Math.abs(arg)).toExponential(iPrecision);
        if(rs.indexOf('.')<0 && flags.indexOf('#')>=0) rs = rs.replace(/^(.*)(e.*)$/,'$1.$2');
        return processFlags(flags,width,rs,arg);        
      }
    converters['f'] = function(flags,width,precision,arg)
      { iPrecision = parseInt(precision);
        if(isNaN(iPrecision)) iPrecision = 6;
        rs = (Math.abs(arg)).toFixed(iPrecision);
        if(rs.indexOf('.')<0 && flags.indexOf('#')>=0) rs = rs + '.';
        return processFlags(flags,width,rs,arg);
      }
    converters['G'] = function(flags,width,precision,arg)
      { return (converters['g'](flags,width,precision,arg)).toUpperCase();
      }
    converters['g'] = function(flags,width,precision,arg)
      { iPrecision = parseInt(precision);
        absArg = Math.abs(arg);
        rse = absArg.toExponential();
        rsf = absArg.toFixed(6);
        if(!isNaN(iPrecision))
          { rsep = absArg.toExponential(iPrecision);
            rse = rsep.length < rse.length ? rsep : rse;
            rsfp = absArg.toFixed(iPrecision);
            rsf = rsfp.length < rsf.length ? rsfp : rsf;
          }
        if(rse.indexOf('.')<0 && flags.indexOf('#')>=0) rse = rse.replace(/^(.*)(e.*)$/,'$1.$2');
        if(rsf.indexOf('.')<0 && flags.indexOf('#')>=0) rsf = rsf + '.';
        rs = rse.length<rsf.length ? rse : rsf;
        return processFlags(flags,width,rs,arg);        
      }  
    converters['o'] = function(flags,width,precision,arg)
      { var iPrecision=parseInt(precision);
        var rs = Math.round(Math.abs(arg)).toString(8);
        if(rs.length<iPrecision) rs=pad(rs,' ',iPrecision - rs.length);
        if(flags.indexOf('#')>=0) rs='0'+rs;
        return processFlags(flags,width,rs,arg); 
      }
    converters['X'] = function(flags,width,precision,arg)
      { return (converters['x'](flags,width,precision,arg)).toUpperCase();
      }
    converters['x'] = function(flags,width,precision,arg)
      { var iPrecision=parseInt(precision);
        arg = Math.abs(arg);
        var rs = Math.round(arg).toString(16);
        if(rs.length<iPrecision) rs=pad(rs,' ',iPrecision - rs.length);
        if(flags.indexOf('#')>=0) rs='0x'+rs;
        return processFlags(flags,width,rs,arg); 
      }
    converters['s'] = function(flags,width,precision,arg)
      { var iPrecision=parseInt(precision);
        var rs = arg;
        if(rs.length > iPrecision) rs = rs.substring(0,iPrecision);
        return processFlags(flags,width,rs,0);
      }
    farr = fstring.split('%');
    retstr = farr[0];
    fpRE = /^([-+ #,]*)(\d*)\.?(\d*)([cdieEfFgGosuxX])(.*)$/;
    for(var i=1; i<farr.length; i++)
      { commas = farr[i].match(/,/);
        fps=fpRE.exec(farr[i]);
        if(!fps) continue;
        formatted = '';
        if(arguments[i]!=null) formatted=converters[fps[4]](fps[1],fps[2],fps[3],arguments[i]);
	if(commas) formatted = addCommas(formatted);
        retstr += formatted + fps[5];
      }
    return retstr;
  }
/* Function printf() END */