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

#define SIZE 5
#define STD_HOURS 40.0
#define OT_RATE 1.5
#define FED_TAX_RATE 0.25

struct name {
    char firstName[10];
    char lastName[10];
};

struct employee {
    struct name empName;
    char taxState[3];
    long int clockNumber;
    float wageRate, hours, overtimeHrs;
    float grossPay, stateTax, fedTax, netPay;
};

struct totals {
    float wage, hours, overtime, gross, stateTax, fedTax, net;
};

struct min_max {
    float min[7], max[7];
};

void getHours(struct employee data[], int size);
void calculatePay(struct employee data[], int size);
void printEmp(struct employee data[], int size);
void printStatistics(struct employee data[], int size);

int main(void)
{
    struct employee data[SIZE] = {
        {{"Connie", "Cobol"}, "MA", 98401, 10.60},
        {{"Mary", "Apl"}, "NH", 526488, 9.75},
        {{"Frank", "Fortran"}, "VT", 765349, 10.50},
        {{"Jeff", "Ada"}, "NY", 34645, 12.25},
        {{"Anton", "Pascal"}, "CA", 127615, 8.35}
    };

    getHours(data, SIZE);
    calculatePay(data, SIZE);
    printEmp(data, SIZE);
    printStatistics(data, SIZE);

    return 0;
}

void getHours(struct employee data[], int size)
{
    for (int i = 0; i < size; i++) {
        printf("Enter hours for employee %06li: ",
               data[i].clockNumber);
        scanf("%f", &data[i].hours);
    }
}

void calculatePay(struct employee data[], int size)
{
    for (int i = 0; i < size; i++) {
        float rate = 0.08;

        data[i].overtimeHrs =
            data[i].hours > STD_HOURS
            ? data[i].hours - STD_HOURS : 0;

        data[i].grossPay =
            (data[i].hours - data[i].overtimeHrs) *
            data[i].wageRate +
            data[i].overtimeHrs * data[i].wageRate * OT_RATE;

        if (strcmp(data[i].taxState, "MA") == 0)
            rate = 0.05;
        else if (strcmp(data[i].taxState, "NH") == 0)
            rate = 0.00;
        else if (strcmp(data[i].taxState, "VT") == 0)
            rate = 0.06;
        else if (strcmp(data[i].taxState, "CA") == 0)
            rate = 0.07;

        data[i].stateTax = data[i].grossPay * rate;
        data[i].fedTax = data[i].grossPay * FED_TAX_RATE;
        data[i].netPay = data[i].grossPay -
                         data[i].stateTax - data[i].fedTax;
    }
}

void printEmp(struct employee data[], int size)
{
    printf("\n%-20s %-5s %8s %7s %6s %6s %8s %8s %8s %8s\n",
           "Name", "State", "Clock#", "Wage",
           "Hours", "OT", "Gross", "StateTax",
           "FedTax", "NetPay");

    for (int i = 0; i < size; i++) {
        char name[21];

        snprintf(name, sizeof(name), "%s %s",
                 data[i].empName.firstName,
                 data[i].empName.lastName);

        printf("%-20s %-5s %08li %7.2f %6.1f %6.1f "
               "%8.2f %8.2f %8.2f %8.2f\n",
               name, data[i].taxState, data[i].clockNumber,
               data[i].wageRate, data[i].hours,
               data[i].overtimeHrs, data[i].grossPay,
               data[i].stateTax, data[i].fedTax,
               data[i].netPay);
    }
}

void printStatistics(struct employee data[], int size)
{
    float total[7] = {0};
    float min[7], max[7];

    for (int i = 0; i < size; i++) {
        float values[7] = {
            data[i].wageRate, data[i].hours,
            data[i].overtimeHrs, data[i].grossPay,
            data[i].stateTax, data[i].fedTax,
            data[i].netPay
        };

        for (int j = 0; j < 7; j++) {
            total[j] += values[j];

            if (i == 0 || values[j] < min[j])
                min[j] = values[j];

            if (i == 0 || values[j] > max[j])
                max[j] = values[j];
        }
    }

    printf("\n\nStatistics (Wage Hours OT Gross StateTax FedTax NetPay)\n");

    printf("Totals:   ");
    for (int j = 0; j < 7; j++)
        printf("%8.2f ", total[j]);

    printf("\nAverages: ");
    for (int j = 0; j < 7; j++)
        printf("%8.2f ", total[j] / size);

    printf("\nMinimum:  ");
    for (int j = 0; j < 7; j++)
        printf("%8.2f ", min[j]);

    printf("\nMaximum:  ");
    for (int j = 0; j < 7; j++)
        printf("%8.2f ", max[j]);

    printf("\n");
}