/*
 * GradeSet - a blueprint class for representing a collection
 * of grades.
 * 
 * This version uses an array of type Grade.
 */

public class GradeSet {
    private String name;         // name of the assignment, quiz, etc.
    private int possiblePoints;  // number of possible points
    private Grade[] grades;      // collection of grades
    private int gradeCount;      // number of grades added thus far
    
    /* constructor */
    public GradeSet(String name, int possPts, int numGrades) {
        this.setName(name);
        this.setPossiblePoints(possPts);
        this.grades = new Grade[numGrades];
        this.gradeCount = 0;
    }
    
    /*** accessor methods for the fields ***/
    
    public String getName() {
        return this.name;
    }
    
    public int getPossiblePoints() {
        return this.possiblePoints;
    }
    
    public int getGradeCount() {
        return this.gradeCount;
    }
    
    /* 
     * getGrade - returns the grade at the specified index in 
     * the collection of grades.
     */
    public Grade getGrade(int i) {
        if (i < 0 || i >= this.gradeCount) {
            throw new IndexOutOfBoundsException();
        }
        
        return this.grades[i];
    }
    
    /*** mutator methods for the fields ***/
    
    public void setName(String name) {
        if (name == null || name.equals("")) {
            throw new IllegalArgumentException();
        }
        
        this.name = name;
    }
    
    public void setPossiblePoints(int possPoints) {
        if (possPoints <= 0) {
            throw new IllegalArgumentException("invalid parameter: " + possPoints);
        }
        
        this.possiblePoints = possPoints;
    }
    
    /*
     * addGrade - adds the specified Grade to the collection.
     * The new grade is added after any existing grades in
     * the collection.
     */
    public void addGrade(Grade g) {
        if (this.gradeCount == this.grades.length) {
            throw new IllegalArgumentException("no more room");
        }
        
        this.grades[this.gradeCount] = g;
        this.gradeCount++;
    }
    
    /*
     * averageGrade - get the average of the grades in the
     * collection, either with the late penalty (if the parameter
     * is true) or without the late penalty (if the parameter
     * is false).
     */
    public double averageGrade(boolean includePenalty) {
        double total = 0.0;
        for (int i = 0; i < this.gradeCount; i++) {
            Grade g = this.grades[i];
            if (includePenalty) {
                total += g.getAdjustedScore();
            } else {
                total += g.getRawScore();
            }
        }
        
        return total/this.gradeCount;
    }
}