package schedule;

import database.Course;
import java.util.Collection;

/**
 * A CourseOverlap holds the information about a courses overlap restrictions. A
 * course overlap restriction represents the courses that cannot be offered at
 * the same time as the provided course. A course represents the selected
 * course, and the restrictions list represents the list of courses that cannot
 * be offered at the same time as the course.
 *
 * A CourseOverlap is derived from Section 2.6.1, specifically Figure 6.
 * @author vforney
 *
 */
public abstract class CourseOverlap extends ScheduleConstraint {
  /**
   * The course whose restrictions we are changing
   */
  Course course;

  /**
   * The collection of courses that are restricted from being offered at the
   * same time as the course above.
   */
  Collection<Course> restrictions;

  /**
   * Add the given Course to the given CourseOverlap's list of restrictions.
   * The courses department and courseNumber must be unique, and the courseType,
   * department, courseNumber, weeklyDuration, expectedSize, wtus, and credits
   * are required.
   * @param course The course to add to the restriction list.
   */
  /*@
    requires
      //
      // There is no course already in the restrictions list with the same
      // department and courseNumber as the course to be added.
      //
      (!restrictions.contains(course))
         &&
      // 
      // The courseType is not empty.
      //
      (course.courseType != null) &&
       (course.courseType == Course.CourseType.DISCUSSION ||
       course.courseType == Course.CourseType.SEMINAR ||
       course.courseType == Course.CourseType.LAB ||
       course.courseType == Course.CourseType.LECTURE)
         &&
      // 
      // The course department is not empty.
      //
      (course.department != null) && (course.department.longName.length() > 0 ||
       course.department.shortName.length() > 0)
         &&
      // 
      // The courseNumber is a positive number.
      //
      (course.courseNumber > 0)
         &&
      // 
      // The weeklyDuration is a positive number.
      //
      (course.weeklyDuration > 0)
         &&
      // 
      // The expectedSize is a number greater than or equal to 0.
      //
      (course.expectedSize >= 0)
         &&
      //
      // The wtus are a positive number.
      //
      (course.wtus > 0)
         &&
      // 
      // The credits are a positive number.
      //
      (course.credits > 0);
    
    ensures
    //
    // A course is in the restriction list after it is added.
    //
    this.restrictions.contains(course);
   @*/
  abstract void addRestriction(Course course);

  /**
   * Removes a restriction from the list of restrictions. The course given
   * must be in the restrictions collection.
   * @param course The course to remove from the restriction list.
   */
 /*@
   requires
     //
     // The given course is in this.restrictions.
     //
     (this.restrictions.contains(course));

   ensures
     // 
     // The given course is no longer in this.restrictions.
     //
     (!this.restrictions.contains(course));
   @*/
  abstract void removeRestriction(Course course);
}