//********************************************************
//
// Assignment 11 - Object Oriented Design
//
// Name: MARTIN CLYTON MAYANJA
//
// Class: C Programming, SPRING,2026
//
// Date: 24APRIL2026
//
// Description: An object oriented program design using
// C++ that will process our existing set of employees.
// It utilizes a class called Employee and generates an 
// array of objects that are used to store, calculate,
// and print out a simple report of inputted and calculated
// values.
//
//
// Object Oriented Design (using C++)
//
//********************************************************

#include <iomanip>
#include <iostream>
#include <string>
#include <cctype>

#define EMP_SIZE 5
#define STD_HOURS 40.0
#define OT_RATE 1.5
#define MA_TAX_RATE 0.05
#define NH_TAX_RATE 0.0
#define VT_TAX_RATE 0.06
#define CA_TAX_RATE 0.07
#define DEFAULT_TAX_RATE 0.08
#define FED_TAX_RATE 0.25

using namespace std;

// class Employee
class Employee
{
    private:
        string firstName;
        string lastName;
        string taxState;
        int clockNumber;
        float wageRate;
        float hours;
        float overTimeHrs;
        float grossPay;
        float stateTax;   
        float fedTax;     
        float netPay;     
        
        float calcOverTimeHrs ()
        {
            if (hours > STD_HOURS)
                overTimeHrs = hours - STD_HOURS;
            else
                overTimeHrs = 0;

            return overTimeHrs;
        }

        float calcGrossPay ()
        {
            if (overTimeHrs > 0)
                grossPay = (STD_HOURS * wageRate) + 
                           (overTimeHrs * (wageRate * OT_RATE));
            else
                grossPay = wageRate * hours;

            return grossPay;
        }

        float calcStateTax ()
        {
            float theStateTax = grossPay;

            if (taxState == "MA")
                theStateTax *= MA_TAX_RATE;
            else if (taxState == "VT")
                theStateTax *= VT_TAX_RATE;
            else if (taxState == "NH")
                theStateTax *= NH_TAX_RATE;
            else if (taxState == "CA")
                theStateTax *= CA_TAX_RATE;
            else
                theStateTax *= DEFAULT_TAX_RATE;

            return theStateTax;
        }

        float calcFedTax ()
        {
            return grossPay * FED_TAX_RATE;
        }

        float calcNetPay ()
        {
            return grossPay - (stateTax + fedTax);
        }

    public:

        Employee()
        {
            firstName = "";
            lastName = "";
            taxState = "";
            clockNumber = 0;
            wageRate = 0;
            hours = 0;
            overTimeHrs = 0;
            grossPay = 0;
            stateTax = 0;
            fedTax = 0;
            netPay = 0;
        }

        Employee (string myFirstName, string myLastName, string myTaxState,
                  int myClockNumber, float myWageRate, float myHours);

        ~Employee();

        string getFirstName();
        string getLastName();
        string getTaxState();
        int getClockNumber();
        float getWageRate();
        float getHours();
        float getOverTimeHrs();
        float getGrossPay();

        // TODO - Add public getter function prototype to retrieve stateTax
        float getStateTax();

        // TODO - Add public getter function prototype to retrieve fedTax
        float getFedTax();

        // TODO - Add public getter function prototype to retrieve netPay
        float getNetPay();

        void printEmployee(Employee e);
};

// constructor
Employee::Employee (string myFirstName, string myLastName, string myTaxState,
                    int myClockNumber, float myWageRate, float myHours)
{
    firstName = myFirstName;
    lastName = myLastName;

    if (islower(myTaxState[0]))
        myTaxState[0] = toupper(myTaxState[0]);
    if (islower(myTaxState[1]))
        myTaxState[1] = toupper(myTaxState[1]);

    taxState = myTaxState;
    clockNumber = myClockNumber;
    wageRate = myWageRate;
    hours = myHours;

    overTimeHrs = calcOverTimeHrs();
    grossPay = calcGrossPay();

    // TODO - set stateTax as the return from calcStateTax member function
    stateTax = calcStateTax();

    // TODO - set fedTax as the return from calcFedTax member function
    fedTax = calcFedTax();

    // TODO - set netPay as the return from calcNetPay member function
    netPay = calcNetPay();
}

Employee::~Employee() {}

string Employee::getFirstName() { return firstName; }
string Employee::getLastName() { return lastName; }
string Employee::getTaxState() { return taxState; }
int Employee::getClockNumber() { return clockNumber; }
float Employee::getWageRate() { return wageRate; }
float Employee::getHours() { return hours; }
float Employee::getOverTimeHrs() { return overTimeHrs; }
float Employee::getGrossPay() { return grossPay; }

// TODO - Add a "getter" function that will retrieve the employee stateTax
float Employee::getStateTax() { return stateTax; }

// TODO - Add a "getter" function that will retrieve the employee fedTax
float Employee::getFedTax() { return fedTax; }

// TODO - Add a "getter" function that will retrieve the employee netPay
float Employee::getNetPay() { return netPay; }

void Employee::printEmployee(Employee e)
{
    cout << "\n\n *** Entered Details are *** \n";
    cout << "\n First Name: " << e.getFirstName();
    cout << "\n Last Name: " << e.getLastName();
    cout << "\n Tax State: " << e.getTaxState();
    cout << "\n Clock Number: " << e.getClockNumber();
    cout << "\n Wage Rate: " << e.getWageRate();
    cout << "\n Hours: " << e.getHours();

    cout << "\n\n *** Calculated Values are *** \n";
    cout << "\n Overtime Hours : " << e.getOverTimeHrs();
    cout << "\n Gross Pay : $" << e.getGrossPay();

    // TODO - Add cout statement with call to stateTax getter function
    cout << "\n State Tax : $" << e.getStateTax();

    // TODO - Add cout statement with call to fedTax getter function
    cout << "\n Fed Tax : $" << e.getFedTax();

    // TODO - Add cout statement with call to netPay getter function
    cout << "\n Net Pay : $" << e.getNetPay();

    cout << "\n";
}

int main ()
{
    string myFirstName, myLastName, myTaxState;
    int myClockNumber;
    float myWageRate, myHours;

    cout << fixed << setprecision(2);

    Employee e[EMP_SIZE];

    for (int i = 0; i < EMP_SIZE; ++i)
    {
        cin >> myFirstName >> myLastName >> myTaxState
            >> myClockNumber >> myWageRate >> myHours;

        e[i] = Employee(myFirstName, myLastName, myTaxState,
                        myClockNumber, myWageRate, myHours);

        e[i].printEmployee(e[i]);
    }

    return 0;
} // main 
