// Elaine Torrez                          CS1A                         Chapter 6, P.373, #4
// *****************************************************************************************
// *                                 OVERLOADED HOSPITAL                                    *
// *--------------------------------------------------------------------------------------- *
// * This program computes and displays the total hospital charges for a patient based on   *
// * whether they were admitted as an in-patient or an out-patient.                         *
// * The program uses two overloaded functions to calculate the total charges:               *
// *   1) For in-patients: accepts number of days, daily rate, medication, and service fees. *
// *   2) For out-patients: accepts medication and service fees only.                        *
// *--------------------------------------------------------------------------------------- *
// * INPUT                                                                                  *
// *   patientType : 'I' or 'O' to indicate in-patient or out-patient                        *
// *   days        : number of days spent in hospital (for in-patient only, >= 0)            *
// *   dailyRate   : rate per day (for in-patient only, >= 0)                                *
// *   medCharges  : medication charges (>= 0)                                               *
// *   servCharges : service/lab test charges (>= 0)                                         *
// *--------------------------------------------------------------------------------------- *
// * OUTPUT                                                                                 *
// *   totalCharges : total cost of hospital stay                                            *
// *****************************************************************************************
 
#include <iostream>
#include <iomanip>
#include <limits>    // for input validation
#include <cctype>    // for toupper
using namespace std;
 
// ---------------- Function Prototypes ----------------
double calcCharges(int days, double dailyRate, double medCharges, double servCharges); // In-patient
double calcCharges(double medCharges, double servCharges);                            // Out-patient
 
// ---------------------- MAIN -------------------------
int main()
{
    char patientType;
    int days;
    double dailyRate, medCharges, servCharges, totalCharges;
 
    cout << fixed << setprecision(2);
 
    // ---------------------- INPUT ----------------------
    cout << "Was the patient admitted as an in-patient or out-patient? (I/O): ";
    cin >> patientType;
    patientType = toupper(patientType);
 
    while (patientType != 'I' && patientType != 'O')
    {
        cout << "ERROR: Please enter 'I' for in-patient or 'O' for out-patient: ";
        cin >> patientType;
        patientType = toupper(patientType);
    }
 
    if (patientType == 'I')
    {
        cout << "Enter number of days spent in the hospital: ";
        cin >> days;
        while (cin.fail() || days < 0)
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "ERROR: Days cannot be negative. Re-enter: ";
            cin >> days;
        }
 
        cout << "Enter daily rate: $";
        cin >> dailyRate;
        while (cin.fail() || dailyRate < 0)
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "ERROR: Daily rate cannot be negative. Re-enter: $";
            cin >> dailyRate;
        }
 
        cout << "Enter hospital medication charges: $";
        cin >> medCharges;
        while (cin.fail() || medCharges < 0)
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "ERROR: Medication charges cannot be negative. Re-enter: $";
            cin >> medCharges;
        }
 
        cout << "Enter charges for hospital services (lab tests, etc.): $";
        cin >> servCharges;
        while (cin.fail() || servCharges < 0)
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "ERROR: Service charges cannot be negative. Re-enter: $";
            cin >> servCharges;
        }
 
        // -------------------- PROCESS --------------------
        totalCharges = calcCharges(days, dailyRate, medCharges, servCharges);
    }
    else
    {
        cout << "Enter charges for hospital services (lab tests, etc.): $";
        cin >> servCharges;
        while (cin.fail() || servCharges < 0)
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "ERROR: Service charges cannot be negative. Re-enter: $";
            cin >> servCharges;
        }
 
        cout << "Enter hospital medication charges: $";
        cin >> medCharges;
        while (cin.fail() || medCharges < 0)
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "ERROR: Medication charges cannot be negative. Re-enter: $";
            cin >> medCharges;
        }
 
        // -------------------- PROCESS --------------------
        totalCharges = calcCharges(medCharges, servCharges);
    }
 
    // ---------------------- OUTPUT ----------------------
    cout << "\nTotal hospital charges: $" << totalCharges << endl;
 
    return 0;
}
 
// ---------------- Function Definitions ----------------
 
// For in-patients
double calcCharges(int days, double dailyRate, double medCharges, double servCharges)
{
    return (days * dailyRate) + medCharges + servCharges;
}
 
// For out-patients
double calcCharges(double medCharges, double servCharges)
{
    return medCharges + servCharges;
}