package schedule;
import java.util.Collection;

/**
 * The Calendar object is derived from an overall view of Sections 2.1 through
 * 2.5 of the requirements.  The functionality described in those sections
 * makes it clear that a Calendar is the primary data object of the Calendar
 * Tool.
 *									     <p>
 * The data component of a Calendar is a collection of scheduled items.  The
 * operations are those that schedule each of the four types of scheduled
 * item.  In the case of meetings, there are two operations involved -- one to
 * compute a list of possible times, and another to confirm a specific selected
 * meeting time.
 */
public abstract class Calendar {

    Collection<ScheduledItem> data;

    /**
     * ScheduleAppointment adds the given Appointment to this.data, if an
     * appointment of the same time, duration, and title is not already
     * scheduled.
     */
    abstract void scheduleAppointment(Appointment appointment);

    /**
     * ScheduleMeeting uses the given MeetingRequest to determine possible
     * times that the requested meeting might be held, within the existing set
     * of scheduled items in the this.data.  The PossibleMeetingTimes output is
     * a list of zero or more possible times and dates that the meeting can be
     * held.
     */
    abstract PossibleMeetingTimes scheduleMeeting(
        MeetingRequest meetingRequest);

    /**
     * ConfirmMeeting takes a MeetingRequest, list of PossibleMeetingTimes, and
     * a Selected time from the list.  It adds a meeting to this.data,
     * comprised of the given request, scheduled at the selected time.  Further
     * details of output constraints are forthcoming.
     */
    abstract void confirmMeeting(
        MeetingRequest request,
        PossibleMeetingTimes times,
        int selectedTime);

    /**
     * ScheduleTask adds the given Task to this.data, if a task of the same
     * time, duration, and title is not already scheduled.
     */
    abstract void scheduleTask(Task task);

    /**
     * ScheduleEvent adds the given Event to this.data, if an event of the same
     * time, duration, and title is not already scheduled.
     *                                                                     <pre>
      pre:
        //
        // The Title field is not empty.
        //
        (event.title != null && event.title.length() >= 1)

            &&

        //
        // The startOrDueDate field is a valid date value.
        //
        (event.startOrDueDate != null) && event.startOrDueDate.isValid()

            &&

        //
        // If non-empty, the EndDate field is a valid date value.
        //
        (event.endDate != null) ==> event.endDate.isValid()

            &&

        //
        // No event of same startDate and title is in the current calendar.
        //
        ! exists (ScheduledItem item ; 
            data.contains(item) ;
                (item.startOrDueDate.equals(event.startOrDueDate)) &&
                (item.title.equals(event.title)));

      post:
        //
        // If preconds met, a scheduled item is in the output calendar if
        // and only if it is the new appt to be added or it is in the 
        // input calendar.
        //
        forall (ScheduledItem item;
            data'.contains(item) iff
                (item == event ||
                 data.contains(item)));

     *
     */
    abstract void scheduleEvent(Event event);

}