// Elaine Torrez                          CS1A                         Chapter 6, P.374, #17
// *****************************************************************************************
// *                                  PAINT JOB ESTIMATOR                                   *
// *--------------------------------------------------------------------------------------- *
// * This program estimates the cost of a paint job based on the number of rooms,           *
// * the square footage of wall space in each room, and the price per gallon of paint.      *
// * For every 115 square feet of wall space, 1 gallon of paint and 8 hours of labor are    *
// * required. Labor costs $18.00 per hour.                                                 *
// *--------------------------------------------------------------------------------------- *
// * INPUT                                                                                  *
// *   numRooms   : number of rooms to be painted (>= 1)                                    *
// *   paintPrice : price per gallon of paint (>= $10.00)                                   *
// *   wallSqFt   : wall space in each room (>= 0)                                          *
// *--------------------------------------------------------------------------------------- *
// * OUTPUT                                                                                 *
// *   gallonsNeeded : total gallons of paint required                                      *
// *   laborHours    : total hours of labor required                                        *
// *   paintCost     : cost of the paint                                                    *
// *   laborCost     : total labor charges                                                  *
// *   totalCost     : total cost of the paint job                                          *
// *****************************************************************************************
 
#include <iostream>
#include <iomanip>
#include <limits>
using namespace std;
 
// ---------------- Function Prototypes ----------------
double getPositiveDouble(string prompt, double minValue);
int getPositiveInt(string prompt, int minValue);
double calcGallons(double totalSqFt);
double calcLaborHours(double totalSqFt);
double calcPaintCost(double gallons, double paintPrice);
double calcLaborCost(double hours);
void displayResults(double gallons, double hours, double paintCost, double laborCost, double totalCost);
 
// ---------------------- MAIN -------------------------
int main()
{
    const double SQFT_PER_GALLON = 115.0;
    const double HOURS_PER_GALLON = 8.0;
    const double LABOR_RATE = 18.0;
 
    int numRooms;
    double paintPrice, wallSqFt, totalSqFt = 0;
    double gallons, hours, paintCost, laborCost, totalCost;
 
    cout << fixed << setprecision(2);
 
    // ---------------------- INPUT ----------------------
    numRooms = getPositiveInt("Enter the number of rooms to be painted: ", 1);
    paintPrice = getPositiveDouble("Enter the price of paint per gallon: $", 10.0);
 
    // Get total square footage from all rooms
    for (int i = 1; i <= numRooms; i++)
    {
        wallSqFt = getPositiveDouble("Enter the square feet of wall space for room #" + to_string(i) + ": ", 0);
        totalSqFt += wallSqFt;
    }
 
    // -------------------- PROCESSING -------------------
    gallons = calcGallons(totalSqFt);
    hours = calcLaborHours(totalSqFt);
    paintCost = calcPaintCost(gallons, paintPrice);
    laborCost = calcLaborCost(hours);
    totalCost = paintCost + laborCost;
 
    // ---------------------- OUTPUT ----------------------
    displayResults(gallons, hours, paintCost, laborCost, totalCost);
 
    return 0;
}
 
// ---------------- Function Definitions ----------------
 
// Get a validated positive integer
int getPositiveInt(string prompt, int minValue)
{
    int value;
    cout << prompt;
    cin >> value;
 
    while (cin.fail() || value < minValue)
    {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        cout << "ERROR: Value must be at least " << minValue << ". Re-enter: ";
        cin >> value;
    }
    return value;
}
 
// Get a validated positive double
double getPositiveDouble(string prompt, double minValue)
{
    double value;
    cout << prompt;
    cin >> value;
 
    while (cin.fail() || value < minValue)
    {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        cout << "ERROR: Value must be at least " << minValue << ". Re-enter: ";
        cin >> value;
    }
    return value;
}
 
// Calculate gallons of paint required
double calcGallons(double totalSqFt)
{
    const double SQFT_PER_GALLON = 115.0;
    return totalSqFt / SQFT_PER_GALLON;
}
 
// Calculate labor hours required
double calcLaborHours(double totalSqFt)
{
    const double HOURS_PER_GALLON = 8.0;
    const double SQFT_PER_GALLON = 115.0;
    return (totalSqFt / SQFT_PER_GALLON) * HOURS_PER_GALLON;
}
 
// Calculate cost of paint
double calcPaintCost(double gallons, double paintPrice)
{
    return gallons * paintPrice;
}
 
// Calculate cost of labor
double calcLaborCost(double hours)
{
    const double LABOR_RATE = 18.0;
    return hours * LABOR_RATE;
}
 
// Display results
void displayResults(double gallons, double hours, double paintCost, double laborCost, double totalCost)
{
    cout << "\n----- Paint Job Estimate -----" << endl;
    cout << "Gallons of paint required : " << gallons << endl;
    cout << "Hours of labor required    : " << hours << endl;
    cout << "Cost of paint              : $" << paintCost << endl;
    cout << "Labor charges              : $" << laborCost << endl;
    cout << "----------------------------------" << endl;
    cout << "Total cost of paint job    : $" << totalCost << endl;
}