// override UOS functions xstooltip_findPosX() and xstooltip_findPosY() to
// determine an object's position relative to innermost positioned ancestor
// (i.e. the innermost ancestor with absolute or relative position)
function xstooltip_findPosX(obj) {
    var curleft = 0;
    if (obj.offsetParent) {
        while (obj.offsetParent) {
            curleft += obj.offsetLeft
            obj = obj.offsetParent;
            if (obj.style.position == 'absolute' || obj.style.position == 'relative') break;
        }
    } else if (obj.x)
        curleft += obj.x;
    return curleft;
}

function xstooltip_findPosY(obj) {
    var curtop = 0;
    if (obj.offsetParent) {
        while (obj.offsetParent) {
            curtop += obj.offsetTop
            obj = obj.offsetParent;
            if (obj.style.position == 'absolute' || obj.style.position == 'relative') break;
        }
    } else if (obj.y)
        curtop += obj.y;
    return curtop;
}

$(document).ready(function() {

    var $dollarInputs = $('input:text[name^=annualExpense], input:text[name^=monthlyExpense], input:text[name^=taxableMonthlyIncome], input:text[name^=aftertaxMonthlyIncome]');
    var $taxRate = $('#taxRate');

    /*
     * "commify" a number, i.e. add non-breaking spaces as thousand separators and replace decimal point with comma
     */
    function commify(num) {
        return num.toString().split('').reverse().join('').replace(/(?=\d*\.?)(\d{3})(?=\d)/img,'$1;psbn&').split('').reverse().join('').replace(/\./, ',');
    };
    
    /*
     * reverse of commify()
     */
    function uncommify(num) {
        return num.toString().replace(/&nbsp;/g, '').replace(/,/, '.');
    };
    
    /*
     * given a taxable input element (can be DOM element or jQuery object), updates the corresponding aftertax input
     */
    function updateAftertaxInput(taxableInput) {
        var rate = uncommify($taxRate.val()) / 100;
        var name = $(taxableInput).attr('name').replace(/taxable/, 'aftertax');
        var value = Number(uncommify($(taxableInput).val())) * (1-rate);
        if (isNaN(value)) {
            value = 0;
        }
        var $aftertaxInput = $dollarInputs.filter('[name='+name+']');
        $aftertaxInput.val( Math.ceil(value) );
    };

    /*
     * update total amounts
     */
    function updateTotals() {
        // total expenses
        var totalMonthlyExpenses = 0;
        $dollarInputs.filter('[name^=annualExpense]').each(function() {
            var value = uncommify(this.value);
            if (!(isNaN(value))) {
                totalMonthlyExpenses += Number(value / 12);
            }
        });
        $dollarInputs.filter('[name^=monthlyExpense]').each(function() {
            var value = uncommify(this.value);
            if (!(isNaN(value))) {
                totalMonthlyExpenses += Number(value);
            }
        });
        $('.totalMonthlyExpenses').html( commify(Math.ceil(totalMonthlyExpenses)) );

        // total income
        var totalMonthlyIncome = 0;
        $dollarInputs.filter('[name^=aftertaxMonthlyIncome]').each(function() {
            var value = uncommify(this.value);
            if (!(isNaN(value))) {
                totalMonthlyIncome += Number(value);
            }
        });
        $('.totalMonthlyIncome').html( commify(Math.ceil(totalMonthlyIncome)) );
        
        // total insurance
        var totalMonthlyInsurance = totalMonthlyExpenses - totalMonthlyIncome;
        if (totalMonthlyInsurance < 0) {
            totalMonthlyInsurance = 0;
        }
        $('.totalMonthlyInsurance').html( commify(Math.ceil(totalMonthlyInsurance)) );
    };
    
    // handle tax rate changes
    $taxRate.change(function() {

        // enforce valid numeric value to 2 decimal places
        var $input = $(this);
        var value = Number( uncommify($input.val()) );
        if (isNaN(value)) {
            value = 0;
        }
        $input.val( commify(value.toFixed(2)) );

    }).keyup(function() {

        // update aftertax values that were automatically generated based on user-provided taxable value
        $dollarInputs.filter('[name^=taxableMonthlyIncome]').each(function() {
            if ($(this).val() != '') {
                updateAftertaxInput(this);
            }
        });

    });
    
    // handle dollar input changes
    $dollarInputs.change(function() {

        // enforce valid integer values
        var $input = $(this);
        var value = Number( uncommify($input.val()) );
        if (isNaN(value)) {
            value = 0;
        }
        $input.val( Math.ceil(value) );

    }).keyup(function(e) {

        var $input = $(this);
        
        // ignore tab and shift
        if (e.keyCode == 9 || e.keyCode == 16) return;

        // ensure consistency between each pair of annual/monthly or taxable/aftertax inputs
        if ($input.attr('name').search(/annualExpense/) != -1) {
            var name = $input.attr('name').replace(/annual/, 'monthly');
            var value = Number(uncommify($input.val())) / 12;
            if (isNaN(value)) {
                value = 0;
            }
            $dollarInputs.filter('[name='+name+']').val( Math.ceil(value) );
        } else if ($input.attr('name').search(/monthlyExpense/) != -1) {
            var name = $input.attr('name').replace(/monthly/, 'annual');
            $dollarInputs.filter('[name='+name+']').val('');
        } else if ($input.attr('name').search(/taxableMonthlyIncome/) != -1) {
            updateAftertaxInput($input);
        } else if ($input.attr('name').search(/aftertaxMonthlyIncome/) != -1) {
            var name = $input.attr('name').replace(/aftertax/, 'taxable');
            $dollarInputs.filter('[name='+name+']').val('');
        }
        
        // update total amounts
        updateTotals();

    });
    
    // start over
    $('#start-over').click(function() {
        $dollarInputs.val('');
        $taxRate.val('25,00');
        updateTotals();
        return false;
    });
    
    // for browsers that remember input values on page reload (e.g. Firefox), enforce required formatting and trigger calculations on page load
    $dollarInputs.add($taxRate).each(function() {
        if ($(this).val() != '') {
            $(this).change();
        }
    }).eq(0).keyup();
    
    // ensure most recently opened help overlay is on top
    var zIndex = 1; // track highest z-index
    $('.togglehelplink').click(function() {
        var $overlayContainer = $(this).parents('.help-container:first');
        var $overlay = $overlayContainer.find('.callout:first');
        if ($overlay.is(':visible')) {
            $overlayContainer.css('zIndex', ++zIndex);
        }
    });

});

