//created by Dr. Ramsey on 4/29/2016
//implements worksheet 9 functionality and then some
//change the NUM_GRADES define to fit the number of
//categories in your class!

#include<iostream>
#include<string>
using namespace std;

#define NUM_GRADES 5

int getInteger(string prompt, int min, int max) {
  cout << prompt;
  int v;
  cin >> v;
  while (cin.fail() || v < min || v > max) {
    cin.clear();
    cin.ignore(100, '\n');
    cout << prompt;
    cin >> v;
  }
  return v;
}
double getDouble(string prompt, double min, double max) {
  cout << prompt;
  double v;
  cin >> v;
  while (cin.fail() || v < min || v > max) {
    cin.clear();
    cin.ignore(100, '\n');
    cout << prompt;
    cin >> v;
  }
  return v;
}


class Grades {
private:
  double weights[NUM_GRADES], scores[NUM_GRADES];
  string names[NUM_GRADES];
public:
  //construct the grades class
  //default weights are .2, and scores are 100
  Grades() {
    for (int i = 0; i < NUM_GRADES; i++) {
      weights[i] = 0.2; // worth 20% of grade
      scores[i] = 100; //100%
      names[i] = "Default"; //default category name
    }
  }

  //get input for all the data from the console
  void readAll() {
    double sum = 0;
    while (sum < .999 || sum > 1.001) {
      sum = 0;
      cout << "Input name, weight and score:" << endl;
      for (int i = 0; i < NUM_GRADES; i++) {
	cout << i + 1 << " name: ";
	cin >> names[i]; 
	weights[i] = getDouble("weight [0.0-1.0]: ", 0, 1);
	scores[i] = getDouble("score [0.0-100.0]: ", 0, 100);
	sum += weights[i];
      }
    }
  }

  //output all the data to the console
  void output() {
    cout << " -------------------- " << endl;
    for (int i = 0; i < NUM_GRADES; i++) {
      cout << names[i] << " \t"
	   << weights[i] << " \t"
	   << scores[i] << endl;
    }
    cout << " -------------------- " << endl;
  }

  //get the weighted average
  double getAverage() {
    double sum = 0;
    for (int i = 0; i < NUM_GRADES; i++) {
      sum += scores[i] * weights[i];
    }
    return sum;
  }

  void setScore(int i, double v) {
    if (i >= 0 && i < NUM_GRADES) {
      scores[i] = v;
    }
  }
};

int main() {
  Grades mygrades;
  mygrades.output(); //not in wk9, but USEFUL!
  mygrades.readAll();
  mygrades.output();
  cout << "My average is: " << mygrades.getAverage() << endl;

  //code in main below this point is in addition to wk9
  string changeScore;
  cout << "Want to change a score? ";
  cin >> changeScore;
  while (changeScore == "y" || changeScore == "yes") {
    int i = getInteger("Input Which Score: ", 0, NUM_GRADES - 1);
    double newValue = getDouble("Input New Score: ", 0, 100);
    mygrades.setScore(i, newValue);
    mygrades.output();
    cout << "My average is: " << mygrades.getAverage() << endl;
    cout << "Want to change a score? ";
    cin >> changeScore;
  }

}
