//********************************************************
//
// Assignment 11 - Object Oriented Design
//
// Name: <Amir Gharouadi>
//
// Class: C Programming, <Spring 2026>
//
// Date: <04/23/2026>
//
// 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>

using namespace std;

#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 NAME_SIZE 20
#define TAX_STATE_SIZE 3
#define FED_TAX_RATE 0.25
#define FIRST_NAME_SIZE 10
#define LAST_NAME_SIZE 10

#define EMP_SIZE 5

using std::string;

class Employee
{
private:
	string firstName = "";
	string lastName  = "";
	string taxState = "";
	int clockNumber = 0;
	float wageRate = 0.0;
	float hours = 0.0;
	float overTimeHrs = 0.0;
	float grossPay = 0.0;
	float stateTax = 0.0;
	float fedTax = 0.0;
	float netPay = 0.0;

	float calcOverTimeHrs();
	float calcGrossPay();
	float calcStateTax();
	float calcFedTax();
	float calcNetPay();

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

	float getStateTax();
	float getFedTax();
	float getNetPay();

public:
	Employee() {}

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

	~Employee();

	void printEmployee();

};

inline string Employee::getFirstName() {
	return firstName;
}

inline string Employee::getLastName() {
	return lastName;
}

inline string Employee::getTaxState() {
	return taxState;
}

inline int Employee::getClockNumber() {
	return clockNumber;
}

inline float Employee::getWageRate() {
	return wageRate;
}

inline float Employee::getHours() {
	return hours;
}

inline float Employee::getOverTimeHrs() {
	return overTimeHrs;
}

inline float Employee::getGrossPay() {
	return grossPay;
}

inline float Employee::getStateTax() {
	return stateTax;
}

inline float Employee::getFedTax() {
	return fedTax;
}

inline float Employee::getNetPay() {
	return netPay;
}

float Employee::calcOverTimeHrs()
{
	if (hours > STD_HOURS)
		overTimeHrs = hours - STD_HOURS;
	else
		overTimeHrs = 0;

	return overTimeHrs;
}

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

	return grossPay;
}

float Employee::calcStateTax()
{
	float theStateTax;

	theStateTax = grossPay;

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

	return theStateTax;
}

float Employee::calcFedTax()
{
	float theFedTax;

	theFedTax = grossPay * FED_TAX_RATE;

	return theFedTax;
}

float Employee::calcNetPay()
{
	float theNetPay;
	float theTotalTaxes;

	theTotalTaxes = stateTax + fedTax;

	theNetPay = grossPay - theTotalTaxes;

	return theNetPay;
}

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

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

	taxState = myTaxState;
	clockNumber = myClockNumber;
	wageRate = myWageRate;
	hours = myHours;
	overTimeHrs = calcOverTimeHrs();
	grossPay = calcGrossPay();

	stateTax = calcStateTax();
	fedTax = calcFedTax();
	netPay = calcNetPay();

}

void Employee::printEmployee() {

	cout << endl << endl <<"*** Entered Details are *** " << endl;
	cout << endl <<" First Name: "<< getFirstName();
	cout << endl <<" Last Name: "<<  getLastName();
	cout << endl <<" Tax State: "<<  getTaxState();
	cout << endl <<" Clock Number: "<< getClockNumber();
	cout << endl <<" Wage Rate: "<< getWageRate();
	cout << endl <<" Hours: "<< getHours();

	cout<< endl << endl <<" *** Calculated Values are *** " << endl;

	cout << endl << " Overtime Hours : " <<  getOverTimeHrs();

	cout << endl << " Gross Pay : $" <<  getGrossPay();

	cout << endl << " State Tax : $" << getStateTax();

	cout << endl << " Federal Tax : $" << getFedTax();

	cout << endl << " Net Pay : $" << getNetPay();

	cout <<"\n";

}

Employee::~Employee()
{
}

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

	cout << fixed
	     << setprecision(2);

	Employee e[EMP_SIZE];

	for (int i = 0; i < EMP_SIZE; ++i)
	{
		cout <<"\n\n Enter Employee First Name: ";
		cin>>myFirstName;
		cout <<"\n Enter Employee Last Name: ";
		cin>>myLastName;
		cout <<"\n Enter Employee Tax State: ";
		cin>>myTaxState;
		cout<<"\n Enter Employee Clock Number: ";
		cin>>myClockNumber;
		cout <<"\n Enter Employee Hourly Wage Rate: ";
		cin>>myWageRate;
		cout <<"\n Enter Employee Hours Worked for the Week: ";
		cin>>myHours;

		e[i] = {myFirstName, myLastName, myTaxState,
		        myClockNumber, myWageRate, myHours
		       };

		e[i].printEmployee();

	}

	return 0;

}