import java.util.Comparator;

/**
 * A simple Student class: name, grade and A-number. Extends Person, so it's 
 * sortable by name.
 *
 * @author Mark Young (A00000000)
 */
public class Student extends Person {

    // instance variables
    public final String A_NUMBER;
    private int grade;

    // class variables
    public static final int MAX_GRADE = 100;
    private static int numStudents = 0;
    
    // comparators
    public static final Comparator<Student> BY_GRADE
            // grades are sorted from highest to lowest
            = (one, other) -> Integer.compare(other.grade, one.grade);
    public static final Comparator<Student> BY_ANUMBER
            = (one, other) -> one.A_NUMBER.compareTo(other.A_NUMBER);

    /**
     * Create a Student with the given name. Grade is initialized to zero, and
     * the new Student is assigned the next available A-number.
     *
     * @param n this Student's requested name
     */
    public Student(String n) {
        super(n);   // set my name AS A Person
        grade = 0;
        A_NUMBER = nextANumber();
    }

    /**
     * Change this Student's grade.
     *
     * @param g the Student's new grade
     * @throws IllegalArgumentException if the requested grade is not valid
     */
    public void setGrade(int g) {
        if (isValidGrade(g)) {
            this.grade = g;
        } else {
            throw new IllegalArgumentException("Invalid grade: " + g);
        }
    }

    /**
     * Get this Student's grade.
     *
     * @return this Student's grade
     */
    public int getGrade() {
        return this.grade;
    }

    /**
     * Include this Student's A-number in the output when the Student is
     * printed.
     *
     * @return this Student's name and A-number in a single String
     */
    @Override
    public String toString() {
        return this.getName() + " (" + this.A_NUMBER + ")";
    }

    /**
     * Check whether the suggested grade is valid. That is, is in the range of
     * zero the {@code MAX_GRADE} inclusive.
     *
     * @param g the suggested grade
     * @return true if the suggested grade is valid; false otherwise
     */
    private static boolean isValidGrade(int g) {
        return 0 <= g && g <= MAX_GRADE;
    }

    /**
     * Generate the next available A-number.
     *
     * @return a previously unused A-number String
     */
    private static String nextANumber() {
        ++numStudents;
        return String.format("A%08d", numStudents);
    }

}
