// Helpful Resource:
//  - http://home.ubalt.edu/ntsbarsh/Business-stat/otherapplets/CompoundCal.htm
var POIE = {

  maxAmountAvailableToBorrow: function (my_income,partner_income) {
    if(partner_income == 0) {
      return Math.round(3.0 * my_income * 100) / 100;
    } else {
      return Math.round(3.5 * (my_income + partner_income) * 100) / 100;
    }
  },

  howMuchWillItCost: function (loanAmount,interestRatePercentage,loanYears,isRepayment) {
    var monthlyInterestRate = interestRatePercentage / 12 / 100;
    var yearlyInterestRate = interestRatePercentage / 100;
    var term = loanYears * 12;
    if(isRepayment) {
      // i = interest rate (monthly) as a fractional value
      // monthly_payment = loan_amount x i / (1 - (1 + i)^-n )
      var monthlyPayment = loanAmount * monthlyInterestRate / (1 - (Math.pow(1/(1 + monthlyInterestRate), term)));
      return Math.round(monthlyPayment * 100)/100; // Round to 2dp
    } else {
      var yearlyInterest = loanAmount * yearlyInterestRate;
      var monthlyInterest = yearlyInterest / 12;
      return Math.round(monthlyInterest * 100) / 100;
    }
  },

  // Work out the effect of paying off the mortgage faster. Returns the
  // number of months to pay off the mortgage (rounded up...)
  overpaymentCalculator: function (loanAmount,interestRatePercentage,loanYears,overpaymentAmount) {

    // n = log[x / (x – P × r)] / log (1 + r) 
    //  - Where:
    //    n => number of months
    //    x => total monthly payment (i.e. normal payment + overpayment amount)
    //    P => total amount
    //    r => monthly interest rate
    
    // Work out how much you would have paid, given no overpayments
    var normalLoanMonths = loanYears * 12;
    var normalMonthlyPayment = Math.round(POIE.howMuchWillItCost(loanAmount,interestRatePercentage,loanYears,true));
    var normalTotalPayment = normalMonthlyPayment * normalLoanMonths;

    // Now work out how long it will take to pay off the mortgage given
    // the overpayment...
    var totalMonthlyPayment = normalMonthlyPayment + overpaymentAmount;
    var monthlyInterestRate = interestRatePercentage / 12 / 100;
    var numberOfMonthsWithOverpayment = Math.log(totalMonthlyPayment / (totalMonthlyPayment - loanAmount * monthlyInterestRate ));
    numberOfMonthsWithOverpayment = numberOfMonthsWithOverpayment / Math.log(1 + monthlyInterestRate);
    totalPaymentWithOverpayment = numberOfMonthsWithOverpayment * totalMonthlyPayment;

    // Now we can return the number of months to pay off the mortgage,
    // plus the amount saved....
    var totalMonths = Math.ceil(numberOfMonthsWithOverpayment);
    return {
      'totalMonthsWithOverpayment': totalMonths,
      'totalMonthsWithoutOverpayment': normalLoanMonths,
      'monthsSaved': normalLoanMonths - totalMonths,
      'totalWithOverpayment': Math.round(totalPaymentWithOverpayment * 100) / 100,
      'totalWithoutOverpayment': Math.round(normalTotalPayment * 100) / 100,
      'totalSaved': Math.round((normalTotalPayment - totalPaymentWithOverpayment) * 100) / 100
    };

  },

  stampDutyCalculator: function (purchasePrice) {
    var rate = 0;
    switch(true) {
      case purchasePrice <= 125000:
        rate = 0;
        break;
      case purchasePrice <= 250000:
        rate = 0.01;
        break;
      case purchasePrice <= 500000:
        rate = 0.03;
        break;
      default:
        rate = 0.04;
        break;
    }
    var stamp_duty = purchasePrice * rate;
    return Math.round(stamp_duty * 100) / 100;
  },

  rentalStressCalculator: function (loanAmount,interestRatePercentage,monthlyInterestOnlyPayments) {
    // Ensure we have a monthly interest-only payment first
    if(monthlyInterestOnlyPayments == 0)
      var monthlyInterestOnlyPayments = POIE.howMuchWillItCost(loanAmount,interestRatePercentage,25,false);
    // 125% of monthly interest-only payments
    var rental_value = monthlyInterestOnlyPayments * 1.25;
    return Math.round(rental_value * 100) / 100;
  },

  rentalYieldCalculator: function (purchase_price,monthly_rental_income) {
    var yield = monthly_rental_income * 12 / purchase_price * 100;
    return Math.round(yield * 100) / 100;
  },

  capitalGrowthCalculator: function (purchasePrice,annualInflationPercentage) {
    var capitalGrowth = purchasePrice * (annualInflationPercentage / 100);
    return Math.round(capitalGrowth * 100) / 100;
  },


  // Utility functions
  addThousandSeparators: function(n) {
    n += '';
    var x = n.split('.');
    var x1 = x[0];
    var x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
  },
  monthsToString: function(n) {
    if( n%12==0 || n==0) {
      return (n/12) + ' years';
    } else {
      if(Math.floor(n/12) == 0) {
        return (n % 12) + ' month' + (n%12>1 ? 's' : '');
      } else {
        return Math.floor(n/12) + ' year' + (Math.floor(n/12) > 1 ? 's' : '') + ' and ' + (n % 12) + ' month' + (n%12>1?'s':'');
      }
    }
  },
  toInt: function(s) { 
    var ret = s.replace(/[^0-9]+/g,'');
    if(ret.length > 0) return parseInt(ret);
    return 0;
  },
  toFloat: function(s) { 
    var ret = s.replace(/[^0-9.]+/g,'');
    if(ret.length > 0) return parseFloat(ret);
    return 0;
  }

};

