/*
** amortize.c    Demonstration C program to calculate loan payments
**               on standard fixed rate loans
**
** 6-16-07, http://willus.com
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>

int main(void)

    {
    char buf[64];
    double annual_rate_percent;
    double years;
    double months;
    double loan_amount;
    double principal;
    double monthly_rate_percent;
    double monthly_rate;
    double monthly_increase;
    double monthly_payment;
    double monthly_extra;
    double extra_start;
    double fixed_payment;
    int i,imod;

    printf("Fixed mortgage payment calculator from http://willus.com.\n\n");
    printf("Enter annual rate (%%, def=7.00):  ");
    fgets(buf,30,stdin);
    if (buf[0]=='\n')
        annual_rate_percent = 7.00;
    else
        annual_rate_percent = atof(buf);
    printf("Enter loan amount ($, def=150000):  ");
    fgets(buf,30,stdin);
    if (buf[0]=='\n')
        loan_amount = 150000.;
    else
        loan_amount = atof(buf);
    printf("Enter number of years or fixed payment? (Y or F, def=Y):  ");
    fgets(buf,30,stdin);
    if (tolower(buf[0])!='f')
        {
        printf("Enter number of years (def=30):  ");
        fgets(buf,30,stdin);
        if (buf[0]=='\n')
            years = 30;
        else
            years = atof(buf);
        months = years * 12.;
        fixed_payment=0.;
        }
    else
        {
        printf("Enter fixed payment ($):  ");
        fgets(buf,30,stdin);
        fixed_payment = atof(buf);
        months=years=0;
        }
    if (fixed_payment<=0.)
        {
        printf("Enter monthly extra (def=0):  ");
        fgets(buf,30,stdin);
        if (buf[0]=='\n')
            monthly_extra=0.;
        else
            monthly_extra = atof(buf);
        printf("Enter monthly extra starting month (def=0):  ");
        fgets(buf,30,stdin);
        if (buf[0]=='\n')
            extra_start=0.;
        else
            extra_start = atof(buf);
        }
    else
        {
        extra_start=999999;
        monthly_extra=0.;
        }
    /*
    ** Note that the monthly rate is not, as you might expect,
    **
    ** 100 * ( ( ( 1 + annual_rate_percent / 100. ) ^ ( 1 / 12. ) ) - 1. )
    **
    ** ... which would, when compounded monthly, result in exactly the
    ** annual rate after one year.  Instead, the convention is simply
    ** to use the annual rate divided by 12, which is pretty close to
    ** the same value.  E.g. for an annual rate of 12.00 %, the monthly
    ** rate calculated by the formula above would be about 0.949 %,
    ** whereas the simpler "divide by 12" formula yields exactly 1.000 %.
    */
    monthly_rate_percent = annual_rate_percent / 12.;
    monthly_rate = monthly_rate_percent / 100.;
    monthly_increase = 1.0 + monthly_rate;

    /* The magic monthly payment formula */
    if (fixed_payment > 0.)
        monthly_payment = fixed_payment;
    else
        monthly_payment = loan_amount * monthly_rate * pow(monthly_increase,months)
                          / (pow(monthly_increase,months) - 1.);

    printf("\nAnnual Rate = %.3f %%\n",annual_rate_percent);
    printf("Loan Amount = $%g\n",loan_amount);
    printf("Number of Years = %g\n",years);
    printf("Monthly Payment = $%.2f\n",monthly_payment);
    printf("Payment #      Interest     Remaining Principal\n"
           "-----------------------------------------------\n");
    imod = (int)(months/30.+.1); // How often to print the values
    if (imod<1)
        imod=1;

    /* Loop to calculate remaining principal over time */
    principal=loan_amount;
    
    for (i=1;1;i++)
        {
        double interest;

        interest = principal * monthly_rate;
        principal = principal + interest - monthly_payment;
        if (i>=extra_start)
            principal -= monthly_extra;
        if (i==1 || i%imod==0 || principal<=0.)
            printf(" %4d         %9.2f         %9.2f\n",i,interest,principal);
        if (principal<=0.)
            break;
        }
    printf("\nPress <Enter> to exit.\n");
    fgets(buf,30,stdin);
    return(0);
    }
