
/**
 * This class provides a base class for loan types.
 * It uses the "template" design pattern where extending concrete
 * classes can override their own specific functionality.
 */
public abstract class Loan
{
    protected String m_name;
    protected double m_interestRate;
    protected int m_length;
    protected double m_principal;
    protected double m_monthlyPayment;

    /**
     * Construct a Loan object
     * @param name the name of the loanee
     * @param rate the interest rate of the loan
     * @param years the length of the loan in years
     * @param amount the initial principal of the loan
     */
    public Loan(String name, double rate, int years, double amount)
    {
        m_name = name;
        m_interestRate = rate;
        m_length = years;
        m_principal = amount;
    }

    /**
     * process() will calculate the monthly payment of the loan
     * @return a summary of the loan
     */
    public String process()
    {
        calcMonthlyPayment();
        return makeSummary();
    }

    /**
     * calcMonthlyPayment will calculate the monthly payment for the loan.
     * It is abstract and so implementing classes will have to provide
     * a definition for this method.
     */
    public abstract void calcMonthlyPayment();

    /**
     * makeSummary will create a textual description of the loan
     * @return a summary of the loan in text form
     */
    public String makeSummary()
    {
        return String.format(
            "%s for %s%n" +
            "%-16s: $%,.2f%n" +
            "%-16s: %.2f%n" +
            "%-16s: %d years%n" +
            "%-16s: $%,.2f%n",
            toString(), m_name,
            "Principal", m_principal,
            "Interest Rate", m_interestRate,
            "Length of Loan", m_length,
            "Monthly Payment", m_monthlyPayment);
    }
}
