
/*
 * Copyright 2008 Squawkfox.  All rights reserved.
 */

/*
 * Calculate loan the payment per period.
 */
function PaymentPerPeriod(loanAmount, rate, periodsPerYear, term) {
    
    var value = 
        loanAmount *
        (rate / periodsPerYear) *
        Math.pow((1 + rate / periodsPerYear), (term * periodsPerYear)) /
        (Math.pow((1 + rate / periodsPerYear), (term * periodsPerYear)) - 1);
        
    return value;
}


function ClearOutput() {
    SetValue('breakEvenPoint', 'never');
    SetValue('rentInvestmentAtBreakEven', FormatCurrency(0));
    SetValue('breakEvenRentAheadBy', FormatCurrency(0));
    SetValue('rentEvenPoint', 'never');
    SetValue('rentEvenNetWorth', FormatCurrency(0));
    SetValue('HomeValue', FormatCurrency(0));
    SetValue('HomeEquity', FormatCurrency(0));
    SetValue('HomeSale', FormatCurrency(0));
    SetValue('BuyingProfit', FormatCurrency(0));
    SetValue('TotalRent', FormatCurrency(0));
    SetValue('TotalInvestment', FormatCurrency(0));
    SetValue('RentalProfit', FormatCurrency(0));
    SetValue('TotalYearsRenting', 0);
    SetValue('TotalYearsBuying', 0);
}


/*
 * Validate all fields and return true if validation passed.
 */
function Validate() {
    
    var result = true;
   
    result &= ValidateIsNumeric('savingsInput');
    result &= ValidateIsNumeric('rateOfReturnInput');
    result &= ValidateIsNumeric('rentInput');
    result &= ValidateIsNumeric('purchasePriceInput');
    result &= ValidateIsNumeric('mortgateRateInput');
    result &= ValidateIsNumeric('mortgateTermInput');
    result &= ValidateIsNumeric('homeAppreciationInput');
    result &= ValidateIsNumeric('realtorFeeInput');
    result &= ValidateIsNumeric('yearsToSaleInput');
    
    return result;

}


/*
 * Check if the provided field is empty.  If empty, flag the field as required, and return false.
 * Otherwise, unflag the field and return true.
 */
function ValidateIsNumeric(id) {
    ClearValidation(id);

    var result = (ReadValue(id) > 0);
        
    if (!result) {
//        document.getElementById(id).setAttribute('class', 'invalidTextInput');
        document.getElementById(id).className = "invalidTextInput";
    }
    
    return result;
}



/*
 * Clear validation failure flag for a field.
 */
function ClearValidation(id) {
    document.getElementById(id).setAttribute('class', '');
}



function calculate() {
    
    ClearOutput();
    Validate();

    var monthlyRentingExpense = ReadValue('rentInput') + ReadValue('rentInsuranceInput');
    var rateOfReturn = ReadValue('rateOfReturnInput') / 100;
    var startingCash = ReadValue('savingsInput');

    var yearsToExamine = ReadValue('yearsToSaleInput');
    var taxRate = ReadValue('taxRateInput') / 100;

    var mortgageAmount =
        ReadValue('purchasePriceInput')
        + ReadValue('loanCostsInput')
        - startingCash
        + ReadValue('renovationCostsInput');
        
    var mortgateTerm = ReadValue('mortgateTermInput');
    var mortgateRate = ReadValue('mortgateRateInput') / 100;
    var taxRate = ReadValue('taxRateInput') / 100;
    var realtorRate = ReadValue('realtorFeeInput') / 100;
    var purchasePrice = ReadValue('purchasePriceInput');
    var appreciationRate = ReadValue('homeAppreciationInput') / 100;
    
    
    var monthlyMortgagePayment = PaymentPerPeriod(mortgageAmount, mortgateRate, 12, mortgateTerm);
    SetValue('monthlyMortgagePayment', FormatCurrency(monthlyMortgagePayment));
    
    // Total monthly payment is sum of mortgage payment and all other payments on a per-month basis.   
    var totalMonthlyPayment =
        monthlyMortgagePayment +
        ReadValue('ownerInsuranceInput') / 12 +
        ReadValue('annualPropertyTaxInput') / 12 +
        ReadValue('annualCondoFeesInput') / 12 +
        ReadValue('annualMaintenanceInput') / 12 +
        ReadValue('otherAnnualInput') / 12;
        
    SetValue('totalMonthlyPayment', FormatCurrency(totalMonthlyPayment));

    /*
     * Main iterative calculation loop
     */

    var outstandingBalance = mortgageAmount;
    var totalPrincipal = 0;
    var totalInterest = 0;
    var totalTaxSavings = 0;
    
    var totalInvestment = startingCash;
    var totalRentPaid = 0;
    
    var breakEvenPoint = 0;
    var rentMatchesBuyPoint = 0;
    
    SetValue('TotalYearsRenting', yearsToExamine);
    SetValue('TotalYearsBuying', yearsToExamine);

            
            
    for (var i = 1; i <= mortgateTerm * 12; i++) {
        
        var currentInterestInPayment = outstandingBalance * mortgateRate / 12;
        totalInvestment += currentInterestInPayment;
        
        var currentPrincipalInPayment = monthlyMortgagePayment - currentInterestInPayment;
        totalPrincipal += currentPrincipalInPayment;
        outstandingBalance -= currentPrincipalInPayment;
        
        var taxSavings = currentInterestInPayment * taxRate;
        totalTaxSavings += taxSavings;
        
        var homeValue = purchasePrice * Math.pow(1 + (appreciationRate / 12), i);
        var equity = homeValue - outstandingBalance;
        var cashAfterRealtor = equity - homeValue * realtorRate + totalTaxSavings;

        totalRentPaid += monthlyRentingExpense;
        totalInvestment *= (1 + rateOfReturn / 12);
        totalInvestment += (monthlyMortgagePayment - monthlyRentingExpense - taxSavings);

            
        if (breakEvenPoint == 0 && cashAfterRealtor >= startingCash) {
            breakEvenPoint = i;
            
            SetValue('breakEvenPoint', Math.round(i / 12 * 100) / 100);
            SetValue('rentInvestmentAtBreakEven', FormatCurrency(totalInvestment));
            SetValue('breakEvenRentAheadBy', FormatCurrency(totalInvestment - startingCash));
        }
        
        
        
        if (rentMatchesBuyPoint == 0 && cashAfterRealtor >= totalInvestment) {
            rentMatchesBuyPoint = i;
           
            SetValue('rentEvenPoint', Math.round(i / 12 * 100) / 100);
            SetValue('rentEvenNetWorth', FormatCurrency(totalInvestment));
        }
        
        if ((i / 12) == yearsToExamine) {
            SetValue('HomeValue', FormatCurrency(homeValue));
            SetValue('HomeEquity', FormatCurrency(equity));
            SetValue('HomeSale', FormatCurrency(cashAfterRealtor));
            SetValue('TotalTaxSavings', FormatCurrency(totalTaxSavings));
            SetValue('BuyingProfit', FormatCurrency(cashAfterRealtor - startingCash));
            
            SetValue('TotalRent', FormatCurrency(i * monthlyRentingExpense));
            SetValue('TotalInvestment', FormatCurrency(totalInvestment));
            SetValue('RentalProfit', FormatCurrency(totalInvestment - startingCash));
            
            var difference = totalInvestment - cashAfterRealtor;
            if (difference > 0) {
                SetValue('Choice', 'RENT');
            }
            else {
                SetValue('Choice', 'BUY');
            }
            
            SetValue('Difference', FormatCurrency(Math.abs(difference)));
            SetValue('TotalYearsToCompare', yearsToExamine);
            
        }
    }
}



function ReadValue(elementId) {
    return document.getElementById(elementId).value * 1;
}


function SetValue(elementId, value) {
    document.getElementById(elementId).innerHTML = value;
}



/*
 * Format a number as currency.
 */
function FormatCurrency(num) {
    num = num.toString().replace(/\$|\,/g,'');
    if(isNaN(num)) {
        num = "0";
    }
    sign = (num == (num = Math.abs(num)));
    num = Math.floor(num*100+0.50000000001);
    cents = num%100;
    num = Math.floor(num/100).toString();
    if(cents<10)
    cents = "0" + cents;
    for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
    num = num.substring(0,num.length-(4*i+3))+','+
    num.substring(num.length-(4*i+3));
    return (((sign)?'':'-') + '$' + num + '.' + cents);
}