﻿
/* Saving Calc Plugin
--------------------------------------
*/


(function($) {

    //util framework
    var lib = {
        StringBuilder: function() {
            var s = [];
            return {
                append: function(v) {
                    if (v) {
                        s.push(v);
                    }
                },
                clear: function() {
                    s.length = 1;
                },
                toString: function() {
                    return s.join("");
                }
            }
        },
        template: function(m, v) {
            v = v.replace(/\{[^\}]*\}/g, function(key) {
                return m[key.slice(1, -1)] || '';
            });
            return v;
        },
        formatNumber: function(n) {
            return Number(n).toFixed(2);
        }
    }

    //calculator results in string
    var buildTable = function(data, _op) {

        var sb = lib.StringBuilder();

        //header template
        sb.append(_op.template.header);

        for (var i = 0, l = data.length; i < l; i++) {

            //alt row swhitch
            if (i % 2) {
                //repeat
                sb.append(lib.template(data[i], _op.template.repeat));
            }
            else {
                //repeat alt row
                sb.append(lib.template(data[i], _op.template.repeatAlt));
            }
        }

        //footer template
        sb.append(_op.template.footer);

        return sb.toString();

    }

    //creates summary object
    var summaryData = function(data, _op) {

        var amountInvested = (data.length * _op.monthlyAmount) + _op.initialDepost;

        var totalAmount = data[data.length - 1].currentAmount;

        return {
            totalAmount: totalAmount,
            totalAmountInvested: amountInvested,
            earnedInterest: lib.formatNumber(totalAmount - amountInvested)
        }
    }

    //calculator ouput data
    var dataCalc = function(obj) {

        var _data = [];

        //some pre-calcs
        var mRate = (obj.interestRate / 100) / 12;
        var numberOfMonths = obj.numberOfYears * 12;

        //Get a decimal
        var currentAmount = 0.1 - 0.1;
        var currentContributions = 0.1 - 0.1;
        var currentInterest = 0.1 - 0.1;

        currentAmount += obj.initialDepost; //initial depost
        currentContributions += obj.initialDepost;

        //amort table loop
        var currentMonth = 0;
        while (currentMonth < numberOfMonths) {

            currentMonth++;

            var interest = Number(currentAmount) * Number(mRate);

            currentInterest = Number(currentInterest) + Number(interest);
            currentContributions = Number(currentContributions) + obj.monthlyAmount;
            currentAmount = Number(currentAmount) + Number(interest) + obj.monthlyAmount;

            //gets table in row format
            _data[currentMonth - 1] = {
                currentContributions: lib.formatNumber(currentContributions),
                currentInterest: lib.formatNumber(currentInterest),
                currentAmount: lib.formatNumber(currentAmount),
                currentMonth: currentMonth
            };
        }

        //final bild out:
        return _data;
    }


    // plugin definition
    $.fn.savingsCalculator = function(op) {

        // build main options before element iteration
        var _op = $.extend({}, $.fn.savingsCalculator.defaults, op);

        // iterate and reformat each matched element
        return this.each(function() {

            var T = $(this); //selected element
            var o = $.meta ? $.extend({}, _op, $this.data()) : _op; // build element specific options

            //final insert

            //gets data in object
            var _data = dataCalc(_op);

            //builds HTML table
            var _tableHtml = buildTable(_data, _op);

            //summary HTML
            var _summaryHtml = lib.template(summaryData(_data, _op), _op.template.summary);

            T.html(_summaryHtml + _tableHtml);

        });
    };

    //gets row data
    $.savingsCalculatorData = function(op) {
    
        // build main options before element iteration
        var _op = $.extend({}, $.fn.savingsCalculator.defaults, op);

        var _data = dataCalc(_op);

        return {
            table: _data,
            summary: summaryData(_data, _op)
        };
    }

    //defaults
    $.fn.savingsCalculator.defaults = {
        initialDepost: 0,
        interestRate: 5,
        numberOfYears: 1,
        monthlyAmount: 100,
        template: {
            summary: "<p>Total amount at the end of the term: {totalAmount}<br />Total amount invested: {totalAmountInvested}<br />Interest earned: {earnedInterest}</p>",
            header: "<table class=\"data_table\"><tr><th>Month</th><th>Contributions</th><th>Interest</th><th>Total</th></tr>",
            repeat: "<tr><td>{currentMonth}</td><td>{currentContributions}</td><td>{currentInterest}</td><td>{currentAmount}</td></tr>",
            repeatAlt: "<tr class=\"alt\"><td>{currentMonth}</td><td>{currentContributions}</td><td>{currentInterest}</td><td>{currentAmount}</td></tr>",
            footer: "</table>"
        }
    };

})(jQuery);



