//********************************************************
//
// Assignment 5 - Functions
//
// Name: Matt Smith
//
// Class: C Programming, Spring 2025
//
// Date: 2/27/2025
//
// Description: Program which determines overtime and 
// gross pay for a set of employees with outputs sent 
// to standard output (the screen).
//
// All functions called by reference
//
//******************************************************** 

#include <stdio.h>

// constants
#define SIZE 5
#define OVERTIME_RATE 1.5f
#define STD_WORK_WEEK 40.0f

// function prototypes
void getHours(long int clockNumber[], float hours[], int theSize);
void printHeader(void);
void printEmp(long int clockNumber[], float wageRate[], float hours[], float overtimeHrs[], float grossPay[], int theSize);

// TODO: Add other function prototypes here as needed
void calcOT(float hours[], int theSize, float overtimeHrs[]);
void calcGross(float wageRate[], float hours[], float overtimeHrs[], float grossPay[], int theSize);

int main() {
    // Variable Declarations

    long int clockNumber[SIZE] = {98401, 526488, 765349, 34645, 127615}; // ID
    float grossPay[SIZE];     // gross pay
    float hours[SIZE];        // hours worked in a given week
    float overtimeHrs[SIZE];  // overtime hours
    float wageRate[SIZE] = {10.60, 9.75, 10.50, 12.25, 8.35}; // hourly wage rate

    // Read in the hours worked for each employee
    getHours(clockNumber, hours, SIZE);

    // TODO: Function call to calculate overtime hours
    for (int i = 0; i < SIZE; i++) {
        overtimeHrs[i] = 0.0f;
    }
    calcOT(hours, SIZE, overtimeHrs);

    // TODO: Function call to calculate gross pay
    for (int i = 0; i < SIZE; i++) {
        grossPay[i] = 0.0f;
    }
    calcGross(wageRate, hours, overtimeHrs, grossPay, SIZE);

    // Print the initial table header
    printHeader();

    // Function call to output results to the screen
    printEmp(clockNumber, wageRate, hours, overtimeHrs, grossPay, SIZE);

    return (0);
}

//***************************************************************
//  Function: getHours  
// 
//  Purpose: Obtains input from user, the number of hours worked 
//  per employee and stores the results in an array that is 
//  passed back to the calling function by reference. 
// 
//  Parameters: 
//
//      clockNumber - Array of employee clock numbers for each employee
//      hours - Array of hours worked by each employee
//      theSize - Number of employees to process
// 
//  Returns: Nothing (call by reference)
//  
//**************************************************************

void getHours(long int clockNumber[], float hours[], int theSize) {
    int i; // loop and array index

    // Read in hours for each employee
    for (i = 0; i < theSize; ++i) {
        printf("\nEnter hours worked by emp # %06li: ", clockNumber[i]);
        scanf("%f", &hours[i]);
    }
}

//**************************************************************
// Function: printHeader
// 
// Purpose: Prints the initial table header information.
// 
// Parameters: none
// 
// Returns: void
//  
//**************************************************************

void printHeader(void) {
    printf("\n\n*** Pay Calculator ***\n");

    // print the table header
    printf("\n");
    printf("| Clock# | Wage | Hours | OT | Gross |\n");
    printf("------------------------------------------------\n");
}

//**************************************************************
// Function: printEmp 
// 
// Purpose: Prints out all the employee information in a
// nice and orderly table format.
// 
// Parameters: 
//
//     clockNumber - Array of employee clock numbers
//     wageRate - Array of employee wages per hour
//     hours - Array of number of hours worked by an employee
//     overtimeHrs - Array of overtime hours for each employee
//     grossPay - Array of gross pay calculations for each employee
//     theSize - Number of employees to process 
// 
// Returns: Nothing (call by reference)
//  
//**************************************************************

void printEmp(long int clockNumber[], float wageRate[], float hours[], float overtimeHrs[], float grossPay[], int theSize) {
    int i; // loop and array index

    // access and print each employee
    for (i = 0; i < theSize; ++i) {
        printf("| %06li | %5.2f | %5.1f | %5.1f | %8.2f |\n",
               clockNumber[i], wageRate[i], hours[i], overtimeHrs[i], grossPay[i]);
        printf("------------------------------------------------\n");
    }
}

// TODO: Add other functions here as needed

//**************************************************************
// Function: calcGross
//
// Purpose: Calculate gross hours worked
//
// Parameters:
//
//		wageRate - Array of employee wages per hour
//		hours - Array of hours worked by an employee 
//		overtimeHrs - Array of overtime hours for each employee
//		grossPay - Arry of gross pay calculations for each employee
//		theSize - Number of employees to process
//
// Returns: Nothing (call by reference)
//
//**************************************************************

void calcGross(float wageRate[], float hours[], float overtimeHrs[], float grossPay[], int theSize) {
    for (int i = 0; i < theSize; i++) {
        if (hours[i] > STD_WORK_WEEK) {
            float regularPay = wageRate[i] * STD_WORK_WEEK;
            float overtimePay = (OVERTIME_RATE * wageRate[i]) * (hours[i] - STD_WORK_WEEK);
            grossPay[i] = regularPay + overtimePay;
        } else {
            grossPay[i] = wageRate[i] * hours[i];
        }
    }
}

//**************************************************************
// Function: calcOT
//
// Purpose: Calculate overtime hours worked
//
// Parameters:
//
//		wageRate - Array of employee wages per hour
//		hours - Array of hours worked by an employee 
//		
//		
//		theSize - Number of employees to process
//
// Returns: Nothing (call by reference)
//
//**************************************************************	

void calcOT(float hours[], int theSize, float overtimeHrs[]) {
    for (int i = 0; i < theSize; i++) {
        if (hours[i] > STD_WORK_WEEK) {
            overtimeHrs[i] = hours[i] - STD_WORK_WEEK;
        } else {
            overtimeHrs[i] = 0.0f;
        }
    }
}