// SECJ1013-PT1-Assignment 2 (20202021-1)
// Group Members:
// 1. Ahmad Nazran bin Yusri
// 2. Megat Irfan Zackry bin Ismail
// 3. Muhammad Syazwan bin Sahdan

#include <iostream>
#include <iomanip>
using namespace std;

#define SIZE 5 // Max size of the array

int count = 0; // global variable to count student's 
               // mark info added into the array

// Function prototypes. The formatName, pressEnter, getGrade and 
// getTask were already implemented. Only need to complete the rest 
// after getTask.
void formatName(string &);
void pressEnter();
char getGrade(int);
int getTask();
void addMarkInfo(string [], int [][2]);
void listMarkInfo(string n[SIZE], int m[][2]);
void viewResults(string n[SIZE], int m[][2], int s);
void viewReports(string n[SIZE], int m[][2]);

// Start main function
int main() {
    // The next 2 array variables are to be used as parallel array
    string names[SIZE]; // 1 dimensional array to store student's names
    int marks[SIZE][2]; // 2 dimensional array to store coursework and final exam marks
    
    int task = getTask();
    while (task != 5 ) {
        switch (task) {
            case 1: addMarkInfo(names, marks); break;
            case 2: listMarkInfo(names, marks); break;
            case 3: viewResults(names, marks, count); break;
            case 4: viewReports(names, marks);
        }
        
        task = getTask();
    }
    
    return 0;   
}

// start user-defined functions implementations
// function to format student's name so it has at least 25 
// characters including the trailing space bar characters
void formatName(string &n) {
    int strlen = n.length();
    if (strlen < 25) {
        for (int i = 0; i < (25 - strlen); i++)
            n = n + " ";
    }
}

// use this function instead of system("PAUSE") to make 
// this program compatibale for both Windows & Linux OS
void pressEnter() {
    char temp = 'x';
    cout << "\nPress ENTER to continue...";
    cin.ignore();
    while (temp != '\n') cin.get(temp);
}

// only 5 levels of grades (A, B, C, D & E)
char getGrade(int m) {
    if (m >= 85) return 'A';
    if (m >= 70) return 'B';
    if (m >= 55) return 'C';
    if (m >= 40) return 'D';
    
    return 'E';
}

// only allow users to choose the option from 1 to 5               
int getTask() {
    int t = 0;
    
    cout << "\n";
    cout << "1. Add data\n";
    cout << "2. List data\n";
    cout << "3. View results\n";
    cout << "4. View reports\n";
    cout << "5. Quit program\n\n";
    
    while (t < 1 || t > 5) {
        cout << "Enter your choice [1 - 5]: ";
        cin >> t;
    }
    
    cout << " \n";
    
    return t;

}

// need to complete the implementation of this function
// refer the instruction slides for details
void addMarkInfo(string n[SIZE], int m[][2]) {
	cout << "Enter student name: ";
	cin >> n[count];
	cout << endl;
	do {
		cout << "Coursework (0-70): ";
		cin >> m[count][0];
	} while (m[count][0] < 0 || m[count][0] > 70);
	cout << endl;
	do {
		cout << "Final Exam (0-30): ";
		cin >> m[count][1];
	} while (m[count][1] < 0 || m[count][1] > 30);
	cout << endl;
	
	count++;
}


// need to complete the implementation of this function
// refer the instruction slides for details
void listMarkInfo(string n[SIZE], int m[][2]) {
    cout << "No. Name                      Coursework  Final Exam\n";
    cout << "--- ------------------------- ----------  ----------\n";
    for (int i = 0; i< count; i++){
    	formatName(n[i]);
    	cout << i+1 << ".  " << n[i] << setw(3)<< m[i][0] << setw(12) << m[i][1] << endl;
	}
	pressEnter();
}


// need to complete the implementation of this function
// refer the instruction slides for details
void viewResults(string n[SIZE], int m[][2], int s) {
    cout << "No. Name                      Total Marks  Grade\n";
    cout << "--- ------------------------- -----------  -----\n";
	char grade [s];
    for (int i = 0; i< count; i++){
    	formatName(n[i]);
    	int total = m[i][0] + m[i][1];
    	grade[i]=getGrade(total);
    	cout << i+1 << ".  " << n[i] << setw(3) << total << setw(12) << grade[i] << endl;
	}
	pressEnter();
}

// need to complete the implementation of this function
// refer the instruction slides for details
void viewReports(string n[SIZE], int m[][2]) {
    int total_all = 0, total[count], highest = 0, lowest = 100, t = 1;
    float avg = 0;
    
    for (int i = 0; i < count; i++){
    	total[i] = m[i][0] + m[i][1];
    	if (total[i] > highest)
    		highest = total[i];
    	if (total[i] < lowest)
    		lowest = total[i];
    		
    	total_all += total[i];
	}
	avg = total_all / count;
	
    cout << "Student's total marks report:\n\n";
    cout << "Highest: " << highest << "\n";
    cout << "Lowest: " << lowest << "\n";
    cout << "Average: " << avg << "\n\n";
        
    cout << "List of students (below average):\n";
    cout << "No. Name                      Total Marks  Grade\n";
    cout << "--- ------------------------- -----------  -----\n";
    char grade [count];
    for (int i = 0; i< count; i++){
    	total[i] = m[i][0] + m[i][1];
    	if (total[i]<avg){
			char grade [count];
    		formatName(n[i]);
    		grade[i] = getGrade(total[i]);
    		cout << t++ << ".  " << n[i] << setw(3) << total[i] << setw(12) << grade[i] << endl;
	}
}
    pressEnter();
}
