package gradebook;

/**
 * Derived from Section 2.2 of the requirements.
 */
import java.util.Collection;
import gradebook.Student;
import java.util.List;

/**
 * Stores the list of students in the class (which in turn contain the
 * class grades) as well as the grading period.
 */
public abstract class ClassData {
   //wdugger
   /**
    * Adds a new student to the students Collection.
    * studentID must be nonempty. There cannot be a student in students
    * with the same studentID as the new student.
    */
   /*@
    requires
      //studentID is not empty
      (newStudent.studentID.length() > 0)

      &&

      //There is no student in students that has the same studentID
      //as the given newStudent.
      (!(\exists Student s_other ;
         students.contains(s_other) ;
         s_other.studentID.equals(newStudent.studentID)));

    ensures
      //A student is in the output data iff it is the new student to
      //be added or it is in the input data.
      (\forall Student s_other ;
         students.contains(s_other) <==>
         s_other.equals(newStudent) || \old(students).contains(newStudent));
   @*/
   abstract void addStudent(Student newStudent);

   //wdugger
   /**
    * Changes the current record in students (oldS) to newS. oldS must
    * exist in students, the new studentID must be non-empty and no
    * record in students can have the same studentID.
    */
   /*@
    requires
      //Student is in students
      students.contains(oldS)

      &&

      //New student ID is not empty
      newS.studentID.length() > 0

      &&

      //There is no student in students that has the same studentId as
      //the given newS
      (!(\exists Student s_other ;
         students.contains(s_other) ;
         s_other.studentID.equals(newS.studentID)));

    ensures
      //Student is in output iff it is the new student or it is in the
      //input and it isn't the old student
      (\forall Student s_other ;
         students.contains(s_other) <==>
         s_other.equals(newS) ||
         (\old(students).contains(s_other) && !s_other.equals(oldS)));
   @*/
   abstract void editStudent(Student oldS, Student newS);

   //wdugger
   /**
    * Removes a student from the students Collection.
    * The student to be removed must exist within students.
    */
   /*@
    requires
      //Student is in students
      students.contains(student);

    ensures
      //Student is in output iff it isn't the student to be deleted and it
      //is in the input
      (\forall Student s_other ;
         students.contains(s_other) <==>
         !s_other.equals(student) && \old(students).contains(s_other));
   @*/
   abstract void deleteStudent(Student student);

   //wdugger
   /**
    * Changes the GradingPeriod in the class to match the given period.
    */
   /*@
    requires
      //GradingPeriod exists
      period != null;

    ensures
      //The period is equal to the new period
      period.year == newPeriod.year &&
      period.period == newPeriod.period;
   @*/
   abstract void updatePeriod(GradingPeriod newPeriod);

   //wdugger
   /**
    * A string containing the name of the class. This will be displayed
    * throughout the program as an identifier to the class.
    */
   String className;

   //wdugger
   /**
    * Represents a year and seasons. Uniquely identifies a class quarter.
    */
   GradingPeriod period;

   //wdugger
   /**
    * students contains the roster for the class, and all of the information
    * for each individual student.
    */
   List<Student> students;
}

/**
 * The grading period (quarter) that the class is in.
 */
abstract class GradingPeriod {
   Period period;
   int year;
}

/**
 * The four grading periods used in the quarter and semester systems
 */
enum Period {
   Fall,
   Winter,
   Spring,
   Summer
}