// Owen Sullivan, Lucia Wang, Geeth Chilukuri
// CPSC 1021-001
// Lab 5

// main.cpp worked on by Owen Sullivan, Lucia Wang

// Clemson University Parking and Transportation Services permit price calculator

// Include statements
#include <iostream>
#include <cctype>

// Include custom header files
#include "CustomerType_Employee.h"
#include "CustomerType_Student.h"
#include "CustomerType_Vendor.h"
#include "VehicleType_Car.h"
#include "VehicleType_Truck.h"
#include "VehicleType_Motorcycle.h"
#include "Invoice.h"

// Declare std namespace
using namespace std;

int main() { // Start main function

    Invoice invoice; // Declare Invoice object instance

    // Print program information
    cout << "Clemson University Parking and Transportation Services permit price calculator." << endl;
    cout << "Created by: Owen Sullivan, CPSC 1021-001." << endl;
    
    cout << endl; // Print new line for spacing

    // Prompt user and accept input for type of permit
    char permitType;
    cout << "Do you want to purchase an annual permit, semester permit, one-day permit, or park-and-ride permit?" << endl;
    cout << "Enter your response (Valid options: \"A\", \"S\", \"O\", \"P\"): ";
    cin >> permitType;
    while (toupper(permitType) != 'A' && toupper(permitType) != 'S' && toupper(permitType) != 'O' && toupper(permitType) != 'P') { // Validate input
        cout << "Value " << permitType << " is not a valid response. Please try again: ";
        cin >> permitType;
    }
    permitType = toupper(permitType); // Convert to uppercase

    cout << endl; // Print new line for spacing

    // Prompt user and accept input for type of customer
    char customerType;
    cout << "Are you an employee, a student, or a vendor?" << endl;
    cout << "Enter your response (Valid options: \"E\", \"S\", \"V\"): ";
    cin >> customerType;
    while (toupper(customerType) != 'E' && toupper(customerType) != 'S' && toupper(customerType) != 'V') { // Validate input
        cout << "Value " << customerType << " is not a valid response. Please try again: ";
        cin >> customerType;
    }
    customerType = toupper(customerType); // Convert to uppercase

    cout << endl; // Print new line for spacing

    // Prompt user and accept input for customer information
    string name;
    string address;
    string email;
    cout << "Please enter your name: ";
    getline(cin >> ws, name);
    cout << "Please enter your permanent address: ";
    getline(cin >> ws, address);
    cout << "Please enter your email address: ";
    getline(cin >> ws, email);

    cout << endl; // Print new line for spacing

    // Determine course of action for prompting user for attributes specific to customer type
    bool isProfessor = false;
    bool isTenured = false;
    bool isResident = false;
    bool isTA = false;
    bool isFoodService = false;
    bool isConstruction = false;
    if (customerType == 'E') {
        // Prompt user and accept input for employee attributes
        char isProfessorInput;
        cout << "Are you a professor? (Valid options: \"Y\", \"N\"): ";
        cin >> isProfessorInput;
        while (toupper(isProfessorInput) != 'Y' && toupper(isProfessorInput) != 'N') { // Validate input
            cout << "Value " << isProfessorInput << " is not a valid response. Please try again: ";
            cin >> isProfessorInput;
        }
        isProfessorInput = toupper(isProfessorInput); // Convert to uppercase
        if (isProfessorInput == 'Y') { // Set global variable
            isProfessor = true;
        }

        char isTenuredInput;
        cout << "Are you tenured? (Valid options: \"Y\", \"N\"): ";
        cin >> isTenuredInput;
        while (toupper(isTenuredInput) != 'Y' && toupper(isTenuredInput) != 'N') { // Validate input
            cout << "Value " << isTenuredInput << " is not a valid response. Please try again: ";
            cin >> isTenuredInput;
        }
        isTenuredInput = toupper(isTenuredInput); // Convert to uppercase
        if (isTenuredInput == 'Y') { // Set global variable
            isTenured = true;
        }
    } else if (customerType == 'S') {
        // Prompt user and accept input for student attributes
        char isResidentInput;
        cout << "Are you a resident? (Valid options: \"Y\", \"N\"): ";
        cin >> isResidentInput;
        while (toupper(isResidentInput) != 'Y' && toupper(isResidentInput) != 'N') { // Validate input
            cout << "Value " << isResidentInput << " is not a valid response. Please try again: ";
            cin >> isResidentInput;
        }
        isResidentInput = toupper(isResidentInput); // Convert to uppercase
        if (isResidentInput == 'Y') { // Set global variable
            isResident = true;
        }

        char isTAinput;
        cout << "Are you a TA? (Valid options: \"Y\", \"N\"): ";
        cin >> isTAinput;
        while (toupper(isTAinput) != 'Y' && toupper(isTAinput) != 'N') { // Validate input
            cout << "Value " << isTAinput << " is not a valid response. Please try again: ";
            cin >> isTAinput;
        }
        isTAinput = toupper(isTAinput); // Convert to uppercase
        if (isTAinput == 'Y') { // Set global variable
            isTA = true;
        }
    } else if (customerType == 'V') {
        // Prompt user and accept input for vendor attributes
        char isFoodServiceInput;
        cout << "Are you with food service? (Valid options: \"Y\", \"N\"): ";
        cin >> isFoodServiceInput;
        while (toupper(isFoodServiceInput) != 'Y' && toupper(isFoodServiceInput) != 'N') { // Validate input
            cout << "Value " << isFoodServiceInput << " is not a valid response. Please try again: ";
            cin >> isFoodServiceInput;
        }
        isFoodServiceInput = toupper(isFoodServiceInput); // Convert to uppercase
        if (isFoodServiceInput == 'Y') { // Set global variable
            isFoodService = true;
        }

        char isConstructionInput;
        cout << "Are you with construction? (Valid options: \"Y\", \"N\"): ";
        cin >> isConstructionInput;
        while (toupper(isConstructionInput) != 'Y' && toupper(isConstructionInput) != 'N') { // Validate input
            cout << "Value " << isConstructionInput << " is not a valid response. Please try again: ";
            cin >> isConstructionInput;
        }
        isConstructionInput = toupper(isConstructionInput); // Convert to uppercase
        if (isConstructionInput == 'Y') { // Set global variable
            isConstruction = true;
        }
    }

    cout << endl; // Print new line for spacing

    char vehicleType;
    cout << "Do you drive a car, a truck, or a motorcycle?" << endl;
    cout << "Enter your response (Valid options: \"C\", \"T\", \"M\"): ";
    cin >> vehicleType;
    while (toupper(vehicleType) != 'C' && toupper(vehicleType) != 'T' && toupper(vehicleType) != 'M') { // Validate input
        cout << "Value " << vehicleType << " is not a valid response. Please try again: ";
        cin >> vehicleType;
    }
    vehicleType = toupper(vehicleType); // Convert to uppercase

    cout << endl; // Print new line for spacing

    // Prompt user and accept input for vehicle information
    string make;
    string model;
    int year;
    string license;
    cout << "Please enter your vehicle's make: ";
    getline(cin >> ws, make);
    cout << "Please enter your vehicle's model: ";
    getline(cin >> ws, model);
    cout << "Please enter your vehicle's year (1886-present): ";
    cin >> year;
    cout << "Please enter your vehicle's license plate: ";
    getline(cin >> ws, license);

    cout << endl; // Print new line for spacing

    // Determine course of action for prompting user for attributes specific to vehicle type
    bool isElectric = false;
    bool isCompact = false;
    bool isWide = false;
    bool isDiesel = false;
    bool isMoped = false;
    bool isTwoSeater = false;
    if (vehicleType == 'C') {
        // Prompt user and accept input for car attributes
        char isElectricInput;
        cout << "Do you have an electric car? (Valid options: \"Y\", \"N\"): ";
        cin >> isElectricInput;
        while (toupper(isElectricInput) != 'Y' && toupper(isElectricInput) != 'N') { // Validate input
            cout << "Value " << isElectricInput << " is not a valid response. Please try again: ";
            cin >> isElectricInput;
        }
        isElectricInput = toupper(isElectricInput); // Convert to uppercase
        if (isElectricInput == 'Y') { // Set global variable
            isElectric = true;
        }

        char isCompactInput;
        cout << "Do you have a compact car? (Valid options: \"Y\", \"N\"): ";
        cin >> isCompactInput;
        while (toupper(isCompactInput) != 'Y' && toupper(isCompactInput) != 'N') { // Validate input
            cout << "Value " << isCompactInput << " is not a valid response. Please try again: ";
            cin >> isCompactInput;
        }
        isCompactInput = toupper(isCompactInput); // Convert to uppercase
        if (isCompactInput == 'Y') { // Set global variable
            isCompact = true;
        }
    } else if (vehicleType == 'T') {
        // Prompt user and accept input for truck attributes
        char isWideInput;
        cout << "Is your truck extra wide? (Valid options: \"Y\", \"N\"): ";
        cin >> isWideInput;
        while (toupper(isWideInput) != 'Y' && toupper(isWideInput) != 'N') { // Validate input
            cout << "Value " << isWideInput << " is not a valid response. Please try again: ";
            cin >> isWideInput;
        }
        isWideInput = toupper(isWideInput); // Convert to uppercase
        if (isWideInput == 'Y') { // Set global variable
            isWide = true;
        }

        char isDieselInput;
        cout << "Does your truck run diesel? (Valid options: \"Y\", \"N\"): ";
        cin >> isDieselInput;
        while (toupper(isDieselInput) != 'Y' && toupper(isDieselInput) != 'N') { // Validate input
            cout << "Value " << isDieselInput << " is not a valid response. Please try again: ";
            cin >> isDieselInput;
        }
        isDieselInput = toupper(isDieselInput); // Convert to uppercase
        if (isDieselInput == 'Y') { // Set global variable
            isDiesel = true;
        }
    } else if (vehicleType == 'M') {
        // Prompt user and accept input for motorcycle attributes
        char isMopedInput;
        cout << "Is your motorcycle a moped? (Valid options: \"Y\", \"N\"): ";
        cin >> isMopedInput;
        while (toupper(isMopedInput) != 'Y' && toupper(isMopedInput) != 'N') { // Validate input
            cout << "Value " << isMopedInput << " is not a valid response. Please try again: ";
            cin >> isMopedInput;
        }
        isMopedInput = toupper(isMopedInput); // Convert to uppercase
        if (isMopedInput == 'Y') { // Set global variable
            isMoped = true;
        }

        char isTwoSeaterInput;
        cout << "Is your motorcycle a two-seater? (Valid options: \"Y\", \"N\"): ";
        cin >> isTwoSeaterInput;
        while (toupper(isTwoSeaterInput) != 'Y' && toupper(isTwoSeaterInput) != 'N') { // Validate input
            cout << "Value " << isTwoSeaterInput << " is not a valid response. Please try again: ";
            cin >> isTwoSeaterInput;
        }
        isTwoSeaterInput = toupper(isTwoSeaterInput); // Convert to uppercase
        if (isTwoSeaterInput == 'Y') { // Set global variable
            isTwoSeater = true;
        }
    }

    cout << endl; // Print new line for spacing

    // Create object instances depending on customer type and vehicle type, then calculate total and print invoice
    if (customerType == 'E') { // If employee
        CustomerType_Employee employee(name, address, email, isProfessor, isTenured);
        if (vehicleType == 'C') { // If car
            VehicleType_Car car(make, model, year, license, isElectric, isCompact);
            invoice.printInvoice(permitType, employee, car);
        } else if (vehicleType == 'T') { // If truck
            VehicleType_Truck truck(make, model, year, license, isWide, isDiesel);
            invoice.printInvoice(permitType, employee, truck);
        } else if (vehicleType == 'M') { // If motorcycle
            VehicleType_Motorcycle motorcycle(make, model, year, license, isMoped, isTwoSeater);
            invoice.printInvoice(permitType, employee, motorcycle);
        }
    } else if (customerType == 'S') { // If student
        CustomerType_Student student(name, address, email, isResident, isTA);
        if (vehicleType == 'C') { // If car
            VehicleType_Car car(make, model, year, license, isElectric, isCompact);
            invoice.printInvoice(permitType, student, car);
        } else if (vehicleType == 'T') { // If truck
            VehicleType_Truck truck(make, model, year, license, isWide, isDiesel);
            invoice.printInvoice(permitType, student, truck);
        } else if (vehicleType == 'M') { // If motorcycle
            VehicleType_Motorcycle motorcycle(make, model, year, license, isMoped, isTwoSeater);
            invoice.printInvoice(permitType, student, motorcycle);
        }
    } else if (customerType == 'V') { // If vendor
        CustomerType_Vendor vendor(name, address, email, isFoodService, isConstruction);
        if (vehicleType == 'C') { // If car
            VehicleType_Car car(make, model, year, license, isElectric, isCompact);
            invoice.printInvoice(permitType, vendor, car);
        } else if (vehicleType == 'T') { // If truck
            VehicleType_Truck truck(make, model, year, license, isWide, isDiesel);
            invoice.printInvoice(permitType, vendor, truck);
        } else if (vehicleType == 'M') { // If motorcycle
            VehicleType_Motorcycle motorcycle(make, model, year, license, isMoped, isTwoSeater);
            invoice.printInvoice(permitType, vendor, motorcycle);
        }
    }

    return 0;

}