#include <iostream>
#include <vector>
#include <cmath>
#include <cstdio>

using namespace std;

int TOTAL_INPUTS_CORRECT = 0;
int TOTAL_INVALID_INPUTS = 0;

struct student{ 
    //making a struct of type student to facilitate the manipulation of data during this program
    bool member_of_church;
    double credit_hours;
    double tuition;
};

void undergrad_or_not(student & s) { 
    //function determines if the student is doing an undergrad
    string input;
    cout << "Are you entering information about an undergraduate student (\"y\" or \"n\")? ";
    cin >> input;
    if(input == "y") {
        TOTAL_INPUTS_CORRECT++;
    }
    else {
        cout << "This program deals only with undergraduate students." << endl;
        TOTAL_INVALID_INPUTS++;
        undergrad_or_not(s);
    }
}

bool check_credit_hours(double input) {
    //checks the credit hours to make sure it is correct
    double decimal = input - floor(input);//eliminate everything before the decimal to be able to evaulate
    if(input > 25.0 or input < .5) {
        cout << input <<  " is too small or too large for valid credit hour entry"  << endl;
        return false;
    }
    if(decimal == .0 or decimal == .5) {
        return true;
    }
    else {
        cout << "A student cannot enroll for " << input << " credit hours" << endl;
        return false;
    }
}

void get_credit_hours(student & s) { 
    //function to get the number of credit hours.
    double input;                                    
    cout << "Credit hours winter 2012: ";
    cin >> input;
    if(check_credit_hours(input) == false) { 
        //using check_credit_hours function to determine if in range
        TOTAL_INVALID_INPUTS++;
        get_credit_hours(s);
    }
    else {
        s.credit_hours = input;
        TOTAL_INPUTS_CORRECT++;
    }
}

void get_member_of_church(student & s) {
    //function to determine if student is a member of the church
    string input;
    cout <<"Does the student belong to the LDS church (\"y\" or \"n\")? ";
    cin >> input;
    if(input == "n") {
        s.member_of_church = false;
    }
    TOTAL_INPUTS_CORRECT++;
}

void calculate_tuition(student & s) {
    //this determines the tuition based on credit hours
    if(s.credit_hours > 12) {
        if(s.member_of_church) {
            s.tuition = 2280;
        }
        else {
            s.tuition = 4560;
        }
    }
    else if(s.credit_hours > 9 && s.credit_hours < 11.5) {
        if(s.member_of_church) {
            s.tuition = 2210;
        }
        else {
            s.tuition = 4435;
        }
    }
    else {
        if(s.member_of_church) {
            s.tuition = 234 * s.credit_hours;
        }
        else {
            s.tuition = 468 * s.credit_hours;
        }
    }
    cout << "Tuition is $" << s.tuition << " for winter 2012" << endl;
}

void calculate_refund(student & s) {
    //used to calculate refund for student
    string input;
    cout << "Were there any classes that were dropped that need refund(\"y\" or \"n\")?";
    cin >> input;
    if(input == "y") {
        int time_frame;
        double credits_dropped;
        double refund;
        double new_tuition;
        double old_tuition;
        cout << "Which of the following dates best describes when you dropped the class(es)" << endl;
        cout << "1) January 19, 2012\n2) January 23, 2012\n3) Feruary 27, 2012\n4) March 16, 2012" << endl;
        cin >> time_frame;
        cout << "How many credit hours were dropped?" << endl;
        cin >> credits_dropped;
        if(check_credit_hours(credits_dropped) == false or s.credit_hours-credits_dropped <= 0) {
            cout << "this is an invalid credit hours, try again" << endl;
            calculate_refund(s);
            TOTAL_INVALID_INPUTS++;
        }
        else {
            s.credit_hours = s.credit_hours - credits_dropped;
            old_tuition = s.tuition;
            calculate_tuition(s);
            new_tuition = s.tuition;
            if(time_frame == 1) {
                refund = (old_tuition - new_tuition) *.85;
            }
            if(time_frame == 2) {
                refund = (old_tuition - new_tuition) *.75;
            }
            if(time_frame == 3) {
                refund = (old_tuition - new_tuition) *.50;
            }
            if(time_frame == 4) {
                cout << "You wont get any money back.  You dropped classes too late." << endl; 
            }
            cout << refund << " is the amount you will be refunded" << endl;
            s.tuition = s.tuition - refund;
            printf ("This is the new tuition after refund %4.2f\n",s.tuition);
            TOTAL_INPUTS_CORRECT++;
        }
    }
}

void get_max_tuition(vector<student> & students) { 
    //function to get the max tuition
    double max_tuition = 0;
    for(unsigned int i = 0; i < students.size();i++) {
        if(max_tuition < students[i].tuition) {
            max_tuition = students[i].tuition;
        }
    }
    printf ("The highest tuition is $%4.2f\n" , max_tuition);
}

void get_min_tuition(vector<student> & students) { 
    //function to get min tuition
    double min_tuition = 4560;                            //need to initilize the double to avoid error
    for(unsigned int i = 0; i < students.size(); i++) {   //made it the largest number it could be so this function
        if(min_tuition > students[i].tuition) {           //wont fail
            min_tuition = students[i].tuition;
        }
    }
    printf ("The lowest tuition is $%4.2f\n" , min_tuition);
}

void get_average_tuition(vector<student> & students) { 
    //function to get the average tuition for all students
    double average = 0;
    for(unsigned int i = 0; i < students.size(); i++) {
        average += students[i].tuition;
    }
    average = average/students.size();
    printf ("The average tuition is $%4.2f\n" , average);
}

void get_average_credit_hours(vector<student> & students) {
    //function to get the average credit hours for all students
    double average = 0;
    for(unsigned int i = 0; i < students.size(); i++) {
        average += students[i].credit_hours;
    }
    average = average/students.size();
    printf ("This is the average credit hours %4.1f\n" , average);
}

void number_of_students(vector<student> & students) {
    //function to report how many students were recorded
    cout << "You entered valid information for " << students.size() << " students" << endl;
}

void percentage_of_correct_entries() {
    //function reports percentage of correct entries
    int percentage;
    int total = TOTAL_INPUTS_CORRECT + TOTAL_INVALID_INPUTS;
    percentage = TOTAL_INPUTS_CORRECT*100/total;
    cout <<  percentage << "%" << " of your entries required no reprompting" << endl;
}

bool keep_playing() {
    bool r = true;
    string input;
    cout << "Enter another student (\"y\" or \"n\")?";
    cin >> input;
    if(input == "n") {
        r = false;
    }
    return r;
}

int main() {
    bool keep_game = true;
    vector<student> students;
    //Keep the game going until person wants to quit
    while(keep_game) {
        student cur_student = {true, 0, 0};
        undergrad_or_not(cur_student);          
        get_member_of_church(cur_student);
        get_credit_hours(cur_student);
        calculate_tuition(cur_student);
        calculate_refund(cur_student);
        students.push_back(cur_student);
        keep_game = keep_playing();
    }
    number_of_students(students);
    get_average_credit_hours(students);
    get_average_tuition(students);
    get_max_tuition(students);
    get_min_tuition(students);
    percentage_of_correct_entries();
}
