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

#define NUM_GRADES 5
//const int NUM_GRADES = 5;


int getInteger(string, int, int);
double getDouble(string, double, double);

class Grades {
private:
  string names[NUM_GRADES];
  double weights[NUM_GRADES];
  double scores[NUM_GRADES];
public:
  //constructor, initialize weights to .2
  //and scores to 100 (pick some default name)
  Grades() { 
    for (int i = 0; i < NUM_GRADES; i++) {
      names[i] = "Default";
      weights[i] = 0.2;
      scores[i] = 100;
    }
  }
  //get in all the values from the console
  void readAll() {
    cout << "Input name, weight and then score: ";
    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("Scores [0-100]: ", 0, 100);
    }
  }
  //output all the values to the console
  void output() {
    cout << " ***************** " << endl;
    for (int i = 0; i < NUM_GRADES; i++) {
      cout << i+1 << ": " << names[i] << " \t"
	   << weights[i] << " \t"
	   << scores[i] << endl;
    }
    cout << " ----------------- " << endl;
  }
  //do the actual weighted average computation
  double getAverage() {
    double avg = 0;
    for (int i = 0; i < NUM_GRADES; i++) {
      avg += weights[i] * scores[i];
    }
    return avg;
  }

  //set the ith score to the value v
  void setScore(int i, double v) {
    if (v > 100 || v < 0 || i < 0 ||
	i >= NUM_GRADES)
      return;
    scores[i] = v;
  }

};

int main() {
  Grades mygrades;
  mygrades.output();
  mygrades.readAll();
  mygrades.output();
  cout << "The average is: " << mygrades.getAverage() << endl;
  for (int i = 0; i <= 100; i += 10) {
    mygrades.setScore(4, i);
    cout << "Last Score: " << i << "  Average: " <<
      mygrades.getAverage() << endl;
  }


}


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;
}
