package schedule; import caldb.CalendarDB; import caldb.Room; 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. *

* 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 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. *

 
       pre:
	// There is at least one time that is between the given start time and
        // end time at which the room is available.
        exists (Time time ;
            inRange(time, starttime, endtime)
                &&
            roomAvailable(room, time)

       post:
        //
        // An item is properly added to the output db at the "best" time,
        // where best means the earliest possible time between the given start
        // time and end time at which the given room is available.
        //
        // Also, the room in which the item is scheduled is booked for the
        // item's time.
        //
        exists (ScheudledItem item; data'.contains(item) ;

            //
            // The item is scheduled at the best time.
            //
            scheduledAtBestTime(item, starttime, endtime, room)

                &&

            //
            // The item's room is booked for the item's time.
            //
            !roomAvailable(meetingRequest.room', item.time)

                &&

            //
            // The item info is that given in the input.
            //
            (item.info = info)

                and

            (*
             * Only the new item and original items are in the output item
             * db (this is standard logic for properly adding to a collection).
             *) 
            forall (item':ScheduledItem) (
                (item' in sidb') iff ((item' in sidb) or (item' = item))
            )
        );
     */
    abstract PossibleMeetingTimes scheduleMeeting(
        MeetingRequest meetingRequest);


    /**
     * A given meeting item is scheduled at the best time.
     *
      post:
       return ==

	//
	// The scheduled time is between the given start time and end time.
	//
	inRange(meeting.time, startTime, endTime)

	    &&

	//
	// The room is available at the scheduled time.
	//
	roomAvailable(room, meeting.time)

	    &&

	//
	// The scheduled time is the earliest possible.
	//
	isEarliest(meeting.time, startTime, endTime, room)
     */
    abstract boolean scheduledAtBestTime(Meeting meeting,
        Time startTime, Time endTime, Room room);

    /**
     * For a given time, no other in-range, non-booked time is earlier.
     *
      post:
       return ==
	!exists (otherTime:Time
		InRange(otherTime, startTime, endTime)
		    &&
		RoomAvailable(room, otherTime)
		    &&
		(otherTime.compareTo(time) < 0)
	    )
	)
     */
    abstract boolean isEarliest(Time time,
	Time startTime, Time endTime, Room room);

    /**
     * A given time is between a given start time and end time.
      post:
       return ==
	time.compareTo(startTime) >= 0 &&
	time.compareTo(endTime) <= 0;
     */
    abstract boolean InRange(Time time, Time startTime, Time endTime);

    /*
     * A given room is available at a given time.  Since the room object
     * contains a list of UNavailable times, the logic is negative.  I.e., a
     * room is available at time t means there is no time on the booked list
     * equal to t.
      post:
       return ==
	!exists (bookedTime; room.booked.contains(time); time == bookedTime);
     */
    abstract boolean roomAvailable(Room room, Time time);
    

    /**
     * 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:
        //
        // 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()

            &&

        //
        // The current workspace is not null.
        //
        (calDB.getCurrentCalendar() != null)

            &&

        //
        // No event of same startDate and title is in the current workspace
        // calendar.
        //
        // No event of same startDate and title is in the current calendar.
        //
        ! exists (ScheduledItem item ; 
            calDB.getCurrentCalendar().items.contains(item) ;
                (item.startOrDueDate.equals(event.startOrDueDate)) &&
                item.duration.equals(event.duration) &&
                (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;
            calDB'.getCurrentCalendar().items.contains(item) iff
                (item == event ||
                 calDB.getCurrentCalendar().items.contains(item)))

            &&

        //
        // Also, requiresSaving is true in the output calendar.
        //
        calDB.getCurrentCalendar().requiresSaving;
     */
    abstract void scheduleEvent(Event event);

    CalendarDB calDB;
    boolean requiresSaving;
}