/********************************************************
 *
 * Assignment 11 - Object Oriented Design (C-Compatible Version)
 *
 * Name: John Semenuk
 * Class: C Programming, Spring 2026
 * Date: April 27, 2026
 *
 * Description:
 * This version is rewritten in standard C so it will compile
 * correctly as prog.c using gcc.
 *
 ********************************************************/

#include <stdio.h>
#include <string.h>
#include <ctype.h>

// constants
#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
#define EMP_SIZE 5

// structure for Employee
struct Employee
{
    char firstName[20];
    char lastName[20];
    char taxState[3];
    int clockNumber;
    float wageRate;
    float hours;
    float overTimeHrs;
    float grossPay;
    float stateTax;
    float fedTax;
    float netPay;
};

// function prototypes
float calcOverTimeHrs(float hours);
float calcGrossPay(float wageRate, float hours, float overTimeHrs);
float calcStateTax(float grossPay, char taxState[]);
float calcFedTax(float grossPay);
float calcNetPay(float grossPay, float stateTax, float fedTax);
void printEmployee(struct Employee e);

// overtime
float calcOverTimeHrs(float hours)
{
    if (hours > STD_HOURS)
        return hours - STD_HOURS;
    else
        return 0.0;
}

// gross pay
float calcGrossPay(float wageRate, float hours, float overTimeHrs)
{
    if (overTimeHrs > 0)
    {
        return (STD_HOURS * wageRate) +
               (overTimeHrs * (wageRate * OT_RATE));
    }
    else
    {
        return wageRate * hours;
    }
}

// state tax
float calcStateTax(float grossPay, char taxState[])
{
    if (strcmp(taxState, "MA") == 0)
        return grossPay * MA_TAX_RATE;
    else if (strcmp(taxState, "VT") == 0)
        return grossPay * VT_TAX_RATE;
    else if (strcmp(taxState, "NH") == 0)
        return grossPay * NH_TAX_RATE;
    else if (strcmp(taxState, "CA") == 0)
        return grossPay * CA_TAX_RATE;
    else
        return grossPay * DEFAULT_TAX_RATE;
}

// federal tax
float calcFedTax(float grossPay)
{
    return grossPay * FED_TAX_RATE;
}

// net pay
float calcNetPay(float grossPay, float stateTax, float fedTax)
{
    return grossPay - (stateTax + fedTax);
}

// print employee
void printEmployee(struct Employee e)
{
    printf("\n\n*** Entered Details are *** \n");

    printf("\n First Name: %s", e.firstName);
    printf("\n Last Name: %s", e.lastName);
    printf("\n Tax State: %s", e.taxState);
    printf("\n Clock Number: %d", e.clockNumber);
    printf("\n Wage Rate: %.2f", e.wageRate);
    printf("\n Hours: %.2f", e.hours);

    printf("\n\n *** Calculated Values are *** \n");

    printf("\n Overtime Hours : %.2f", e.overTimeHrs);
    printf("\n Gross Pay : $%.2f", e.grossPay);
    printf("\n State Tax : $%.2f", e.stateTax);
    printf("\n Federal Tax : $%.2f", e.fedTax);
    printf("\n Net Pay : $%.2f", e.netPay);

    printf("\n\n");
}

// main
int main()
{
    struct Employee e[EMP_SIZE];
    int i, j;

    for (i = 0; i < EMP_SIZE; i++)
    {
        printf("\n\n Enter Employee First Name: ");
        scanf("%s", e[i].firstName);

        printf("\n Enter Employee Last Name: ");
        scanf("%s", e[i].lastName);

        printf("\n Enter Employee Tax State: ");
        scanf("%s", e[i].taxState);

        // convert taxState to uppercase
        for (j = 0; e[i].taxState[j]; j++)
        {
            e[i].taxState[j] = toupper(e[i].taxState[j]);
        }

        printf("\n Enter Employee Clock Number: ");
        scanf("%d", &e[i].clockNumber);

        printf("\n Enter Employee Hourly Wage Rate: ");
        scanf("%f", &e[i].wageRate);

        printf("\n Enter Employee Hours Worked for the Week: ");
        scanf("%f", &e[i].hours);

        // calculations
        e[i].overTimeHrs = calcOverTimeHrs(e[i].hours);
        e[i].grossPay = calcGrossPay(e[i].wageRate, e[i].hours, e[i].overTimeHrs);
        e[i].stateTax = calcStateTax(e[i].grossPay, e[i].taxState);
        e[i].fedTax = calcFedTax(e[i].grossPay);
        e[i].netPay = calcNetPay(e[i].grossPay, e[i].stateTax, e[i].fedTax);

        // output
        printEmployee(e[i]);
    }

    return 0;
}
