/*
This program reads in student grades and names from files, and then
calculates the students averages and letter grades, and ouputs
the letter grades to the console and a file.
This program is my original work.
*/

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <conio.h>
using namespace std;

const int NUM_STUDENTS = 4;		// Sets number of stduents
const int NUM_GRADES = 4;		// Sets number of scores

// Declare a gradesArrayType to be an alias for an array of grades
typedef double gradesArrayType[NUM_STUDENTS][NUM_GRADES];

// Declare a letterGradesArrayType to ben an alias for an array of letter grades
typedef string letterGradesArrayType[NUM_STUDENTS][2];

// Function prototypes
void readNames(string[], int);
void readGrades(gradesArrayType, int);
void calculateAverages(gradesArrayType, int);
string calculateLetterGrade(double);
void outputLetterGrades(letterGradesArrayType, int);

int main()
{
	string names[NUM_STUDENTS];			// Holds each student's name
	gradesArrayType grades;				// Holds each student's grades
	letterGradesArrayType letterGrades;	// Holds each student's letter grades

	// Call the readNames function.
	readNames(names, NUM_STUDENTS);

	// Call the readGrades function.
	readGrades(grades, NUM_STUDENTS);

	// Call the calculateAverages function.
	calculateAverages(grades, NUM_STUDENTS);

	// Populate the letterGrades array using the calculateLetterGrade function.
	for (int row = 0; row < NUM_STUDENTS; row++) {
		letterGrades[row][0] = names[row];
		letterGrades[row][1] = calculateLetterGrade(grades[row][NUM_GRADES - 1]);
	}

	// Call the outputLetterGrades function.
	outputLetterGrades(letterGrades, NUM_STUDENTS);
	cout << "\n\nPress <Enter> to exit";
	_getch();
	return 0;
}

/********************************************************************************
*								   readNames									*
* This function reads names from a file and stores them in an array.            *
*********************************************************************************/

void readNames(string names[], int NUM_STUDENTS) {
	int count = 0;					// Loop control variable that counts
									// how many data items have bee read in
	ifstream inputFile;				// Input file stream object

	// Open the data file.
	inputFile.open("StudentNames.txt");

	if (!inputFile)
		cout << "Error opening data file\n";
	else {
		// Read the names from the file into the array.  When we exit
		// the loop, count will hold the number of items read in.
		while (count < NUM_STUDENTS && inputFile >> names[count])
			count++;

		// Close the file.
		inputFile.close();
	}
}

/********************************************************************************
*								  readGrades									*
* This function reads grades from a file and stores them in an array.           *
*********************************************************************************/

void readGrades(gradesArrayType grades, int NUM_STUDENTS) {
	int student, grade;				// Loop counters
	ifstream inputFile;				// Input file stream object

	// Open the data file.
	inputFile.open("Grades.txt");

	if (!inputFile)
		cout << "Error opening data file\n";
	else {
		// Nested loops are used to fill the array with grades
		// for each student
		for (student = 0; student < NUM_STUDENTS; student++) {
			for (grade = 0; grade < (NUM_GRADES - 1); grade++) {
				inputFile >> grades[student][grade];
			}
		}
		inputFile.close();
	}
}

/********************************************************************************
*							   calculateAverages							    *
* This function calculates the averages and stores them in the 4th column       *
* of a 4 column array of grades.												*
*********************************************************************************/

void calculateAverages(gradesArrayType grades, int NUM_STUDENTS) {
	double total;			// Accumulator
	double average;			// Holds a given student's average

	// Sum each student's grades so his or her average
	// can be calculated and stored in the 4th column
	for (int student = 0; student < NUM_STUDENTS; student++) {
		// Reset accumulator to 0 for this student
		total = 0;

		// Sum a row
		for (int grade = 0; grade < (NUM_GRADES - 1); grade++) {
			total += grades[student][grade];
		}

		// Compute and store the average for this student
		average = total / (NUM_GRADES - 1);
		grades[student][NUM_GRADES - 1] = average;
	}
}

/********************************************************************************
*							 calculateLetterGrades  	             		    *
* This function calculates the letter grade from a student's average.           *
*********************************************************************************/

string calculateLetterGrade(double average) {
	string letterGrade;
	if (average >= 90)
		letterGrade = "A";
	else if (average >= 80)
		letterGrade = "B";
	else if (average >= 70)
		letterGrade = "C";
	else if (average >= 60)
		letterGrade = "D";
	else
		letterGrade = "F";
	return letterGrade;
}

/********************************************************************************
*							 outputLetterGrades     	             		    *
* This function ouputs student's letter grades to a file and to the console.    *
*********************************************************************************/

void outputLetterGrades(letterGradesArrayType letterGrades, int NUM_STUDENTS) {
	ofstream outputFile;	// Output file stream object

	// Open the data file.
	outputFile.open("LetterGrades.txt");

	// Output the contents of the letterGrades array to the console and file.
	for (int row = 0; row < NUM_STUDENTS; row++)
	{
		for (int col = 0; col < 2; col++)
		{
			cout << setw(10) << left << letterGrades[row][col] << " ";
			outputFile << setw(10) << left << letterGrades[row][col] << " ";
		}
		cout << endl;
		outputFile << endl;
	}

	// Close the file
	outputFile.close();
}