/*
File name: funcs.cpp
Author: Bo Bayles
E-mail address: bmb3h6@umr.edu  
Description: This is an implementation file containing the function
  definitions for the DisplayMenu, AddCourse, ModCourse, DispCourse,
  CalcHours, and CalcGpa functions.
*/

#include "hw6.h"
#include <string>
#include <iostream>
using namespace std;
//Include the necessary headers.

char DisplayMenu(int const iClasses, const int iHours, const float fGpa,
                 const string letterGrade)
{
  char cMenu;

  cout << endl << "Number of courses: " << iClasses
       << "\t" << "Hours: " << iHours
       << "\t" << "Grade: " << letterGrade
       << "\t" << "GPA: " << fGpa << endl;

  cout << "\t \t MENU" << endl
       << "\t 1) Add Course" << endl
       << "\t 2) Display Courses" << endl
       << "\t 3) Modify Course" << endl
       << "\t 4) Quit" << endl;
  do
  {
    cout << "Your choice (1-4): ";
    cin >> cMenu;
    
    if ((cMenu == '3') && (iClasses == 0))
      cout << endl << "You must first enter a course." << endl;
  }
  while((cMenu == '3') && (iClasses == 0));
    
  return cMenu;
}
//Display the current grade information received by the calling
//  function, then display the menu and get the user's choice. Make
//  sure it's between 1 and 4, and not 3 if there are no entries.
//  Return the user's choice to the calling function.

void AddCourse(Course courses[], const int iClasses)
{
  cout << endl << "Enter the name of the course (no spaces): ";
  cin >> courses[iClasses].cName;
  
  do
  {
    cout << "Enter the number of hours for the course: ";
    cin >> courses[iClasses].hours;
    
    if ((courses[iClasses].hours <= 0) || (courses[iClasses].hours > 13))
      cout << endl << "Invalid entry." << endl;
  }  
  while ((courses[iClasses].hours <= 0) || (courses[iClasses].hours > 13));
  
  do
  {
    cout << "Enter your grade in the course (A, B, C, D, F): ";
    cin >> courses[iClasses].grade;
    
    if (
        ( (courses[iClasses].grade < 'A') ||
        (courses[iClasses].grade > 'F') ||
        (courses[iClasses].grade == 'E') ) &&
        ( (courses[iClasses].grade < 'a') ||
        (courses[iClasses].grade > 'f') ||
        (courses[iClasses].grade == 'e') )
        )
      cout << "Invalid entry." << endl;
  }  
  while (
        ( (courses[iClasses].grade < 'A') ||
        (courses[iClasses].grade > 'F') ||
        (courses[iClasses].grade == 'E') ) &&
        ( (courses[iClasses].grade < 'a') ||
        (courses[iClasses].grade > 'f') ||
        (courses[iClasses].grade == 'e') )
        );
  
  return;
}
//Receive the courses array and what position to add from the calling
//  function. Then prompt the user for the course name, number of hours
//  (Making sure they're positive and no more than 13), and the grade.
//  Modfiy the position in the array by reference and return nothing.

void DispCourses(Course courses[], const int iClasses)
{
  for (int i = 0; i < iClasses; i++)
  {
    cout << endl << (i+1) << ") Name: \t" << courses[i].cName << endl
       << "   Hours: \t" << courses[i].hours << endl
       << "   Grade: \t" << courses[i].grade << endl;
  }

  return;
}

void ModCourse(Course courses[], const int iClasses)
{
  int iWhichCourse = 0;
    
  cout << endl << "Modify Course:" << endl;
  DispCourses(courses, iClasses);
  
  do
  {
    cout << endl << "Which course do you want to modify?: ";
    cin >> iWhichCourse;
    
    if ((iWhichCourse <= 0) || (iWhichCourse > iClasses))
      cout << endl << "Invalid entry." << endl;
  }
  while((iWhichCourse <= 0) || (iWhichCourse > iClasses));

  iWhichCourse--;
  AddCourse(courses, iWhichCourse);
  
  return;
}
//Receive the courses array and number of courses from the calling
//  function. Then prompt the user for which course to modify. Call
//  the DispCourse function with the courses array and number of classes
//  to give the user a menu. Get the user's choice for what to modify.
//  Call the AddCourse function with the courses array and the user's
//  choice (minus 1, since arrays start counting from 0). Return nothing.

int CalcHours(Course courses[], const int iClasses)
{
  int iHours = 0;
    
  for (int i = 0; i < iClasses; i++)
  {
    iHours = iHours + courses[i].hours;
  }

  return iHours;
}
//Receive the courses array, number of classes, and number of hours
//  from the calling function. Reset the number of hours, then add
//  up the hours members from each struct in each position of the array.
//  Then return the total number of hours.

float CalcGpa (Course courses[], const int iClasses, const int iHours)
{
  int iMultiplier = 0;
  float fGpa = 0;
  
    for (int i = 0; i < iClasses; i++)
  {
    switch (courses[i].grade)
    {
    case 'A':
    case 'a':
            iMultiplier = 4;
            break;
    case 'B':
    case 'b':
            iMultiplier = 3;
            break;
    case 'C':
    case 'c':
            iMultiplier = 2;
            break;
    case 'D':
    case 'd':
            iMultiplier = 1;
            break;
    case 'F':
    case 'f':
            iMultiplier = 0;
            break;
    }
    
    fGpa = fGpa + (courses[i].hours * iMultiplier);
  }
  if (iHours != 0)
    fGpa = fGpa / iHours;
  
  return fGpa;
}
//Receive the courses array, number of classes, and number of hours from
//  the calling function. Then associate the grade members from each struct
//  in each position of the array with a multiplier (A is 4, B is 3, C
//  is 2, D is 1, and F is 0). Multiply each multiplier by the number of
//  hours and keep a running total. Divide the final total by the number
//  of hours and return the result to the calling function.

string CalcGrade (const float fGpa, const int iClasses)
{
  string letterGrade = " ";
  
  if (iClasses != 0)
  {
    if (fGpa >= 3.85)
      letterGrade = "A";
    else if (fGpa >= 3.70)
      letterGrade = "A-";
    else if (fGpa >= 3.30)
      letterGrade = "B+";
    else if (fGpa >= 3.0)
      letterGrade = "B";
    else if (fGpa >= 2.70)
      letterGrade = "B-";
    else if (fGpa >= 2.30)
      letterGrade = "C+";
    else if (fGpa >= 2.0)
      letterGrade = "C";
    else if (fGpa >= 1.70)
      letterGrade = "C-";
    else if (fGpa >= 1.30)
      letterGrade = "D+";
    else if (fGpa >= 1.0)
      letterGrade = "D";
    else if (fGpa >= 0.70)
      letterGrade = "D-";
    else
      letterGrade = "F";
  }  
  
  return letterGrade;
}
//Receve the GPA and number of classes from the calling function.
//  If the number of classes is 0, just return a blank for the letter.
//  Otherwise compare the GPA to a table of values and return the letter
//  grade.

