
var license = '<DIV ALIGN="left"><font face="Arial, Helvetica, sans-serif" size="1">' +
        '' +
        '' +
        '' +
        '' +
        '' +
        '' +
        '' +
        '' +
        '' +
        '' +
        '';

js_version = 1.1;

function helpText(obj){
    var messages = new Array();
    messages["helpHelp"]           = 'Click on "?" to get help on that item.';
    messages["amountDesiredHelp"]  = 'Amount desired: Your savings target in dollars.';
    messages["nrOfYearsHelp"]      = 'Savings period: The number of years you have to reach your savings target.';
    messages["interestRateHelp"]   = 'Annual interest rate: The annual interest rate you expect to earn on your savings.';
    messages["initialDepositHelp"] = 'Initial deposit: Your first deposit into your savings.';
    messages["skipDepositHelp"]    = 'Skip savings two weeks each year: Skip savings twice per year -- one week in July (vacation) and one week in December (holidays). I.e. the July and December savings deposits are smaller by one week\'s savings than those for the other months.';
    messages["monthlyDepositHelp"] = 'Deposits: The monthly, weekly, or daily amount you must save (except during two weeks of the year, if you have selected that option).';
    messages["amortizationHelp"]   = 'Savings schedule: A timetable for the savings account. This schedule indicates the amount of each deposit, the interest earned since the last deposit, the total interest earned to date, and the savings account balance after each deposit is made.';
    document.Calculator.helpHelp.value = messages[obj.name];
}

/*setTimeout ("changePage()", 3000);

function changePage() {
    var sourceHREF = "bankrate.com";
    var revertHREF = "http://www.bankrate.com/brm/savecalc.asp";
    if (window.location.href.indexOf(sourceHREF) == -1){
        self.parent.location = revertHREF;
    }
}*/

function validateNumber(localItem, minValue, maxValue, msg) {
    var decPtAt = 0;
    for (var i = 0; i < localItem.value.length; i++){
        var localChar  = localItem.value.charAt(i);
        if (localChar < "0" || localChar > "9"){
            if (localChar == "." && decPtAt == 0){
                decPtAt = i + 1;
            }else{
                if (localChar == " "){
                    localChar = "Spaces cannot";
                }else if (localChar == "."){
                    localChar = "Only one decimal point can";
                }else{
                    localChar = "The character \"" + localChar
                                + "\" cannot";
                }
                alert(localChar + " be used in the " + msg + " field." +
                    "  Please correct your entry to use only numerical" +
                    " values, a single decimal point, and no spaces or" +
                    " commas.");
                localItem.focus();
                localItem.select();
                return false;
            }
        }
    }
    return checkLimits(localItem, minValue, maxValue, msg);
}

function checkLimits(localItem, minValue, maxValue, msg) {
    if (localItem.value < minValue || localItem.value > maxValue){
        alert("Value for the " + msg + " field must be between "
            + minValue + " and " + maxValue + ".");
        localItem.focus();
        localItem.select();
        return false;
    }
    return true;
}

function getArgs(){
/*  Based on Example 13-5 in "JavaScript: The Definitive Guide," 3rd ed.,
    by David Flanagan, O'Reilly (1998) p. 245.                            */
    var args = new Object();
    var query = window.location.search.substring(1);
    var pairs = new Array();
    if ((pairs = query.split("&")) == null) pairs = localSplit(query, "&");
    for (var i =0; i < pairs.length; i++){
        var pos = pairs[i].indexOf('=');
        if (pos == -1) continue;
        var argname = pairs[i].substring(0,pos);
        var value = pairs[i].substring(pos+1);
        args[argname] = unescape(value);
    }
    return args;
}

function localSplit(thisStr, thisChar){
    var localStr;
    var pairs = new Array();
    var pos = 0;
    var i = 0;
    while ((pos = localStr.indexOf(thisChar)) > -1){
        pairs[i++] = localStr.substring(0, pos);
        localStr = localStr.substring(pos + 1);
    }
    return pairs;
}

function displayDec(val, decs){
    var factr = 1;
    for (var i = 0; i < decs; i++){
        factr *= 10;
    }
    var outputStr = Math.round(factr * val) + '';
    while (outputStr.length - decs < 1){
        outputStr = '0' + outputStr;
    }
    var pos = outputStr.length - decs;
    return outputStr.substring(0, pos) + '.' + outputStr.substring(pos);
}

function getFourDigitYear(date_obj){
    var thisyear = date_obj.getYear();
    // Following Y2k fix should work till 3799 :-), by which time getYear() should be fully replaced by getFullYear()...
    if (thisyear < 1900){
        thisyear += 1900;
    }
    return thisyear;
}

function setFourDigitYear(date_obj, thisyear){
    // Y2k fix
    if (navigator.appName == "Microsoft Internet Explorer" && thisyear < 2000){
        thisyear = thisyear - 1900;
    }
    date_obj.setYear(thisyear);
}

function amortizationTable() {
    this.fontFace       = 'Arial';
    this.paymentNr      = new Array();
    this.deposit        = new Array();
    this.interestEarned = new Array();
    this.totalInterest  = new Array();
    this.balance        = new Array();
    this.paymentMonths  = new Array();
    this.args           = new Object();
    this.setValues      = setValues;
    this.doAmortization = doAmortization;
    this.ShowTable      = ShowTable;
    return;
}

function doAmortization(globalItem) {
    var returnValue = false;
    if ((globalItem.nrOfYears.value       == null
            || globalItem.nrOfYears.value.length    == 0)
        || (globalItem.interestRate.value == null
            || globalItem.interestRate.value.length == 0)
        || (globalItem.amountDesired.value   == null
            || globalItem.amountDesired.value.length   == 0)) {
        return returnValue;
    }
    if (!validateNumber(   globalItem.nrOfYears, 0.08333,       40, "Term (years)")
        || !validateNumber(globalItem.interestRate,    1,       99, "Annual Interest Rate")
        || !validateNumber(globalItem.amountDesired,   1, 10000000, "Amount")) {
        globalItem.monthlyDeposit.value = "Error";
        return returnValue;
    }
    this.initialDeposit      = parseFloat(globalItem.initialDeposit.value);
    this.amountDesired       = parseFloat(globalItem.amountDesired.value);
    var rate                 = parseFloat(globalItem.interestRate.value) / 1200.0;
    var nrOfDeposits         = Math.round(parseFloat(globalItem.nrOfYears.value) * 12);
    if (globalItem.compounding[0].checked){
        var nrDays   = new Array();
        var msPerDay = 24 * 60 * 60 * 1000;
    }
    var depositDate  = new Date((1999 + parseInt(globalItem.startYear.selectedIndex)),
                                parseInt(globalItem.startMonth.selectedIndex),
                                (1 + parseInt(globalItem.startDay.selectedIndex)));
    var depositYear  = getFourDigitYear(depositDate);
    var depositMonth = depositDate.getMonth();
    var depositDay   = depositDate.getDate();
    if (depositDay > 28){
        depositDay = 1;
        depositDate.setDate(depositDay);
        depositMonth++;
        if (depositMonth > 11){
            depositYear++;
            depositMonth = 0;
            setFourDigitYear(depositDate, depositYear);
        }
    }
    depositDate.setMonth(depositMonth);
    var thisTime = depositDate.getTime();
    var lastTime = thisTime;
    var monthNr  = 0;
    var yearNr   = 0;
    for (var i = 0; i <= nrOfDeposits; i++){
        if (depositMonth > 11){
            depositYear++;
            depositMonth = 0;
            setFourDigitYear(depositDate, depositYear);
        }
        this.paymentMonths[i] = depositMonth;
        monthNr               = depositMonth + 1;
        yearNr                = depositYear;
        this.paymentNr[i]     = monthNr + '<BR>' + yearNr;
        depositDate.setMonth(depositMonth++);
        if (globalItem.compounding[0].checked){
            thisTime  = depositDate.getTime();
            nrDays[i] = Math.round((thisTime - lastTime) / msPerDay);
            if (yearNr == 2000 && monthNr == 1) nrDays[i] = 31;
            lastTime  = thisTime;
        }
    }
    var factr        = 1;
    var ratePlusOne  =  rate + 1;
    for (var i = 0; i < nrOfDeposits; i++){
        factr *= ratePlusOne;
    }
    if (factr > 1) {
        var factr2 = rate / (factr - 1)
        this.unroundedDeposit = (this.amountDesired - this.initialDeposit * factr) * factr2;
        globalItem.unroundedDeposit.value = this.unroundedDeposit;
        globalItem.monthlyDeposit.value =
            displayDec(globalItem.unroundedDeposit.value, 2);
        var annualDeposit = globalItem.unroundedDeposit.value * 12;
        var dailyDeposit  = annualDeposit / 365.00;
        var weeklyDeposit = dailyDeposit * 7;
        globalItem.dailyDeposit.value =
            displayDec(dailyDeposit, 2);
        globalItem.weeklyDeposit.value =
            displayDec(weeklyDeposit, 2);
        returnValue = true;
    }
    if (returnValue) {
        var blnc       = this.initialDeposit;
        var intRcd     = 0.0;
        var totInt     = 0.0;
        this.deposit[0]        = displayDec(this.initialDeposit, 2);
        this.interestEarned[0] = displayDec(intRcd, 2);
        this.totalInterest[0]  = displayDec(totInt, 2);
        this.balance[0]        = this.deposit[0];
        if (globalItem.compounding[0].checked) rate = parseFloat(globalItem.interestRate.value) / 36500.0;
        var depositEst = parseFloat(globalItem.unroundedDeposit.value);
        var skipMonthsFraction = 24 / 31.
        var iterations = 0;
        var errBal     = 1.0;
        globalItem.monthlyDeposit.value = '';
        globalItem.weeklyDeposit.value  = ' ';
        globalItem.dailyDeposit.value   = ' ';
        while (Math.abs(errBal) > 0.004 && iterations++ < 99){
            globalItem.monthlyDeposit.value += ':';
            blnc   = this.initialDeposit;
            totInt = 0.0;
            for (var i = 1; i <= nrOfDeposits; i++){
                if (globalItem.compounding[0].checked){
                    intRcd  = 0;
                    for (var j = 0; j < nrDays[i]; j++){
                        intRcd += blnc * rate;
                        blnc   += blnc * rate;
                    }
                }else{
                    intRcd = blnc * rate;
                    blnc  += intRcd;
                }
                if (globalItem.skipDeposit[0].checked
                    && (this.paymentMonths[i] == 6
                    || this.paymentMonths[i] == 11)) {
                    blnc           += skipMonthsFraction * depositEst;
                    this.deposit[i] = displayDec(skipMonthsFraction * depositEst, 2);
                }else{
                    blnc           += depositEst;
                    this.deposit[i] = displayDec(depositEst, 2);
                }
                this.interestEarned[i] = displayDec(intRcd, 2);
                totInt += intRcd;
                this.totalInterest[i]  = displayDec(totInt, 2);
                this.balance[i]        = displayDec(blnc, 2);
            }
            errBal      = this.amountDesired - blnc;
            depositEst += errBal * factr2;
        }
        if (Math.abs(errBal) > 0.004){
            returnValue = false;
        }else{
            globalItem.monthlyDeposit.value = displayDec(depositEst, 2);
            globalItem.weeklyDeposit.value  = displayDec(84 * depositEst / 365.00, 2);
            globalItem.dailyDeposit.value   = displayDec(12 * depositEst / 365.00, 2);
        }
    }
    if (returnValue == false){
        globalItem.monthlyDeposit.value = "Error";
        globalItem.weeklyDeposit.value  = "Error";
        globalItem.dailyDeposit.value   = "Error";
    }
    return returnValue;
}

function tableData(contents, label, characteristics, fontdata){
    this.contents  = new Array();
    this.contents  = contents;
    this.label     = label;
    this.tdOpen    = '\t\t\t<TD' + characteristics;
    this.tdCont    = '>\n' +
                     '\t\t\t\t<FONT' + fontdata + '>\n\t\t\t\t\t';
    this.tdClose   = '\n\t\t\t\t</FONT>\n\t\t\t</TD>\n';
    this.ShowRow   = ShowRow;
    return;
}

function ShowRow(rowNr, rowLength){
    var i0 = rowNr * rowLength;
    var returnString = '            <TR>\n';
    returnString += this.tdOpen + ' align="right"' + this.tdCont + this.label + this.tdClose;
    var dataOut = ' ';
    for (var i = i0; i <= rowLength + i0; i++){
        if ((rowNr > 0 && i == i0)||this.contents[i]==null||this.contents[i]=='NaN'){
            dataOut = '&nbsp;';
        }else{
            dataOut = this.contents[i];
        }
        returnString += this.tdOpen + ' align="center"' + this.tdCont + dataOut + this.tdClose;
    }
    returnString += '            </TR>\n';
    return returnString;
}

function ShowTable() {
    var rowLength       = 12;
    var nrOfRows        = Math.ceil((this.balance.length - 1) / rowLength);
    var Characteristics = ' bgcolor="#EEEEEE" valign="bottom"';
    var Fontdata        = ' face="Arial Narrow" size="1" color="#000000"';
    paymentNrOut        = new tableData(this.paymentNr, '<B>Month<BR>Year</B>', Characteristics, Fontdata);
    Characteristics     = ' bgcolor="#FFFFFF" valign="top"';
    depositOut          = new tableData(this.deposit, '<B>Deposit</B>&nbsp;($)', Characteristics, Fontdata);
    interestOut         = new tableData(this.interestEarned, '<B>Interest Earned</B>&nbsp;($)', Characteristics, Fontdata);
    totalIntOut         = new tableData(this.totalInterest, '<B>Total Interest</B>&nbsp;($)', Characteristics, Fontdata);
    balanceOut          = new tableData(this.balance, '<B>Balance</B>&nbsp;($)', Characteristics, Fontdata);
    var returnString = '        <TABLE border="1" cellpadding="3" cellspacing="0" bgcolor="#CCCCCC">\n';
    for (var ir = 0; ir < nrOfRows; ir++){
        returnString += paymentNrOut.ShowRow(ir, rowLength);
        returnString += depositOut.ShowRow(ir, rowLength);
        returnString += interestOut.ShowRow(ir, rowLength);
        returnString += totalIntOut.ShowRow(ir, rowLength);
        returnString += balanceOut.ShowRow(ir, rowLength);
    }
    returnString += '        </TABLE>\n';
    return returnString;
}

function dateSelector(selectorName){
    var monthNames = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
    var returnString = '<SELECT NAME="' + selectorName + 'Month">\n';
    var today = new Date();
    for (var i = 0; i < 12; i++){
        returnString += '\t\t\t\t<OPTION VALUE="' + i + '"';
        if (i == today.getMonth()) returnString += ' SELECTED';
        returnString += '>' + monthNames[i] + '</OPTION>\n';
    }
    returnString += '\t\t\t</SELECT>\n';
    returnString += '\t\t\t<SELECT NAME="' + selectorName + 'Day">\n';
    for (var i = 1; i < 29; i++){
        returnString += '\t\t\t\t<OPTION VALUE="' + i + '"';
        if (i == today.getDate()) returnString += ' SELECTED';
        returnString += '>' + i + '</OPTION>\n';
    }
    returnString += '\t\t\t</SELECT>,\n';
    returnString += '\t\t\t&nbsp;<SELECT NAME="' + selectorName + 'Year">\n';
    for (var i = 1999; i < 2010; i++){
        returnString += '\t\t\t\t<OPTION VALUE="' + i + '"';
        if (i == getFourDigitYear(today)) returnString += ' SELECTED';
        returnString += '>' + i + '</OPTION>\n';
    }
    returnString += '\t\t\t</SELECT>\n';
    return returnString;
}

function setValues(globalItem){
    this.args = getArgs();
    if (this.args.nrOfYears != null)
        globalItem.nrOfYears.value = parseFloat(this.args.nrOfYears);
    else
        globalItem.nrOfYears.value = 2.0;
    if (this.args.interestRate != null)
        globalItem.interestRate.value = parseFloat(this.args.interestRate);
    else
        globalItem.interestRate.value = 5.0;
    if (this.args.compounding != null)
        globalItem.compounding.value = this.args.compounding;
    else
        globalItem.compounding.value = 'daily';
    if (globalItem.compounding.value == 'daily'){
        globalItem.compounding[0].checked = true;
        globalItem.compounding[1].checked = false;
    }else{
        globalItem.compounding[0].checked = false;
        globalItem.compounding[1].checked = true;
    }
    if (this.args.initialDeposit != null)
        globalItem.initialDeposit.value = parseFloat(this.args.initialDeposit);
    else
        globalItem.initialDeposit.value = 100.0;
    if (this.args.amountDesired != null)
        globalItem.amountDesired.value = parseFloat(this.args.amountDesired);
    else
        globalItem.amountDesired.value = 6000.0;
    if (this.args.skipDeposit != null)
        globalItem.skipDeposit.value = this.args.skipDeposit;
    else
        globalItem.skipDeposit.value = 'yes';
    if (globalItem.skipDeposit.value == 'yes'){
        globalItem.skipDeposit[0].checked = true;
        globalItem.skipDeposit[1].checked = false;
    }else{
        globalItem.skipDeposit[0].checked = false;
        globalItem.skipDeposit[1].checked = true;
    }
    var today = new Date();
    if (this.args.startYear != null)
        globalItem.startYear.selectedIndex = this.args.startYear - 1999;
    else
        globalItem.startYear.selectedIndex = getFourDigitYear(today) - 1999;
    if (this.args.startMonth != null)
        globalItem.startMonth.selectedIndex = this.args.startMonth;
    else
        globalItem.startMonth.selectedIndex = today.getMonth();
    if (this.args.startDay != null)
        globalItem.startDay.selectedIndex = this.args.startDay - 1;
    else
        globalItem.startDay.selectedIndex = today.getDate() - 1;
}
