function MortgageCalculator(LoanAmount,LoanTerm,InterestRate,MirasRate,MirasCeiling,PaymentsPerYear,CapFrequency) {
	this.LoanAmount = parseFloat(LoanAmount);
	this.LoanTerm = parseInt(LoanTerm,10);
	this.InterestRate = parseFloat(InterestRate);
	this.MirasRate = parseFloat(MirasRate);
	this.MirasCeiling = parseFloat(MirasCeiling);
	this.PaymentsPerYear = parseInt(PaymentsPerYear,10);
	this.CapFrequency = parseInt(CapFrequency,10);
	this.InterestOnly = InterestOnly;
	this.CapitalAndInterest = CapitalAndInterest;
}

// METHOD TO CALCULATE INTEREST ONLY REPAYMENT
function InterestOnly() {
	var dblInterestRate = (this.InterestRate / 100);
	var dblMirasRate = (this.MirasRate / 100);
	var dblMirasCeiling = this.MirasCeiling;
	
	if (parseFloat(this.LoanAmount) < parseFloat(dblMirasCeiling)) dblMirasCeiling = this.LoanAmount;
	var dblPayment = this.LoanAmount * dblInterestRate;
	dblPayment -= dblMirasCeiling * dblInterestRate * dblMirasRate;
	return dblPayment / this.PaymentsPerYear;
	
}

// METHOD TO CALCULATE CAPITAL AND INTEREST REPAYMENT
function CapitalAndInterest() {

	var dblInterestRate = (this.InterestRate / 100) / (12 / this.CapFrequency);
	var dblMirasCeilingRate = this.MirasCeiling * dblInterestRate;
	var dblMirasRate = (this.MirasRate / 100.00);
	var dblMirasCeiling_IntRate = dblMirasCeilingRate * dblMirasRate;
	var dblMirasRate_IntRate = (1 - dblMirasRate) * dblInterestRate;
	var dblTermByCapFreq = (this.LoanTerm / this.CapFrequency);
	// The next 3 lines round Term down to 2 decimal places to match ICBS
	var strTemp = dblTermByCapFreq.toString();
	var intPos = strTemp.indexOf(".");
	if (intPos != -1) dblTermByCapFreq = parseFloat(strTemp.substring(0,intPos+3));
	
	var dblIndicesLimit = Math.pow(1 + dblInterestRate , dblTermByCapFreq);
	var dblAnnualRepayment = this.LoanAmount * dblInterestRate
	
	//*   Repayment Calculation assuming no MIRAS   *
	var dblPayment = this.LoanAmount * dblInterestRate / (1 - Math.pow( (1 / (1+dblInterestRate)) , dblTermByCapFreq)) ;
	var dblOriginalPayment = dblPayment;
	//*  Repayment Calculation assuming full MIRAS  *
	var dblPaymentMiras = this.LoanAmount * dblMirasRate_IntRate / (1 - Math.pow( (1 / (1 + dblMirasRate_IntRate)) , dblTermByCapFreq));
	var dblOriginalPaymentMiras = dblPaymentMiras;
	
	var dblIndex1 = dblCalculateIndex(dblMirasCeilingRate, dblPaymentMiras, 0, 0, 0, dblAnnualRepayment, dblMirasCeiling_IntRate, dblInterestRate,dblTermByCapFreq, dblIndicesLimit);
	var dblIndex2 = dblCalculateIndex(dblMirasCeilingRate, dblPayment, dblIndex1, dblIndex1, 0, dblAnnualRepayment, dblMirasCeiling_IntRate, dblInterestRate,dblTermByCapFreq, dblIndicesLimit);
	var dblCalc1 = dblCalculatePayment(dblIndex1, dblPaymentMiras, (1 - dblMirasRate), dblMirasRate_IntRate, dblTermByCapFreq, dblMirasCeiling_IntRate, dblInterestRate,this.LoanAmount);
	var dblOriginalR1 = dblCalc1;
	var dblCalc2 = dblCalculatePayment(dblIndex2, dblPayment, (1 - dblMirasRate), dblMirasRate_IntRate, dblTermByCapFreq, dblMirasCeiling_IntRate, dblInterestRate, this.LoanAmount);
	var dblOriginalR2 = dblCalc2;
	var dblNewPayment = 0;
	var dblIndex3 = 0;
	var dblCalc3 = 0;

	while (true == true) {

		if (dblCalc1 != dblCalc2) {
			dblNewPayment = (dblPaymentMiras + ((dblPayment - dblPaymentMiras) * ( dblCalc1 / (dblCalc1 - dblCalc2))));
		} 
		else {
			dblPayment = ((dblPayment * 12) / this.CapFrequency) / this.PaymentsPerYear;
			return dblPayment;
		}	
  
		if (dblNewPayment < dblOriginalPaymentMiras) { dblNewPayment = dblOriginalPaymentMiras; }
		if (dblNewPayment > dblOriginalPayment) { dblNewPayment = dblOriginalPayment; }

		dblIndex3 = dblCalculateIndex(dblMirasCeilingRate, dblNewPayment, dblIndex2, dblIndex1, dblIndex2, dblAnnualRepayment, dblMirasCeiling_IntRate, dblInterestRate,dblTermByCapFreq, dblIndicesLimit);
		dblCalc3 = dblCalculatePayment(dblIndex3, dblNewPayment, (1 - dblMirasRate), dblMirasRate_IntRate, dblTermByCapFreq, dblMirasCeiling_IntRate, dblInterestRate, this.LoanAmount);

		if ((dblCalc3 < 0.001) && (dblCalc3 > -0.001)) {
			dblNewPayment = ((dblNewPayment * 12) / this.CapFrequency) / this.PaymentsPerYear;
			return dblNewPayment;
		}

		if (dblCalc3 < dblOriginalR1) { dblCalc3 = dblOriginalR1; }
		if (dblCalc3 > dblOriginalR2) { dblCalc3 = dblOriginalR2; }

		dblPaymentMiras = dblPayment;
		dblCalc1 = dblCalc2;
		dblPayment = dblNewPayment;
		dblCalc2 = dblCalc3;
	} 
} 
	
function dblCalculateIndex(dblMirasLimitRate, dblPayment, dblIndex1, dblIndex2,
	dblIndex3, dblLoanRate, dblMirasRateCalc, dblIntRate,dblTerm, dblIndicesLimit) {

	var dblTemp;
	var dblCalc = ((dblMirasLimitRate - dblPayment) - dblMirasRateCalc) / ((dblLoanRate - dblPayment) - dblMirasRateCalc);
	var dblIndices;

	if (dblCalc > dblIndicesLimit) dblCalc = -1;

	if (dblIndex2 > dblIndex3) dblIndices = dblIndex3;
	else dblIndices = dblIndex2;
	
	if (dblCalc < 0) {
		dblIndex1 = dblTerm;
		return dblIndex1;
	}
	
	do {
		dblIndices++;
		dblTemp = Math.pow(1 + dblIntRate, dblIndices);
	} while (dblTemp < dblCalc);
	
	return dblIndices;
} 

function dblCalculatePayment(dblIndex, dblPayment, dblMirasRelief, dblRate_TaxRelief,
	dblTerm, dblRateCalc, dblIntRate, dblLoanAmount) {
	
	var dblTemp1 = Math.pow((1 / (1 + dblIntRate)) , dblIndex);
	var dblCalc1 = (dblRateCalc + dblPayment) * ((1 - dblTemp1) / dblIntRate);
	dblTemp1 = Math.pow((1 / (1 + (dblMirasRelief * dblIntRate))) , (dblTerm - dblIndex));
	dblTemp1 = (((1 - dblTemp1) / dblRate_TaxRelief) * dblPayment);
	var dblCalc2 = dblTemp1 / Math.pow((1+dblIntRate),dblIndex);
	return dblCalc2 + dblCalc1 - dblLoanAmount;
} 