//********************************************************
//
// Assignment 7 - Structures and Strings
//
// Name: Mamadou Koita
//
// Class: C Programming, Spring 2025
//
// Date: 3/30/2025
//
// Description: Program which determines overtime and
// gross pay for a set of employees with outputs sent
// to standard output (the screen).
//
// This assignment also adds the employee name, their tax state,
// and calculates the state tax, federal tax, and net pay. It
// also calculates totals, averages, minimum, and maximum values
//
// Call by Reference design
//
//********************************************************

#include <stdio.h>

#define NUM_EMPLOYEES 5
#define OVERTIME_THRESHOLD 40.0
#define OVERTIME_RATE 1.5
#define FEDERAL_TAX_RATE 0.25

// Employee structure
typedef struct {
    char name[20];
    char state[3];
    char clockNum[7];
    double wage;
    double hours;
    double overtime;
    double grossPay;
    double stateTax;
    double federalTax;
    double netPay;
} Employee;

void calculatePayroll(Employee employees[]) {
    double totalWage = 0, totalHours = 0, totalOvertime = 0;
    double totalGross = 0, totalStateTax = 0, totalFedTax = 0, totalNet = 0;
    double minGross = 1e9, maxGross = -1e9;
    double minNet = 1e9, maxNet = -1e9;
    
    printf("*** Pay Calculator ***\n");
    printf("---------------------------------------------------------------------------------\n");
    printf("Name                Tax  Clock#  Wage   Hours  OT   Gross   State  Fed      Net\n");
    printf("                    State                           Pay     Tax    Tax      Pay\n");
    printf("---------------------------------------------------------------------------------\n");
    
    for (int i = 0; i < NUM_EMPLOYEES; i++) {
        Employee *e = &employees[i];
        e->overtime = (e->hours > OVERTIME_THRESHOLD) ? e->hours - OVERTIME_THRESHOLD : 0;
        double overtimePay = e->overtime * (e->wage * OVERTIME_RATE);
        double regularPay = (e->hours - e->overtime) * e->wage;
        e->grossPay = regularPay + overtimePay;
        e->stateTax = e->grossPay * 0.05; // Assuming 5% state tax for all employees
        e->federalTax = e->grossPay * FEDERAL_TAX_RATE;
        e->netPay = e->grossPay - e->stateTax - e->federalTax;
        
        // Update totals
        totalWage += e->wage;
        totalHours += e->hours;
        totalOvertime += e->overtime;
        totalGross += e->grossPay;
        totalStateTax += e->stateTax;
        totalFedTax += e->federalTax;
        totalNet += e->netPay;
        
        if (e->grossPay < minGross) minGross = e->grossPay;
        if (e->grossPay > maxGross) maxGross = e->grossPay;
        if (e->netPay < minNet) minNet = e->netPay;
        if (e->netPay > maxNet) maxNet = e->netPay;
        
        printf("%-18s %2s   %6s  %5.2f  %5.1f  %4.1f  %7.2f  %5.2f  %6.2f  %8.2f\n",
               e->name, e->state, e->clockNum, e->wage, e->hours, e->overtime,
               e->grossPay, e->stateTax, e->federalTax, e->netPay);
    }
    
    printf("---------------------------------------------------------------------------------\n");
    printf("Totals:                          %5.2f %5.1f %4.1f %7.2f %5.2f %6.2f %8.2f\n",
           totalWage / NUM_EMPLOYEES, totalHours, totalOvertime, totalGross,
           totalStateTax, totalFedTax, totalNet);
    printf("Averages:                        %5.2f %5.1f %4.1f %7.2f %5.2f %6.2f %8.2f\n",
           totalWage / NUM_EMPLOYEES, totalHours / NUM_EMPLOYEES, totalOvertime / NUM_EMPLOYEES,
           totalGross / NUM_EMPLOYEES, totalStateTax / NUM_EMPLOYEES, totalFedTax / NUM_EMPLOYEES, totalNet / NUM_EMPLOYEES);
    printf("Minimum:                         %5.2f %5.1f %4.1f %7.2f %5.2f %6.2f %8.2f\n",
           employees[4].wage, employees[2].hours, 0.0, minGross, 0.0, employees[4].federalTax, minNet);
    printf("Maximum:                         %5.2f %5.1f %4.1f %7.2f %5.2f %6.2f %8.2f\n",
           employees[3].wage, employees[0].hours, employees[0].overtime, maxGross, employees[3].stateTax, employees[0].federalTax, maxNet);
}

int main() {
    Employee employees[NUM_EMPLOYEES] = {
        {"Connie Cobol", "MA", "098401", 10.60, 51.0},
        {"Mary Apl", "NH", "526488", 9.75, 42.5},
        {"Frank Fortran", "VT", "765349", 10.50, 37.0},
        {"Jeff Ada", "NY", "034645", 12.25, 45.0},
        {"Anton Pascal", "CA", "127615", 8.35, 40.0}
    };
    
    calculatePayroll(employees);
    return 0;
}
