// ==========================================================================
// Author:  Yee Hsu
// Date:    8/11/2005
// File:    Bank.cpp
//
// Desc:    Calculates loan payments for mortgages base on principal, loan
//          interest, balance, and provides a monthly payment and
//          amortization list.
//
//          Calculation is base on real world application and provides real
//          interest rate balance sheet to help determine if you wish to
//          purchase property as a home or investment.
// ==========================================================================

// ==========================================================================
// Identifier:  Bank()
//
// Description: Bank Constructor
//              Initialize default fields
// ==========================================================================

Bank::Bank()
{
    // initial Loan value
    this->loan.nYear            = 0;
    this->loan.dAmount          = 0.0;
    this->loan.dRate            = 0.0;

    // Loan value after user prompt
    this->loan.nNumMonth        = 0;
    this->loan.dPrinciple       = 0.0;
    this->loan.dMonthlyPayment  = 0.0;
    this->loan.dInterest        = 0.0;
}

// ==========================================================================
// Identifier:  CalculatePayment()
//
// Description: Calculates the monthly expected payment to the bank.
// ==========================================================================

double Bank::CalculatePayment()
{
    // combine with year annual compound
    this->loan.dPrinciple   = this->loan.dAmount;
    this->loan.dInterest    = this->loan.dRate  / 12 / 100.0;
    this->loan.nNumMonth    = this->loan.nYear  * 12;

    // calculate monthly payment
    double dPow = pow(1 + this->loan.dInterest, -this->loan.nNumMonth);
    this->loan.dMonthlyPayment = (this->loan.dAmount * this->loan.dInterest) / (1 - dPow);

    return this->loan.dMonthlyPayment;
}

// ==========================================================================
// Identifier:  AskLoanData()
//
// Description: Does some simple question asking to prior to any calculations
// ==========================================================================

void Bank::AskLoanData()
{
    cout << "Please enter the loan you want to borrow: ";
    cin  >> loan.dAmount;

    cout << "Please enter the APR (Anual Percentage Rate): ";
    cin  >> loan.dRate;

    cout << "Please enter the number of years: ";
    cin  >> loan.nYear;

    this->CalculatePayment();
}

// ==========================================================================
// Identifier:  ShowPayment()
//
// Description: Shows the monthly payment needed
// ==========================================================================

void Bank::ShowPayment()
{
    cout.setf(ios::showpoint | ios::fixed);
    cout.precision(2);

    cout << "\nYour monthly payment is $"
         << this->loan.dMonthlyPayment;

    cout << "\nYour total payment is $"
         << this->loan.dMonthlyPayment * this->loan.nNumMonth;

    cout << "\nThe bank total interest earned is $"
         << this->loan.dMonthlyPayment * this->loan.nNumMonth - this->loan.dAmount;

    cout << endl;
}

// ==========================================================================
// Identifier:  ShowAmrList()
//
// Description: Shows detail amortization schedule on a balance sheet
// ==========================================================================

void Bank::ShowAmrList()
{
    const int   SIZE        = 04;
    const int   WIDTH       = 12;
    int         nLoop       = 0;
    int         nYearNum    = 1;

    cout << "\n\t\t\t\tYear "   << nYearNum;
    cout << setw(SIZE)          << "\n\n No.";
    cout << setw(WIDTH)         << "Balance B.";
    cout << setw(WIDTH)         << "Payment";
    cout << setw(WIDTH)         << "Total Paid";
    cout << setw(WIDTH)         << "Rate/Bal";
    cout << setw(WIDTH)         << "Rate/Pay";
    cout << setw(WIDTH)         << "Balance A.";
    cout << endl;

    for (int index = 1; index <= this->loan.nNumMonth; index++)
    {
        cout << setw(SIZE)      << index;
        cout << setw(WIDTH)     << this->loan.dPrinciple;
        cout << setw(WIDTH)     << this->loan.dMonthlyPayment;
        cout << setw(WIDTH)     << this->loan.dMonthlyPayment * index;
        cout << setw(WIDTH)     << this->loan.dPrinciple * this->loan.dInterest;
        cout << setw(WIDTH)     << this->loan.dMonthlyPayment - (this->loan.dPrinciple * this->loan.dInterest);

        // recalulate next balance
        this->loan.dPrinciple = this->loan.dPrinciple * (this->loan.dInterest + 1) - this->loan.dMonthlyPayment;

        cout << setw(WIDTH)     << this->loan.dPrinciple;
        cout << endl;

        nLoop++;

        if (nLoop == 12 && index != this->loan.nNumMonth)
        {
            cout << "\nPress ENTER to continue...";
            cout.flush();
            getchar();

            nYearNum++;
            cout <<"\n\t\t\t\tYear "    <<nYearNum;
            cout << setw(SIZE)          << "\n\n No.";
            cout << setw(WIDTH)         << "Balance B.";
            cout << setw(WIDTH)         << "Payment";
            cout << setw(WIDTH)         << "Total Paid";
            cout << setw(WIDTH)         << "Rate/Bal";
            cout << setw(WIDTH)         << "Rate/Pay";
            cout << setw(WIDTH)         << "Balance A.";
            cout << endl;

            nLoop = 0;
        }
    }
}