TABLE OF CONTENTS:

1. Problem Analysis

1.1. Operational Personnel and Proposed System Users

1.2. Overview of Current and Proposed Operations

1.3. Analysis of Relevant Existing Systems

1.4. Impact Analysis

2. User Overview

2.1. Scenario 1: Calendar Viewing and Appointment Editing

2.2. Scenario 2: Browsing Other Calendars and Group Meeting Information

2.3. Scenario 3: Group Scheduling and Administration

2.4. Scenario 4: Global Administration

3. System Overview: Major System Objects and Operations

4. Overview of System Goals and Constraints

4.1. System Performance Constraints

4.2. Qualitative System Characteristics

4.3. Development Goals and Constraints

5. Formal Specifications -- Preliminary

6. Appendix A: Preliminary Users Manual

1. Problem Analysis

Personal time management and scheduling become more and more crucial to an organization as its size increases. Obviously, the more employees or members there are within a particular business or organization, the more difficult it will be to coordinate and manage the organization as a whole. As a remedy to the hassles of continuously conflicting schedules and inefficient time management, Fab Five Inc. proposes an elaborate electronic calendar.

The calendar will act exactly like a personal datebook to the individual user, but it will also be able to electronically schedule meetings among group members and normal users. The normal employee will be able to view the days and months of a particular year, or the days of a given month or week. If a single day is brought up by the user, the calendar will closely resemble a daily planner, where he or she can enter personal appointments, reminders, or anything else he or she desires under the appropriate time slots listed. If a meeting is requested by a group manager or supervisor, a prposed time is simply entered into the system, along with a proposed room number, and the calendar then checks each group members individual calendar. The calendar then best determines a time and room to hold the meeting based on availability of key attendees and the overall group, as well as room availability.

1.1. Operational Personnel and Proposed System Users

There are four classifications for the basic hierarchy of the proposed system's users:

  1. Superuser
  2. Global Administrator
  3. Group Administrators
  4. Group Members
  5. Normal Users

The global administrator has the ability to add or remove users and groups, import and export mail aliases for creating mail aliases and Calendar groups from each other, schedule meetings for any group, and add or remove any member from any group. The superuser shares the same abilities as the global administrator, but the superuser can also read and modify all user calendars and meeting databases, regardless of whether the information is private.

Group administrators are capable of adding and removing group members to their respective groups. They also are the typical meeting schedulers for their respective groups, and with this responsibility, they must in turn handle schedule requests from their group's members since only an administrator can schedule a meeting.

A global administrator can also take requests and schedule meetings for any group within the group database, while a group administrator is restricted to just being able to schedule meetings for any group he or she administrates. One final administrative priviledge available to both a global and group administrator is the ability able to select what information for a meeting should be private within the group or public to all. For example, a group administrator would typically choose to make the minutes of a meeting private and readable only to members of the group while leaving other information such as meeting times and location open to the public.

Normals users are able to view any person's scheduling or group's meeting information so long as it is public, but they cannot read private group meeting information or private personal schedules of other system users.

1.2. Overview of Current and Proposed Operations

Everyone has their own personal planners and calendar, either hand-held or on personal computers. These planner are good for personal use but not as useful for planning group meetings. There are many factors in scheduling meetings that make it very difficult, such as finding times when all participants are free. With the proposed system, meetings will be much easier to schedule.

Scheduling rooms for meeting is difficult. The administrators have to schedule meeting times to coincide with employee freetime and the time a room is empty. The increase in group size leads to more confusion and difficulty. In the proposed system, administrators will query the system calendar about the best time and best room to have the meeting.

Employees might be in more than one group or committee. Time must be scheduled around the different groups and committees. The proposed system will schedule groups to best fit everyone's schedule. Groups under five and single users are not reccommended for this system.

1.3. Analysis of Relevant Existing Systems

Many people have the basic idea of a calendar either on the computer or a personal digital one. Many businesses and organizations, own or have access to a computer with an electronic calendar. The calendar has been used world-wide in the conventional manner; however, not necessarily using a network as it's backbone. A calendar may meet the needs of single users, small companies or organizations where communication between busy schedules is not a major problem.

We would like to have a network of computers, each having a calendar, sharing resources in order to efficiently use time. If computers exist for the organization or business that would like to install a network-calendar, the only other issue is if they have a network.

1.4. Impact Analysis

The positive impact of the proposed system is that it would offer greater efficiency and improved accessibility into one another's public schedules for users of a company or organization. Most people already use some form of a scheduling manager, such as a notebook or computerized pocket planner. The proposed system would allow users to coordinate their activities with greater ease than existing personal planners.

The most negative impact of the proposed system is that some users may be concerned about privacy issues with respect to their own schedules. Users need to be assured that their personal engagements will not be visible to any other user, should they wish it to be private. Another negative impact of the proposed system is that it requires users to participate. If a large percentage of the users fail to do so, the proposed system will not be effective. Several factors could cause a lack of use. Among them, some people may be intimated by using a computer program to organize their schedules or they may need a small amount of training to become comfortable with the proposed system. Others may not have easy access to a computer with this system installed, and finally some people may prefer to keep their schedules in a personal daily planner.

For the proposed system, the positive impacts outnumber the negative impacts. Using the proposed system would save a significant amount of time and confusion which often arises when coordinating schedules, especially for employees in a large company. A down side is that some people may be hesitant or unable to use the proposed system on a regular basis. However, in the worst case, this will only force them to resort to previous methods that they used to organize their schedules. With some encouragement and assistance from co-workers already using the proposed system, they will hopefully change and begin using this product, thus making it more effective.

2. User Overview

2.1. Calendar Viewing and Appointment Editing

This initial scenario describes the various calendar views and appointment editing features available to all users of the calendar system. A normal user can browse or edit his or her own calendar, view another's calendar, or read meeting information for all groups within the calendar system. The scenario below outlines calendar viewing and appointment editing. Normal users cannot schedule meetings or perform administrative tasks. These privileges are left to the superuser, global administrator, and group administrators. Later scenarios illustrate these capabilities.

When a normal user starts up the calendar system, he or she will see a screen which looks like the following:

The first screen demonstrates the yearly view for a user calendar. In this view, a user can click on a month or day and change to a corresponding calendar view. The user also has several options available in the three pulldown menus.

The screen above illustrates the contents of the pulldown menu buttons. The View button can be used to alternate among the yearly, monthly, and weekly views. Pressing the Browse button allows the user to view the calendar of another user or group. The Edit button has two options in its pull down menu. One option opens up an appointment editor window for the current day, or one could simply click on a day. The other option opens a window for setting the user's preferences. In this example, the user's first selection is to click on the View pull down menu button in order to change to the monthly calendar view.

Notice that the same View, Edit, and Browse buttons are available from the monthly view. From this window, the user can read brief notes written in for each day of the month. The user can also insert text here for any given day. For any day in which the user has not entered a remark, a very brief form of the day's appointment summary will appear instead. clicking once on the day and typing a few words of text.

Next, the user decides the use the Edit button in order to reconfigure his or her display settings and editing defaults.

After applying any new changes or canceling, the user will be returned to the monthly calendar view. From there, the user changes to the regular weekly calendar view which is shown below.

This weekly view shows the day summaries for every day of the week. There is a second weekly view available to the user, and it is shown next. Once again, the user must use the View pull down menu in order to change screens. In this example, the user proceeds to the second weekly view, the weekly model.

The weekly model above provides a quick reference for determining when a user is busy during the week. All shaded areas indicate times when the user has something scheduled.

There are many ways one can get to the appointment editor. For example, the user could double click on a day in the monthly view, or one could use the Edit pull down menu button. For this screen, the user simply clicks on a time during the week.

From this screen, the user can edit his or her personal appointments, choosing from three levels of privacy. Only one of the three privacy buttons may be depressed. If the scheduled item is chosen to be Public, then the information for the appointment will be readable to all users. If marked as Busy, then the scheduled item will simply appear as "unavailable". Private appointments do appear in the calendar to other users and are thus invisible when others try browsing this calendar.

Alarm settings can also be adjusted for each scheduled item, and appointments can be repeated conveniently any number of times for various time intervals. The day summary and remarks for the day are listed on the right. Remarks are brief notes or reminders which appear in day boxes on the monthly calendar view. If no remarks are entered for the day, then a brief form of the day summary is what the user will instead see in the monthly view.

Several options appear at the bottom of the appointment editor. The Clear button erases the start, end, and description information and would normally be used when the user wishes to begin entering a new appointment. The Insert button inserts a newly scheduled item into the user's calendar if the all of the appointment information is valid. Delete removes the currently selected appointment for the day, and Change updates the currently highlighted appointment if any modifications have been made to the scheduled items information. This would inlclude modifying the user's calendar should the date or start and end times be changed.

2.2. Browsing Other Calendars and Group Meeting Information

To browse through the calendar of another user or of a group, the user only needs to use the pull down Browse button in any of the calendar views. In this scenario, the user chose to view the calendar of another user. Here is the first screen that the user will see when he or she begins to browse:

By clicking on a user in the list, his or her name will be shown as the user selected. The user's name cannot be entered and must be chosen from the list. After a user has picked another user's calendar to browse, the View Calendar button may be pressed to begin browsing. The user will first see the daily view for the current day. This screen is shown below:

The user can use the View pulldown menu to browse through the other user's schedule just as if it was his or her own calender. However, as shown in the above screen, the person browsing does not have at Edit menu button and will thus not be able to use the appointment editor. It should also be noted that things marked as private will not be visible to the browser, and items marked as unavailable will appear as unavailable rather than being summarized.

The screen below shows the contents of the two available pulldown menus.

After viewing someone else's calendar, the user next decides to browse through a group and its meeting records. To do this, the user must use the pull down Browse button to open the window below. Once again, the group must be chosen from the list and cannot be entered by hand. In our example, the user decides to view meeting information for the SLOSoft Software Design Team.

Normally, the first meeting record to appear will be the next upcoming meeting. For purpose of illustration, the meeting record shown below is an event that has already taken place. This was done in order to demonstrate how the meeting minutes would appear. Also note, everything listed in the meeting record is visible. Certain information chosen by the group administrator could have been marked as private, and thus would have not been seen here. If however, the person browsing is actually a member of the group, then all of the meeting information would be printed, regardless of whether it was marked as public or private.

2.3. Group Scheduling and Administration

This scenario demonstrates some of the basic functionality of scheduling meetings for a group. The scenario initially begins with the same yearly view seen earlier.

Notice the Admin button in the yearly calendar view. Anyone who is an admininstrator (Group Administrators, Global Administrator, SuperUser) will see this button in all of their own calendar views. The screen above shows the yearly calendar view as an example. For a group administrator who presses this button, the following menu is opened:

Three options are available: Schedule Meeting, Import Minutes and Attendees, and Update Member List. A screen illustrating the Import feature is not given, but this operation allows the group administrator to import text files for the minutes and user attendee list after the meeting has taken place. This feature saves the group administrator from having to re-type these items when updating the meeting information.

In our scenario, the group administrator initially chooses to schedule a meeting.

This window is used to schedule meetings by the group administrator. The Group administrator uses the scroll bar, next to committee name, to check the group for which the meeting is to be set. Once the Committee is selected, the committee members' names will appear in the designated window. The group administrator sets any or all of the following: time, date, duration, and location. Any variable that is not set will be that for which the calendar will search.

If the search was successful, the screen above appears showing the search results. The group admininstrator is then given a final set some of the miscellaneous meeting information. The group adminstrator can set the meeting as a priority and also set the kind of reminders to send the committee members. In this example, priority has been set to "no" and the reminders "flash" and "mail" have been set. Note that the starting time of the meeting has been found. Once the group administrator is completed adjusting the extra options, the meeting can be penciled into the members' calendars.

With the meeting officially scheduled, the group administrator must then mark what portions of the meeting he or she would like private and hidden from non-group members.

In this example, the minutes of the last meeting are declared to be private, thus the minutes will not be shown on the screen when someone wishes to browse the proceedings of the meeting.

After scheduling a meeting, the group administrator returns to the main admin menu. From here, the user then decides to update the group member list.

The Modify Committee Members screen is used to add a member to the a group or to delete them. All that is needed to add a member is to enter the name and the userid. After that is done, just click the add button and the persons name will appear on the Commuttee Members screen. To delete a person, one needs to either enter the name and the id or highlight the name in the Committee Members box and then press delete. Right now Darryl Ragsdale needs to be added to the Finance Committee.

2.4. Global Administration

The following scenario demonstrates some of the features available to a global administrator or superuser. The only power the superuser has over the global administrator is the ability to read and write protected and private user calendar appointment information and private meeting information for any group's meeting database. The superuser should rarely need to do this, and the scenario below does not demonstrate this power. The primary points of interest in this scenario center on maintaining the group, user, and room databases.

The scenario begins with a monthly calendar view already seen in a previous scenario. As before, the Admin button must me used to open the administration menu. This menu and its options can be seen below.

The next three screens illustrate how to update the user, group, and room databases respectively.

The above window shows how to add, delete, or modify users in the user database.

After updating the user database and returning to the main administrative menu, the global administrator then decides to update the group database.

Updating the group database in done in very similar to the way you maintain the user database. Groups themselves can likewise be added and deleted. The superuser or global administrator can also change the group administrator for any group should he or she wish to do so. Additionally, there is a scrollable window for viewing the selected group's members. If the administrator wishes to alter the list of members for the group, then the Update Member List button may be pressed. This action will open up a screen already seen previously in the Group Scheduling and Administration scenario.

After updating the group database and returning to the main administrative menu, the global administrator next decides to update the room database.

To add or remove a room from the room database, like adding or deleting a user from a group, the administrator adds the appropriate information for the given prompts. The selection buttons give the user the option of adding or deleting and a confirmation is automatically made for the selection of either. "Modify" is used to change either the room name, location, id or any combination of the three.

Once last adminstrative feature yet to be discussed, is the ability to import and export mail aliases. This can be done from the main administrative menu seen at the beginning of this scenario. The import/export mail alias operation allows the global administrator to create mail aliases and Calendar groups from each other.

3. System Overview: Major System Objects and Operations

The Calendar Manager has two functions: Meeting scheduler and an appointment calendar. The Meeting scheduler communicates with all the databases while the electronic calendar manages all of the users appointment calendars.

The Calendar Managers major function is scheduling meetings for registered users and groups. The scheduler operates on all of the databases that the system contains. These are the User database, the Room database, the Meeting database, the Group database, and the Defaults databases. The User database contains a list of the registered users of the Calendar system. The Room database is a list of rooms id's, a list of the times the room is unavailable, and the maximum occupancy of the room. The Meeting database is just a list of past, present and future scheduled meetings and their relevant information. The Group database is a list of group names, group members that go with the corresponding group name, and the size of the group. The last database is the Default database. It holds all of the system defaults.

The Global and Group administrators are the only users who can schedule meetings in this system. The Global administrator can schedule meetings among groups, individuals, and for just single groups. The Group administrator can only schedule for the group that he administrates.

The Calendar Manager takes in the inputs start and end time(the range of the meeting), start and end date(the date range of the meeting), duration (how long the meeting is), and the location of the meeting. All of the fields do not have to be filled in. The Calendar System will search for the best time, place, or day for the meeting. When the best time is found, the system will pencil it in on the Group member's Calendar. The user is then instructed to mail the administrator to confirm the meeting.

The users are able to put appointments on their calendars and set the calendar to alarm and remind them of their meetings. The users can also browse other users calendars to see what their schedule is. One user can see another user's public calendar entries but not the protected or private entries. Protected entries will be seen but only as "unavailable" while private entries will not show at all.

The user calendar can be shown in a yearly view, monthly view, a weekly view, and a daily view. Each user can set their calendar to show any view upon startup of the calendar manager.

4. Overview of System Goals and Constraints

Given below are qualitative constraints that must be met by the Electronic Calendar system. The following terminology is used:

	- Super User: "Overseer" to the system; closest contact on the part
	  of the purchasers with the developers of the calendar.

	- Global Administrator: Maintainer of all databases and major
	  operations of the system. 
	
	- Group Administrator: Users of the calendar system who add, remove
	  and schedule members of their respective groups.   

	- Group Member: Individual users of the system who essentially view
	  the calendar as a personal datebook, or daily planner.

	- Normal User: Those users who do not belong to a particular group. 

	- System Developers: Team of engineers who will implement the system
	  and assure it conforms to all requirements specified in this
          document.	 

        - Analysts: the authors of this specific document.

4.1. System Performance Constraints

	- The calendar system shall respond to a scheduling query within 15
	  seconds.  If all scheduling criteria is met, the meeting information
	  will be penciled into the attendee's calendar's within 5 seconds
	  after the meeting has been confirmed by the scheduler. 

	- The overall performance of the calendar system has been proven to be
	  30 percent faster than the fastest available system of its kind
          currently out on the market.

	- The calendar system has shown a 99.4% consistency level, in terms of
	  scheduling the appropriate meeting at the most convenient time at
	  the desired location while including all key attendees.

	- All benchmark tests and performance data are base on the article
	  "Neat Micellaneous Tools for Large Organizations" from the June 1,
	  1993 edition of Consumer Reports.

4.2. Qualitative System Characteristics

	- The overriding characteristic of the scheduling interface is speed
		  and ease of use.

4.3. Development Goals and Constraints

The system developers will collaborate with the customer representatives to negotiate a reasonable amount of time to install the calendar system. Installation has typically been accomplished within 3 months, however careful examination of the clients existing system is required to determine the length of time needed to make the system fully operational.

All specifications and performance characteristics are final as stated by this document. All upgrades and alterations must be negotiated seperately and are not included in this package.

The implementation of this system shall be made at the convenience of the customer. All on-site work will be performed during non-business hours and all system developers will be "on call" as deemed necessary by customer representatives. System developers will be required to install any 'temporary' hardware required by the customer in case the calendar implementation requires existing system downtime.

5. Formal Specifications


{*****
******  OBJECTS
*****}


object UserCal is
    components: yearList:Year*;
    operations: ;
    description: {
        A calendar for a user can be broken down into a list of years.
    };
end UserCal;

object Year is
    components: yr:YearNum, monthList:Month*;
    operations: ;
    description: {
        As with any calendar, a Year can be broken into twelve months.
    };
end Year;

object Month is
    components: mon:MonthNum, dayList:Day*;
    operations: ;
    description: {
        Months are broken down into days.
    };
end Month;

object Day is
    components: day:DayName, mmddyy:Date,
		daySched:DaySchedule, rem:Remark;
    operations: ;
    description: {
        The individually scheduled events are stored at the Day level.
        A Day contains a list of all of the ScheduledItems planned 
        for the day.
    };
end Day;

object DaySchedule is
    components: schedList:ScheduledItem*;
    operations: AddSchedItem, DelSchedItem, EditSchedItem, FindSchedItem;
    description: {
        A DaySchedule contains a set of items scheduled for a day.
    };
end DaySchedule;

object MonthNum is number;
object DayName is
    components: Mon or Tue or Wed or Thu or Fri or Sat or Sun;
    operations: ;
    description: {
        DayName is a string naming the day of a week.
    };
end DayName;
object Mon = "Monday";
object Tue = "Tuesday";
object Wed = "Wednesday";
object Thu = "Thursday";
object Fri = "Friday";
object Sat = "Saturday";
object Sun = "Sunday";

object YearNum is number;
object DayNum is number;
object Remark is string;

object ScheduledItem is
    components: startTime:Time, endTime:Time, sum:Summary, desc:Description, 
        details:ScheduleDetails;
    operations: ;
    description: {
        A ScheduledItem contains all of the information pertaining
        to an individual appointment scheduled in a user's calendar.
        The Summary is a brief title description of the ScheduledItem,
        and the Description is a much longer and more detailed decription
        of what is planned.  By letting ScheduledItem contain AlarmInfo
        and ScheduleDetails, it is possible to adjust and customize the 
        behavior of each event.
    };
end ScheduledItem;

object ScheduleDetails is
    components: alarm:AlarmInfo, repeat:RepeatInfo, priv:Privacy;
    operations: ;
    description: {
        ScheduleDetails contains other miscellaneous ScheduledItem  
        details.  Having AlarmInfo as part of ScheduleDetails allows
        alarm settings to be adjusted individually for scheduled
        appointments. RepeatInfo helps ease scheduling by allowing
        the user to schedule personal events daily, weekly, monthly,
        or yearly.  Privacy is an enumerated type which shows whether
        the scheduled item is public, unavailable, or private.
    };
end ScheduleDetails;

object RepeatInfo is
    components: value:TimeValue, interval:TimeUnit;
    operations: ;
    description: {
        RepeatInfo provides a convenient way for the user to schedule
        personal appointments repeatedly.  The TimeUnit is an enumerated
        type showing if the ScheduledItem is repeated daily, weekly, monthly 
        or yearly, and the TimeValue represents how many times the user
        would like it repeated.
    };
end RepeatInfo;

object Privacy is
    components: Public | Unavailable | Private;
    description: {
        Privacy is an enumerated type which determines
        whether the scheduled appointment is public, unavailable,
        or private 
    };
end Privacy;

object Public is
    description: {
        Public is an opaque type representing a kind of scheduled
        appointment.
    };
end Public;

object Unavailable is
    description: {
        Unavailable is an opaque type representing a kind of scheduled
        appointment.
    };
end Unavailable;

object Private is
    description: {
        Private is an opaque type representing a kind of scheduled
        appointment.
    };
end Private;

object Summary is string;
object Description is string;
object TimeValue is number; 
object Active is boolean;

object TimeUnit is
    components: Daily | Weekly | Monthly | Yearly;
    description: {
        TimeUnit is an enumerated type which determines whether the a 
        calendar view is daily, weekly, monthly, or yearly. 
    };
end TimeUnit;

object AlarmTimeUnit is
    components: Minutely | Hourly | Daily;
    description: {
        AlarmTimeUnit is an enumerated type which determines
        whether the TimeValue is in minutes, hours, or days. 
    };
end AlarmTimeUnit;

object Minutely is
    description: {
        Minutely is an opaque object representing a unit of time.
    };
end Minutely;

object Hourly is
    description: {
        Hourly is an opaque object representing a unit of time.
    };
end Hourly;

object Daily is
    description: {
        Daily is an opaque object representing a unit of time.
    };
end Daily;

object Weekly is
    description: {
        Weekly is an opaque object representing a unit of time.
    };
end Weekly;

object Monthly is
    description: {
        Monthly is an opaque object representing a unit of time.
    };
end Monthly;

object Yearly is
    description: {
        Yearly is an opaque object representing a unit of time.
    };
end Yearly;

object AlarmType is
    components: value:TimeValue, unit:AlarmTimeUnit, on:Active;
    operations: ;
    description: {
        AlarmType contains a time value which is a number representing
        how many time units before an alarm occurs, where a time unit
        is an enumerated type representing minutes, hours, days, etc.
    };
end AlarmType;

object AlarmInfo is
    components: beepAlarm:AlarmType, flashAlarm:AlarmType,
        popupAlarm:AlarmType, mailAlarm:AlarmType;
    operations: ;
    description: {
        AlarmInfo contains the various alarms which can be set for
        each scheduled event in a user calendar.
    };
end AlarmInfo;

object UserOptions is
    components: range:DayBoundaries, defView:TimeUnit, 
        alarm:AlarmInfo, showRem:ShowRemarks;
    operations: ;
    description: {
        Options contains all of the preferences for the user's
        personal calendar.
    };
end UserOptions;

object ShowRemarks is boolean;

object DayBoundaries is
    components: startHour:Hour, endHour:Hour;
    operations: ;
    description: {
        DayBoundaries determines what range of hours appear by default when
        the user is in the day view of his/her calendar.
    };
end DayBoundaries;


object InitialOptions:UserOptions = [ InitialDayBoundaries, InitialView, 
        InitialAlarmInfo, InitialAddr ] is
    description: {
        InitialOptions is a predefined object representing what the
        original options are set to for a new user.  A user can also
        choose to restore his or her options to their original defaults.
    };
end InitialOptions;

object InitialDayBoundaries:DayBoundaries = [ BeginDay, EndDay ] is
    description: {
        InitialDayBoundaries are the default day boundaries set for
        a new user's options.  A user can also choose to restore his
        or her day boundaries to these original defaults.
    };
end InitialDayBoundaries;

object BeginDay:Time = [ 7, 0 ] is
    description: {
        BeginDay represents the default begin time for a day boundary.
    };
end BeginDay;

object EndDay:Time = [ 19, 0 ] is
    description: {
        EndDay represents the default end time for a day boundary.
    };
end EndDay;

object InitialView = Yearly;

object InitialAlarmInfo:AlarmInfo = [ InitialAlarm, InitialAlarm,
        InitialAlarm, InitialAlarm ] is
    description: {
        InitialAlarmInfo represents the default alarm configuration
        for a user.  All four of the alarm types (beep, flash, popup,
        mail) are set to the same initial condition as described in
        InitialAlarm.
    };
end InitialAlarmInfo;

object InitialAlarm:AlarmType = [ 10, Minutely, false ] is
    description: {
        InitialAlarm describes a default alarm type for a user.
        In this case, the alarm is set to go off 10 minutes prior to
        an appointment, but the 'false' indicates the alarm is turned 
        off.  A user can change an alarm setting at any time and for 
        any scheduled event, or he or she can restore an alarm to these 
        initial defaults.
    };
end InitialAlarm;
        
object PersonalViewMenu is
    components: ;
    operations: ChangeToMonthlyView, ChangeToYearlyView,
                ChangeToWeeklySummary, ChangeToWeeklyModel;
    description: {
        The PersonalViewMenu lists the calendar view changing
        options available when viewing one's own personal calendar.
    };
end PersonalViewMenu;

object ViewMenu is
    components: ;
    operations: ChangeToDailyView, ChangeToMonthlyView, ChangeToYearlyView,
                ChangeToWeeklySummary, ChangeToWeeklyModel;
    description: {
        The ViewMenu lists the calendar view changing options available when 
        viewing another user's calendar.  A ChangeToDailyView option for
        changing to a daily summary window is included here because a user 
        browsing another individual's calendar cannot use the daily appoint
        editor.
    };
end ViewMenu;

object EditMenu is
    components: ;
    operations: EditDailyAppts, ChangeOptions;
    description: {
        The EditMenu is available when a user is viewing his or her
        own calendar.  The two operations allow the user to edit
        his or her calendar or change preferences.
    };
end EditMenu;

object BrowseMenu is
    components: ;
    operations: UserBrowse, GroupBrowse;
    description: {
        The BrowseMenu enables the user to begin browsing other user
        calendars and various group meeting information.
    };
end BrowseMenu;


object UserDB is
    components: userList:User*;
    operations: MaintainUserDB;
    description: {
        The UserDB is the repository for all users of the calendar
        system.
    };
end UserDB;

object User is
    components: name:UserName, pwd:UserPassword, opt:UserOptions, 
       id:UserId, groups:GroupName*, cal:UserCal, m_alias:MailAlias;
    operations: ;
    description: {
       The User object defines the information each individual
       will have.  Every user has a UserName, ..., and a Calendar.
    };
end User;

object UserName is string;
object UserPassword is string;
object UserId is string;
object MailAlias is string;
object Message is string;
object GroupName is string;

object Time is
    components: hr:Hour, min:Minutes;
    operations: ;
    description: {
        Time is made up of an Hour and Minutes.
    };
end Time;

object Hour is number;
object Minutes is number;
object Date is
    components: mn:MonthNum, dn:DayNum, yn:YearNum;
    operations: ;
    description: {
        Date contains the month, day, and year in numerical form.
    };
end Date;
(*
object Date is string;        (* The date is kept in the form mm/dd/yy *)

object AlarmThreshold is number;
object RepeatThreshold is number;
object MaxDescLength is number;
object MaxSumLength is number;

object DefaultsDB is
    components: at:AlarmThreshold, rt:RepeatThreshold, defMeetingDuration:Time,
                defStartTime:Time, defEndTime:Time, defLocation:RoomId,
                maxDesc:MaxDescLength, maxSummary:MaxSumLength, maxdate:Date;
    operations: ChangeDefaults;
    description: {
        The DefaultsDB contains all of the tunable parameter for the
        calendar system.  The global administrator can adjust these
        using the ChangeDefaults operation.  A breakdown of the default
        settings is as follows:

           The alarm threshold value is the maximum interval that a
           user can assign to any of the alarm values for a scheduled item.

           The maximum number of times a scheduled item can repeated
           is contained in the repeat threshold.

           The default meeting duration is the length of time used when
           the amount isn't specified by the global or group administrator
           attempting to schedule a meeting.

           The default start and end times indicate the range of times
           that the calendar program uses when they aren't specified
           during meeting scheduling.

           Similarly, the default location serves as the primary
           location when it isn't specified in the search parameters
           for scheduling a meeting.

           The maximum description length indicates the maximum number
           of characters that can be used for the description of a scheduled
           item.

           The maximum description length indicates the maximum number
           of characters that can be used for the topic summary of each
           scheduled item.

           maxDate is the farthest date into the future that an appointment
           can be scheduled.
    };
end DefaultsDB;


object GroupDB is
  components: committee:Group;
  operations: ;
  equations: 
    var g: GroupDB; e, e':Group;
    FindInGroupDB(EmptyDB(), e) == false;
    FindInGroupDB(AddtoGroupDB(g, e), e') == 
      if e = e' then true else Find(s,e');
    DeletefromGroupDB(EmptyDB(), e) == Empty;
    DeleteFromGroupDB(AddToGroup(g, e), e') ==
      if e = e' then DeleteFromGroupDB(g, e') 
      else AddToGroupDB(DeleteFromGroupDB(g , e'), e);
  description: {This holds all the group names and a list of users that
                belong to each gorup.  This database will be updated whenever                   group or user is added or deleted };
end GroupDB;


object Group is
  components: CommitteeName:GroupName, Member:User, number:size,GroupAdmin:User;
  operations: ;
  description: {};
end Group;

object SchedulingSpec is
  components: meetinginfo:SchedulingInfo;
  operations: Search, Cancel;
  description: { This screen is used to search for common location, time and
                 date for a meeting.};
end SchedulingSpec;

object SchedulingInfo is
  components: CommitteeName:GroupName, subject:Topic, Member:User,
              starttime:Time, endtime:Time, startdate:Date, enddate:Date,
              location:RoomId;
  operations: Search, Cancel;
  description: { This screen is used to search for common location, time and
                 date for a meeting.};
end SchedulingInfo;

object RoomDB is
  components: room:RoomInfo*;
  operations: ;
  equations: 
    var g: RoomDB; e, e':RoomInfo; 
    FindInRoomDB(EmptyDB(), e) == false;
    FindInRoomDB(AddtoRoomDB(g, e), e') == 
      if e = e' then true else Find(s,e');
    DeletefromRoomDB(EmptyDB(), e) == Empty;
    DeleteFromRoomDB(AddToRoomDB(g, e), e') ==
      if e = e' then DeleteFromRoomDB(g, e') 
      else AddToRoomDB(DeleteFromRoomDB(g , e'), e);
  description: {
	Collection of rooms that the scheduler has direct access to, which
	we'll refer to as ``local rooms''.  If room is not on this list, then
	its managed by some other agency than that running the calendar system
	(e.g., some campus room guru).
  };
end RoomDB;

object RoomInfo is
  components: location:RoomId, maximum:MaxOccupants, 
              lists:UnavailabilityList;
end RoomInfo;

object UnavailabilityList  is
  components: dandt:DateAndTime*;
  description: {List of time slots in which a room is not available};
end UnavailabilityList ;

object DateAndTime is
  components: mmddyy:Date, t:Time;
  operations: ;
  description: {};
end DateAndTime;

object RoomId is string;

object MaxOccupants is number;
 
object Priority is boolean;

object SetBrowseParam is
  components: subject:Topic, meetmin:MeetingMinutes, outcome:Decision,
              misc:Miscellaneous;
  operations: ;
  description: {};
end SetBrowseParam;

object Topic is string;

object MeetingMinutes is string;

object Decision is string;

object Miscellaneous is string;
 
object conflict is
  components: startime:Time, mmddyy:Date, location:RoomId;
  operations: ;
  description: {};
end conflict; 
 
object CommitteeName is string;
object size is number;







object SearchResults is
	components: d:Date,st:Time,et:Time,u:UserConflictInfo,m:MemberConflict*;
	operations: ;
	description:{*Gives a list of the location, date, time and users with
						the conflicts, with the least conflicts occurring first.
					*};
end SearchResults;

object MemberConflict is
	components: name:User,meetinginfo:SchedulingInfo*,endtime:Time,
					starttime:Time;

	description: {*Gives a list of the users with time conflicts pf meeting.
						It will also list the meeting time.
					*};
end MemberConflict;

object UserConflictInfo is
	components: t:Total, u:UserName*;
	operations: ;
	description:{*A list of the users with conflicts 
					*};
end UserConflictInfo;

object MinuteRecord is
	components: d:Date, st:Time,et:Time,Attendees:User*,m:MeetingMinutes;
	description:{*This is a list of the fields in the minute record, it will
						keep a record of the date, time both starting and ending
						as well as the attendess for the meeting database
					*};
end MinuteRecord;

object MeetingDB is
	components: m:MinuteRecord*;
	operations: ;
	description: ;
end MeetingDB;

object Total is integer;
object filesystem is string;
object dir is string;

object MeetingToBeScheduled is
   components: starttime:Time,endtime:Time, attendees:User*,
               CommitteeName:GroupName,subject:Topic,date:Date,location:RoomId;
   description: {* This object contains the information about a meeting that
                     has been scheduled but not yet taken place.
                  *};
end MeetingToBeScheduled;

object ConflictData is
   components: dateofconflict:Date, timeofconflict:Time, countofconflict:CountofConflict;
end ConflictData;

object ConflictList is
   components: cd:ConflictData*;
end ConflictList;

object CountofConflict is number;


{*****
******  OPERATIONS
*****}

function IsAlarmValid(alarm:AlarmInfo, ddb:DefaultsDB):  (boolean) =
        (appt.alarm.beepAlarm.value >= 0) and
        (appt.alarm.beepAlarm.value <= ddb.at)
             and
        (appt.alarm.mailAlarm.value >= 0) and
        (appt.alarm.mailAlarm.value <= ddb.at)
             and
        (appt.alarm.flashAlarm.value >= 0) and
        (appt.alarm.flashAlarm.value <= ddb.at)
             and
        (appt.alarm.popupAlarm.value >= 0) and
        (appt.alarm.popupAlarm.value <= ddb.at);

function IsApptValid(crit:ScheduledItem):  (boolean) = 
        (appt.startTime <= appt.endTime)
             and
        #appt.sum <= maxSummary (* num of characters allowed for a summary *)
             and
        #appt.desc <= maxDesc (* num of chars allowed for a description *)
             and
        IsAlarmValid(appt.alarm)
             and
        (appt.repeat.value >= 0) and (appt.repeat.value <= MaxRepeats);

operation EditDailyAppts is
    components: AddSchedItem, DelSchedItem, EditSchedItem;
    description: ;
end EditDailyAppts;

operation AddSchedItem is
    inputs: ds:DaySchedule, appt:ScheduledItem;
    outputs: ds':DaySchedule;
    precondition: 
        IsApptValid(appt)
             and
        not IsApptInSchedList(ds.schedList, appt);
    postcondition: IsApptInSchedList(ds.schedList, appt);
    description: {
        AddSchedItem inserts an appointment into the list of scheduled
        items for a day in a user calendar.
    };
end AddSchedItem;

operation DelSchedItem is
    inputs: ds:DaySchedule, appt:ScheduledItem;
    outputs: ds':DaySchedule;
    precondition: IsApptInSchedList(ds.schedList, appt) = true;
    postcondition: IsApptInSchedList(ds.schedList, appt) = false;
    description: {
        DelSchedItem deletes an appointment from the list of scheduled
        items for a day in a user calendar.  
    };
end DelSchedItem;

operation IsApptInSchedList is
    components: ;
    inputs: sl:ScheduledItem*, si:ScheduledItem;
    outputs: b:boolean;
    precondition: ;
    postcondition: si in sl;
    description: {
        IsApptInSchedList determines if a scheduled item is in the
        list of scheduled items for a day.
    };
end IsApptInSchedList;

operation EditSchedItem is
    inputs: ds:DaySchedule, appt:ScheduledItem;
    outputs: ds':DaySchedule;
    precondition: 
        IsApptValid(appt)
           and
        IsApptInSchedList(ds.schedList, appt);
    postcondition: IsApptInSchedList(ds.schedList, appt);
    description: {
        EditSchedItem edits an appointment in the list of scheduled
        items for a day in a user calendar.  
    };
end EditSchedItem;

operation FindSchedItem is
    inputs: ds:DaySchedule, t:Time;
    outputs: apptList:ScheduledItem*;
    precondition: ;
    postcondition:
        forall (si:ScheduledItem) (
            if (si in apptList) then (
                (si in ds.schedList) and (si.startTime = t) 
            )
        );
    description: {
        FindSchedItem returns a scheduled item if there is an appointment
        at the given time and day, returns a null scheduled item otherwise.
        Note, it is possible to have more than one scheduled item for a
        given time.  This may happen when a high priority meeting has been
        penciled in by the meeting scheduler.
    };
end FindSchedItem;

operation ChangeOptions is
    components: ChangeDayBoundaries, ChangeDefaultView, ChangeAlarmInfo; 
    inputs: u:User, uo:UserOptions;
    outputs: u':User;
    precondition: ;
    postcondition: 
        u'.opt = uo and
        u'.name = u.name and
        u'.pwd = u.pwd and
        u'.id = u.id and
        u'.groups = u.groups and
        u'.cal = u.cal and
        u'.m_alias = u.m_alias;
    description: {
        ChangeOptions allows options for a user to be modified, reset,
        or restored to their defaults.
    };
end ChangeOptions; 

operation ChangeDayBoundaries is
    inputs: uo:UserOptions, bound:DayBoundaries;
    outputs: uo':UserOptions;
    precondition: 
        (bound.startHour >= 0) and (bound.startHour <= 23)
            and
        (bound.endHour >= 0) and (bound.endHour <= 23)
            and
        (bound.startHour <= bound.endHour);
    postcondition:
        uo'.range = bound;
    description: {
        ChangeDayBoundaries modifies the day boundaries for a user's
        daily calendar view.
    };
end ChangeDayBoundaries;

operation ChangeDefaultView is
    inputs: uo:UserOptions, tu:TimeUnit;
    outputs: uo':UserOptions;
    precondition: ;
    postcondition:
        uo'.defView = tu;
    description: {
        ChangeDefaultView sets the default opening calendar view
        seen by a user to either daily, weekly, monthly, or yearly.
    };
end ChangeDefaultView;

operation ChangeAlarmInfo is
    inputs: uo:UserOptions, ai:AlarmInfo;
    outputs: uo':UserOptions;
    precondition: 
        IsAlarmValid(ai);
    postcondition: 
        uo'.alarm = ai;
    description: {
        ChangeAlarmInfo modifies the four types of alarms available
        to a user for reminding him or her of scheduled appointments.
        The four alarm types are: beep, flash, popup, and mail.
    };
end ChangeAlarmInfo;

operation ChangeToYearlyView is
    inputs: yrnum:YearNum, cal:UserCal;
    outputs: y:Year;
    precondition: ;
    postcondition: (y in cal.yearList) and (y.yr = yrnum);
    description: {
        ChangeToYearlyView changes the current calendar view for the
        user to the yearly view.
    };
end ChangeToYearlyView;

operation ChangeToMonthlyView is
    inputs: mn:MonthNum, y:Year;
    outputs: m:Month;
    precondition: ;
    postcondition: (m in y.monthList) and (m.mon = mn);
    description: {
        ChangeToMonthlyView changes the current calendar view for the
        user to the montly view.
    };
end ChangeToMonthlyView;

operation ChangeToDailyView is
    inputs: dnum:DayNum, m:Month;
    outputs: d:Day;
    precondition: ;
    postcondition: (d in m.dayList) and (d.daynum = dnum);
    description: {
        ChangeToDailyView changes the current calendar view for the
        user to the daily view.
    };
end ChangeToDailyView;

operation ChangeToWeeklyModel is
    inputs: date:Date, cal:UserCal;
    outputs: week:Day*;
    precondition: ;
    postcondition: ;
    description: {
        ChangeToWeeklyModel changes the current calendar view for
        the user to the 7-day model week corresponding to the Date input.
        The week that is displayed begins on the on the closest Monday
        on or before the inputted Date.  A model week contains a quick
        reference which shades busy hours during the week.
    };
end ChangeToWeeklyModel;

operation ChangeToWeeklySummary is
    inputs: yn:YearNum, mn:MonthNum, dn:DayNum, cal:UserCal;
    outputs: week:Day*;
    description: {
        ChangeToWeeklySummary changes the current calendar view for
        the user to the 7-day summary of the week corresponding to the
        Date input.  The week that is displayed begins on the on the
        closest Monday on or before the inputted Date.  A weekly summary
        contains a listing of the day summaries for the week.
    };
end ChangeToWeeklySummary;

operation NextYear is
    inputs: y:Year, uc:UserCal;
    outputs: y':Year;
    precondition: y in uc.yearList;
    postcondition: (y' in uc.yearList) and (y'.yr = y.yr + 1);
    description: ;
end NextYear;

operation PrevYear is
    inputs: y:Year, uc:UserCal;
    outputs: y':Year;
    precondition: y in uc.yearList;
    postcondition: (y' in uc.yearList) and (y'.yr = y.yr - 1);
    description: ;
end PrevYear;

operation NextMonth is
    inputs: month:Month, year:Year, uc:UserCal;
    outputs: month':Month;
    precondition: (month in year.monthList) and (year in uc.yearList);
    postcondition:  if (month.mon < 12 ) then
                       (month'.mon = month.mon + 1) and
                       (month' in year.monthList)
                    else
                       (month'.mon = 1) and
                       exists (m:Month)
                          (m in (NextYear(year, uc)).monthList) and
                          (month' = m);
    description: {
        NextMonth obtains the month which directly follows the
        inputted month.
    };
end NextMonth;

operation PrevMonth is
    inputs: m:Month, y:Year, uc:UserCal;
    outputs: m':Month;
    precondition: (m in y.monthList) and (y in uc.yearList);
    postcondition:  if (month.mon > 1 ) then
                       (month'.mon = month.mon - 1) and
                       (month' in year.monthList)
                    else
                       (month'.mon = 12) and
                       exists (m:Month)
                          (m in (PrevYear(year, uc)).monthList) and
                          (month' = m);
    description: {
        PrevMonth obtains the month which directly precedes the
        inputted month.
    };
end PrevMonth;

operation NextDay is
    inputs: day:Day, month:Month, year:Year, uc:UserCal;
    outputs: day':Day;
    precondition:(day in month.dayList) and (month in year.monthList) and
                 (year in uc.yearList);
    postcondition: if (day.date.dn = LastDayOfTheMonth(month)) then
                      (day'.date.dn = 1) and (day' in
                       (NextMonth(month,year,uc).dayList))
                   else
                      (day'.date.dn = day.date.dn + 1) and
                      (day' in month.dayList);
    description: {
	NextDay obtains the next day which directly follows the
	inputted day.
    };
end NextDay;

operation PrevDay is
    inputs: day:Day, month:Month, year:Year, uc:UserCal;
    outputs: day':Day;
    precondition:(day in month.dayList) and (month in year.monthList) and
                 (year in uc.yearList);
    postcondition: if (day.date.dn > 1) then
                      (day'.date.dn = day.date.dn - 1) and
                      (day' in month.dayList)
                   else
                      (day' in PrevMonth(month, year, uc).dayList) and
                      (day'.date.dn = LastDayOfTheMonth(day'.date.mn));
    description: {
        PrevDay obtains the day which directly precedes the
        inputted day.
    };
end PrevDay;

function LastDayOfTheMonth(mn:MonthNum): (n:number) =
    if (mn = 1 or mn = 3 or mn = 5 or mn = 7 or mn = 8 or mn = 10 or
     mn = 12) then
       31
    else if (mn = 2) then
       28  (* This isn't really true because it should be 29 for
              leap years. *)
    else
       30;

operation ImportExportMailAliases is
	inputs: udb:UserDB,gdb:GroupDB,ma:MailAlias,fs:filesystem,d:dir,ma:MailAlias;
	outputs: ma':MailAlias;
	precondition: Find(fs,d)=true; 
						(*We are assuming that a mail alias file in a UNIX based
						file system. In which case we are relying on this file to 
						update the mailing system for the calendar.  *)
	postcondition:  
						{* All modifications to the UNIX based file will affect mail
							aliases 
						*};
end ImportExportMailAliases;

operation MaintainUserDB is
	components:AddUsr,DelUsr,ModifyUsr,Cancel;
	inputs: udb:UserDB,id:UserId,u:User;
	outputs: udb':UserDB;
	description:{* Global Admin will be able to add and delete users from
						the user database 
					*};
end MaintainUserDB;

operation ModifyUsr is
	components: ;
	inputs: member:User, gdb:UserDB,committee:User;
	outputs: gdb':UserDB;
	preconditions: Find(gdb,Committee.commiteename) = true;
						{* We must find a user in order to modify.
						*}
	postconditions:Find(gdb',Commitee.committeename) = false;
						{* A member of the group changes status to group administrator
							and the previous group administrator changes status to 
							a member. 
						*}
end ModifyUsr;
	
operation AddUsr is
	inputs: udb:UserDB, u:User;	
	outputs: udb':UserDB;
	precondition:	Find(udb,u) = false;
						{* Searches the user database for a particular user as
							indicated in the second parameter, u, if it finds
							a match then you cannot add the same person twice to
							the user database.
						*}
	postcondition: Find(udb',u)=true;
						{* The user now exists in the user database 
						*}
end AddUsr;

operation DelUsr is
	inputs: udb:UserDB, u:User;	
	outputs: udb':UserDB;
	precondition:	Find(udb,u)=true;
		{* Searches the user database for a particular user as
		indicated in the second parameter, u, if it finds a
		match then that user can be deleted from the user
		database.
		*}	
	postcondition: Find(udb',u)=false;
		{* The user no longer exists in the user database. 
		*}
end DelUsr;

operation UpdateGroupDatabase is
	components:AddGrp,DelGrp,ModifyGrp,Cancel;
	inputs: g:GroupDB,gr:Group;
	outputs: g':GroupDB;
	description:{* The UpdateUserGroupDatabase will add groups, delete groups
			and modify group administrators from the group database.
	*};
end UpdateGroupDatabase;	

operation AddGrp is
   inputs: d:GroupDB, g:Group;
   outputs: d' :GroupDB;
   preconditions:Find(d, g) = false;
	{* Searches the group database for a particular group as
	indicated in the second parameter, g, if it finds
	a match then you cannot add the same group, twice to
	the group database.
	*}
   postcondition: Find(d',g)=true;
	{* The group now exists in the group database 
	*}
end AddGrp;


operation DelGrp is
   inputs: d:GroupDB, g:Group;
   outputs: d' :GroupDB;
   preconditions: Find(d, g) = true;
	{* Searches the group database for a particular group as
	indicated in the second parameter, u, if it finds a
	match then that group can be deleted from the group
	database.
	*}

   postcondition: Find(d',g)=false;
	{* The group no longer exists in the group database. 
	*}
end DelGrp;

operation ModifyGrp is
	inputs: member:User, gdb:GroupDB,committee:Group;
	outputs: gdb':GroupDB,committee':Group;
	preconditions: Find (gdb,Committee.committeename) = true	
						and 
		Find (Committee.GroupAdmin'.member) = false;
			{* Seaches the committee for the existing group as
			well as verifies that the member is not currently the
			group admin for that group
			*}
	postconditions:Find (Committee.GroupAdmin',member) = true;
			{*	The member is now the group administrator for a
			particular group.
			*}
end ModifyGrp;

operation ChangeDefaults is
    components: ;
    inputs: systemDefaults:DefaultsDB, newSettings:DefaultsDB, rdb:RoomDB;
    outputs: systemDefaults':DefaultsDB;
    precondition:
          newSettings.at >= 0 and
          newSettings.rt >= 0 and
          newSettings.defMeetingDuration.hr >= 0 and
          newSettings.defMeetingDuration.min >= 0 and
          newSettings.defStartTime.hr >= 0 and
          newSettings.defStartTime.hr <= 23 and
          newSettings.defStartTime.min >= 0 and
          newSettings.defStartTime.min <= 59 and
          newSettings.defEndTime.hr >= 0 and
          newSettings.defEndTime.hr <= 23 and
          newSettings.defEndTime.min >= 0 and
          newSettings.defEndTime.min <= 59 and
          newSettings.maxDate >= GetCurrentDate() and
          newSettings.maxSummary >= 0 and
          newSettings.maxDesc >= 0 and
          exists (r:RoomInfo)
             (r in rdb.room and r.location = newSettings.defLocation);
    postcondition: systemDefaults' = newSettings;
    description: {
          ChangeDefaults allows the global administrator to update
          the tunable parameters for the calendar system.
    };
end ChangeDefaults;

operation GetCurrentDate is
    components: ;
    inputs: ;
    outputs: mmddyy:Date;
    precondition: ;
    postcondition: ;
    description: {
        GetCurrentDate returns the current date.
    };
end GetCurrentDate;

operation Cancel is
  inputs: info:SchedulingInfo;
  preconditions: ;
  postconditions: {the meeting screen is canceled};
end Cancel;

operation SetAlarm is
  inputs: alarm:AlarmInfo;
  outputs: alarm:AlarmInfo, member:User;
  preconditions: {A meeting must have been scheduled};
  postconditions: {Alarms for the members of the group are set.};
end SetAlarm;

operation SetPriority is
  inputs: p:Priority;
  outputs: p:Priority;
  preconditions: p = false; 
                 (* A meeting has to have been scheduled *)
  postconditions: p = false 
                    or
                  p = true;
                 (* The priority of the meeting has been set for the members
                    of the group *)
end SetPriority;

operation AddToGroup is
  inputs: gdb:GroupDB, member:User, committee:Group;
  outputs: gdb':GroupDB;
  preconditions: FindInGroupDB(gdb, committee.member) = false;
                 (* The user is not in the database *)
  postconditions: FindInGroupDB(gdb', committee.member) = true
                  and
                   committee.size' = committee.size + 1;
                  (* the user has been added as a member of a group *)
end AddToGroup;

operation DeleteFromGroupDB is
  inputs: gdb:GroupDB, member:User, committee:Group;
  outputs: gdb':GroupDB;
  preconditions: FindInGroupDB(gdb, committee.member) = true;
                 (* User name must be in the group database *)
  postconditions: FindInGroupDB(gdb', committee.member) = false
                  and
                  committee.size' = committee.size - 1;
                  (* User name is removed from the database. *)
end DeleteFromGroupDB;

operation AddToRoomDB is
  inputs: rdb:RoomDB, room:RoomInfo, location:RoomId;
  outputs: rdb':RoomDB;
  preconditions: FindInRoomDB(rdb, room.location) = false
                  and
                 FindInRoomDB(rdb, room.maximum) = false
                  and
                 FindInRoomDB(rdb, room.lists) = false;
                 (* The room is not in the database *)
  postconditions: FindInRoomDB(rdb', room.location) = true
                  and
                  FindInRoomDB(rdb', room.maximum) = true
                  and
                  FindInRoomDB(rdb, room.lists) = true;
                  (* The room is added to the room database *)
end AddToRoomDB;

operation DeleteFromRoomDB is
  inputs: rdb:RoomDB, room:RoomInfo, location:RoomId;
  outputs: rdb':RoomDB;
  preconditions: FindInRoomDB(rdb, room.location) = true
                  and
                  FindInRoomDB(rdb, room.maximum) = true
                  and
                  FindInRoomDB(rdb, room.lists) = true;
                 (* Room must be in the RoomDB *)
  postconditions: FindInRoomDB(rdb', room.location) = false
                  and
                 FindInRoomDB(rdb', room.maximum) = false
                  and
                 FindInRoomDB(rdb', room.lists) = false;
                  (* Room is removed from the RoomDB *)
end DeleteFromRoomDB;

operation ModifyRoomInfo is
  inputs: rdb:RoomDB, room:RoomInfo;
  outputs: room':RoomInfo, rdb':RoomDB;
  preconditions: FindInRoomDB(rdb, room.location) = true
                  and
                  FindInRoomDB(rdb, room.maximum) = true
                  and
                  FindInRoomDB(rdb, room.lists) = true;
                 (* Room must be in the RoomDB *)
  postconditions: FindInRoomDB(rdb', room.location) = true
                  and
                  FindInRoomDB(rdb', room.maximum') = true
                  and
                  FindInRoomDB(rdb', room.lists') = true;
                  (* RoomInfo has been modified and placed back in RoomDB *)
end ModifyRoomInfo;

operation FindInRoomDB is
  inputs: rdb:RoomDB, room:RoomInfo;
  outputs: b:boolean;
  preconditions: ;
  postconditions: room in rdb;
end FindInRoomDB;
 
operation FindInGroupDB is
  inputs: gdb:GroupDB, committee:Group;
  outputs: b:boolean;
  preconditions: ;
  postconditions: committee in gdb;
end FindInGroupDB;


 (**SCHEDULER STUFF **)

operation Schedule is
  inputs:meetinginfo:SchedulingInfo, rdb:RoomDB, mdb:MeetingDB,
         committeename:GroupName, users:User, defaults:DefaultsDB,
         mwc:MemberConflict;
  outputs: results:SearchResults, room:RoomDB, mdb:MeetingDB, members:User;
  precondition: forall (attendee:User) attendee in udb.userList and
                meetinginfo.starttime < meetinginfo.endtime and
                meetinginfo.startdate < meetinginfo.enddate and
                meetinginfo.location in room;

   { Attendees must all be registered users
      If given, start time must be before end time
      Ditto for start/end dateD
      If given, loc must be in Cal room db
    }
   postcondition: 
      if (  UsersCanAttend(results,meetinginfo) and
         StartTimeAndDateAreNearest(results,users) and
         AttendeesCorrect(results,meetinginfo,MtgTbSched) and
         TimeRangeMet(results,meetinginfo) and
         DateRangeMet(results,meetininfo) and
         LocationMet(results,meetinginfo))then true
      else
         FindUserTimeConflict(results,meetinginfo,MtgTbSched);
            

   
  description: {
   Among other constraints, if a room cannot be found for a meeting, but a
   time can, then the location field of the outputs is left as ``call for
   room'', meaning the that human scheulder needs to ask for a room
   through some other agency.  The idea is that we'll schedule a meeting
   if a time can be found, whether or not we can find a local room.
  }
end Schedule;

function FindUserTimeConflict(meetinginfo:SchedulingInfo,results:SearchResults,
                          MtgTbSched:MeetingToBeScheduled) : (MemberConflict) =
 
 
  forall (meetinginfo: SchedulingInfo) 

     if(meetinginfo.attendees.cal.yearList.monthList.dayList.daySched.schedList.
         startTime ~= empty) then
       if (meetinginfo.attendees.cal.yearList.monthList.dayList.daySched.
           schedList.starttime <= MtgTbSched.starttime) and
          (meetinginfo.attendees.cal.yearList.monthList.dayList.daySched.
           schedList.starttime > MtgTbSched.starttime) then

         mc.uname.name = meetinginfo.attendees.name and
         mc.mi.startdate = meetinginfo.startdate and
         mc.mi.edddate = meetinginfo.enddate and
         mc.st = meetinginfo.cal.yearList.monthList.dayList.daySched.schedList.
               starttime and
         mc.et = meetinginfo.cal.yearList.monthList.dayList.daySched.
                 schedList.endtime
      
      else if (meetinginfo.attendees.cal.yearList.monthList.dayList.daySched.
          schedList.endtime > MtgTbSched.starttime) and 
         (meetinginfo.attendees.cal.yearList.monthList.dayList.daySched.
          schedList.endtime <= MtgTbSched.endtime) then

         mc.uname.name = meetinginfo.attendees.name and
         mc.mi.startdate = meetinginfo.startdate and
         mc.mi.edddate = meetinginfo.enddate and
         mc.st = meetinginfo.cal.yearList.monthList.dayList.daySched.schedList.
               starttime and
         mc.et = meetinginfo.cal.yearList.monthList.dayList.daySched.
                 schedList.endtime;
         

function TimeRangeMet(results:SearchResults, meetinginfo:SchedulingInfo,
                      defaults:DefaultsDB): (boolean) =


   if (results.starttime ~= empty) then
      results.starttime >= meetinginfo.starttime
   else if (results.starttime = empty) then
      results.starttime >= defaults.endtime
   else if (results.endtime ~= empty) then
      results.endtime <= meetinginfo.endtime
   else if (results.endtime = empty) then
      results.endtime >= defaults.endtime 
      
   else true;

function DateRangeMet(results:SearchResults,meetinginfo:SchedulingInfo,
                      defaults: DefaultsDB) : (boolean) =

   if (results.startdate ~= empty) then
      results.startdate >= meetinginfo.startdate
   else if (results.startdate = empty) then
         results.startdate >= defaults.startdate 
   else if (results.enddate ~= empty) then
      results.startdate <= results.enddate
   else if (results.enddate = empty) then
         results.enddate >= defaults.startdate 
   else true;


function LocationMet(results:SearchResults,meetinginfo:SchedulingInfo,
                     defaults:DefaultsDB) : (boolean) =

(* Checks to see if the room is exists in the room database, and returns
true  if it does. If a room is not specified, true is returned in case
the scheduler wants to know if people can meet
*)

   if (results.location ~=  empty) then
       results.location = meetinginfo.location
   else  
       true;
   

function AttendeesCorrect(results:SearchResults,meetinginfo:SchedulingInfo,
                  udb:UserDB,MtgTbSched:MeetingToBeScheduled): (boolean) =

(* Checks to see that the attendees are valid by verification with the 
user database 
*)
                           
   forall (MtgTbSched:MeetingToBeScheduled) 
      (MtgTbSched.attendees in udb) and
      (MtgTbSched.attendees in meetinginfo.Members);



function UsersCanAttend(results:SearchResults,
                        MtgTbSched:MeetingToBeScheduled,users:User,
                        meetinginfo:SchedulingInfo) : (boolean) =

(* Checking to see if the start time and stop times are valid *)
   
   forall (MtgTbSched: MeetingToBeScheduled)
         if((MtgTbSched.attendees.cal.yearList.monthList.dayList.daySched.schedList.
            startTime) ~= empty) then

               (MtgTbSched.attendees.cal.yearList.monthList.dayList.daySched.   
                     schedList.starttime < meetinginfo.starttime and
                MtgTbSched.attendees.cal.yearList.monthList.dayList.daySched.   
                     schedList.endtime <= meetinginfo.starttime)

                             or 

         if((attendees.cal.yearList.monthList.dayList.daySched.schedList.
            startTime) ~= empty) then

               (attendees.cal.yearList.monthList.dayList.daySched.   
                     schedList.starttime >= meetinginfo.starttime and
                   attendees.cal.yearList.monthList.dayList.daySched.   
                     schedList.endtime > meetinginfo.starttime);


6. Appendix A: Preliminary Users Manual

Appendix A: Preliminary Users Manual

I. Introduction

WELCOME TO FAB FIVES CALENDAR MANAGER.

TABLE OF CONTENTS:

A. Pictorial Overview

B. User

C. Group Administrator

D. Global Administrator

E. Super User

    A. Top-Down View of Calendar Manager:

B. User

As the user first screen you encounter is the yearly view of a calendar There are three options view,edit and browse that the user may click on. When the user selects 'view' they have the following viewing options:

VIEWS:

The yearly view allows the user to view one year at a time. The current day will be boxed. By clicking on a particular day, one is allowed to zoom in on a particular day. The edit button allows the user to modify the daily appointment calendar.

The monthly view allows a user to glance an entire month along with the brief comments of each day's schedule. It is possible for example to zoom in on April 6, enter some text about a particular event for later reference. There is also the flexibility to few the next month or the previous month by clicking on the right or left arrow buttons respectively.

The weekly view allows a user to glance one week at a time, giving more detail about each day's event. For instance, Thursday, April 21, there are 4 items scheduled for that day. Notice how the Staff Meeting is scheduled from 1:30pm to 3:00pm and italicized as being unconfirmed. This means that the user must send email to this party confirming that they can make it for the meeting. It is essential that the user respond to via email, to confirm the meeting time.

EDIT:

DATE AND TIME:

The appointment editor allows the user to enter their daily schedule for that particular day. A valid date for a meeting must be entered or the system will reject that appointment. The start time can be chosen by clicking on the left arrow button, this will bring up a selection of times from which the user can select a start time. The am/pm button must also be selected. The same method is used when selecting the end time, but it must be scheduled after the end time.

ALARM SETTINGS:

Notice that there are several "bells and whistles" that the user has at their disposal. For example, the alarm settings. A user maybe wish to have their computer to beep at them to warn them of a specific event. The beep button provides this option. These intervals can be specified as in minutes, hours or days. The button flash performs the same functions as the alarm, except that the screen will flash at you at the interval you set for a particular event. PopUp allows for an event to be displayed on your computer regardless if you are in the calendar or not. If the reminder pops up on your screen, the user may remove it by clicking on the button 'OK'. This like a reminder utility that was built in so that the user will can be reminded of an important meeting. The mail button allows you to be verified of new mail during specific intervals, which the user can set.

PRIVACY:

The next buttons involve the privacy issue. One can either choose their daily activities to be visible to the public or restricted to certain people. The three options to choose from are:

These three hierarchies form the security for calendar manager.

Lets take a time slot from 10am - 12pm on 4/21/94. By clicking on public when this particular time is highlighted in the day summary this meeting will be made visible to all users.

By clicking on busy this marks this particular time slot as being "unavailable" during the time slot of 5pm to 6pm on 4/21/94. No one else can view the information for those particular hours.

By clicking on private this marks this particular time slot as being visible only to those members that the users is in. This slot will be readable by the other members of the group, but will not be visible to any other users outside the group.

REPEAT:

By clicking on the down arrow, the user can choose to repeat this particular meeting for several weeks, months, or years. This avoids the redundancy of having to re-entering the same meeting everyday.

FOR:

By clicking on the down arrow you can specify the duration of weeks, months, years that this particular meeting will be scheduled for in the future.

Notice that as you schedule a time and mark it as public, busy or private, it is listed on the day summary according to chronological time. A brief description of that particular appointment maybe entered. The remarks for the day are a brief description of the day's event.

On the bottom of that screen, the user has the ability Insert, Delete, Change, Clear or Quit.

From the main screen, the user can choose to change their preferences. This option is available through the edit pulldown for the main view of the calendar.

EDIT:

DISPLAY SETTINGS:

The Display Settings can be modified so that the length of a work day can be modified. One can also modify the default view when the calendar manager is first invoked. These settings can be applied to a year, month, week, or day view.

EDIT:

Edit defaults are those in which the various alarm intervals can be modified.

The user has the ability to instantly apply the modifications that have been made, reset the values or invoke the defaults of the users previous defaults.

BROWSE:

By clicking on "user calendar" in the browse utility, another screen will pop up with a list of users and their email addresses. In this case bwallace@galaxy.csc.calpoly.edu is highlighted. At the bottom of the screen it displays:

User Selected: bwallace@galaxy.csc.calpoly.edu

By clicking on the View Calendar button, one can view all the public information in bwallace's calendar. A user can glance at bwallace's daily, weekly, or monthly schedule and see what events the person has scheduled for each day of that particular week. Note that on Thursday, April 21, from 10am to 3pm, this area is shaded out. This person is busy at those particular time intervals.

BROWSE:

By selecting Group Meetings under the browse utility, another screen appears in which several groups are listed.

At the bottom of the screen it displays:

Group Selected: SLOSoft Software Design Team

By clicking on the group name, another screen will be displayed will all the public information about that particular meeting. If you are a member of this group, then you have unrestricted access to all information of this meeting. In this screen the groups name, date, location, start and end times, topic, minutes and attendees are displayed for viewing. In the top right corner, one has several options:

C. GROUP ADMINISTRATOR

The group administrator has all the same privileges as a user plus some more. One of the most critical jobs as a group administrator is scheduling meetings between members of the same group.

SCHEDULE MEETINGS:

When this button is pressed from the Group Adminstrator Menu, we are transferred to the Group Meeting Scheduling Window. Notice that there is several pieces of information that needs to be filled in.

GROUP NAME:

It is absolutely essential that a group name be selected, by clicking on the down arrow on the right side of the group name, the group administrator may select a group that he/she wishees to schedule. If a group name is not entered, then an error message will appear, stating that a group name is missing or cancel the scheduling at this time. Once a group name is selected, the members of that group appear in the box below labeled: Members.

TOPIC:

In this field text maybe entered specifying the nature of the meeting, this is optional data.

DURATION:

By clicking on the right down arrow button, the administrator can specify the duration of a meeting. If no duration is entered, a default value is used, in this case 1 hour.

START TIME:

If this time is left blank, then a time beginning at this very instant is selected. Otherwise, a time maybe selected by clicking on the left down arrow button. The am/pm button must also be selected or the system will display an error message.

END TIME:

If this time is left blank, the start time plus the duration time will become the end time for that meeting. Otherwise, a time maybe selected by clicking on the left down arrow button. The am/pm button must also be selected or the system will display an error message.

START DATE:

If the start date is left blank, then today's date will be used as the default date. A start date maybe specified by selecting the month, day and year buttons.

END DATE:

If the end date is left blank, then today's date will be used as the default date. An end date maybe specified by selecting the month, day and year buttons.

LOCATION:

If a room location is not specified then the default location will be used. A location maybe selected by clicking on the down arrow and a list of rooms will be displayed.

SEARCH:

Once all this criteria has been selected, then click the search button, this will perform a search of those times selected with the members of the group. If the administrator wishes to cancel, then they may click on the cancel button and be returned to the initial group administrator's window.

The search button returns another window with the group name, topic, members and the start time, end time, date and location of the meeting to be scheduled.

PRIORITY:

One important note to consider is the use of the priority button. If the administrator chooses Yes, then this meeting becomes mandatory. All members' calendars will be overwritten with this meeting time, if there was a meeting at that time, it will be saved above the priority meeting. If No is selected this meeting will be schedule those users who are available. It will "pencil in", the meeting time on each users calendar and mark it as unconfirmed. Unconfirmed implies that the user must respond via email that he or she will be attending the meeting. *Note that this was seen in the user's weekly view.

If all members of a meeting have been preliminary scheduled, then a screen will appear implying that a meeting has been scheduled. Should conflicts arise, the user, date, start/end time of the meeting and start/end time of the conflict will be displayed in chronological time order. The administrator may wish to schedule the meeting as it, reschedule the meeting or cancel the scheduling. By rescheduling the window the administrator is taken back to the initial group meeting scheduling window.

A sample of the conflicts window :

IMPORT MINUTES AND ATTENDEES:

Once a meeting has passed, the meeting minutes and attendees, meeting date and group name which are stored else where in a text file. The administrator has access to a template which they use to import the minutes and attendess into, and this template allows them to mark the following meeting information as public or private:

D. GLOBAL ADMINISTRATOR

The Global administrator has the same calendar views as a typical user but there is one difference. The Global and Group administrators have an additional button on their calendar called the "Admin" button. When pressed another screen pops up called the "Global Administration Menu". The options of this window are: "Update User Database", "Update Group Database", "Update Room Database", "Import/Export Mail Aliases", "Change System Settings", "Schedule Meetings", "Import Minutes and Attendees", and "Quit". The following is a general description of the functions performed by each:

UPDATE USER DATABASE:

When this button is pressed, the update user database screen appears. With this screen the Global Administrator could add, delete, or modify a user in the User Database(UDB). The screen has a list of current users in the "Current Users" window and the scroll bar can be use to scroll down and select a user. If this is done the users name and userid will appear in the upper portion of the screen. This can also work in the other direction. If the users name and/or userid is type into the screen, the system will highlight that name in the Current Users window.

If this person just entered is to be added then simply click the "Add" button and the system will figure out a unique userid for that person. But if this person is to be deleted, then the Highlighted name in the Current User screen will disappear and will also be gone from the "Name of User" field.

To modify a user, just select the name or type in the name of the user. Let's say the users last name and id must be changed. All one needs to do is type in the new last name and id into their prospective fields and click the "Modify" button. This will automatically change the users name in the UDB.

The "Cancel" Button will bring back the "Global Administration Menu" to the screen so that you can make another selection.

UPDATE GROUP DATABASE:

With this screen, the Global Administrator could add a group by typing the new name of the group into the Group slot in the upper window. The Global Administrator is then entered along with the user id. Then hit add and that group will be entered into the Group database.

To delete a group from the database, the Global Administrator just has to type the name of the group or select the group out of the "Existing Groups" window. If you type in the name of the group or select it and the group exists,the Group Administrator and that persons user id will be in the window. Clicking on "Delete" will remove the group from the group database.

Modifying a group is just as easy. The Global Administrator could either type the name of the group or select it inthe the "Existing Group" window. Then the group name could be changed or the group administrator could be changed.

The Global Administrator could also add and delete member of the group. Click on the "Update member list" button by the "Current user" screen and select the member that is to be deleted from a group. Press the Delete button and that person is deleted from the that particular group. To add a member to a group, select the group the member is to join and then press the "Update member list". Type in the new members name and then press add and the new member is in the group.

UPDATE ROOM DATABASE:

Adding a room to the Room Database is done by typing the building id and the room number into the "Room Location" field. Then type in the Maximum Occupancy of that room. If the "Add" button is selected, that room will be added to the room database.

To delete a room the administrator highlights the room to be removed in the scroll window, then clicks on the "Delete" button.

Modifying a room entry in the room database is done in a similar way. The user highlights the appropriate room in the scroll window, then selects "Modify". A cursor will move to that entry allowing modifications to be made.

Selecting "Cancel" will allow the user to leave the screen without modifying the room database.

IMPORT/EXPORT MAIL ALIASES:

Essentially, in order to create mail accounts for existing users on the UNIX based mainframe, the global administrator will simply click on the "Import/Export Mail Alias" button. The system will search for all user's who have an account and will automatically set up all mail information for each user. This information will consist primarily of a mail alias for the user (the alias will usually be the user's login name). Once this has been done, group aliases can be created by adding individual alias names to a name for the entire group in the file /usr/lib/aliases from the root directory of the UNIX system. A typical group alias entry might be: grp_admins:mlow,mpereira, bwallace,owallace,dragsdal. This would define the group alias name "grp_admins"which consists of user the alias names "mlow","mpereira", ect. . It is important to note that neither the user, nor even the global administrator sees any of the conversion take place. Simply put, the calendar merely uses the mail aliases' that previously exist on the UNIX system to ensure that the two are consistent and that the UNIX mail system can be used inside of the calendar. All modifications regarding mail alias files are in the hands of a UNIX administrator and are not the responsibility of the calendar's global administrator. Having the system set up this way will allow the calendar's administrator to avoid the unnecessary work of having to re-enter all user's into a new database.

CHANGE SYSTEM SETTINGS:

The global administrator has the capability to change all default settings for certain meeting information. These default settings will be used whenever particular information is left blank. For example, if a group administrator is scheduling a meeting for his group and does not enter a meeting start time, the default setting set by the global administrator will be used. To change any one of the listed settings, the user simply clicks on the desired field. The cursor then appears on the line of the corresponding field to be changed and modifications can then be made.

It is critical that the global administrator enter valid values for each setting that he modifies. For example, the default end time for a meeting search should not be a value earlier than the default start time. Invalid entries such as this will warn the user of the problem, but only when the default settings are used. As a result, if the global administrator enters invalid default settings all group administrators attempting to schedule using these values will get an error message. Therefore, to save substantial time and complications, the global administrator should take great care in assuring that all default value settings are correct.

SCHEDULE MEETINGS:

The "Schedule Meetings" operation act exactly like the "Schedule Meetings" button for a group administrator.

INPUT MINUTES AND ATTENDEES:

This button works exactly the same as that used by a group administrator.

QUIT:

The "Quit" button allows the global administrator to leave the screen and return to the normal user calendar view.

E. SUPER USER

The Super User has unrestricted access to all user information, whether it is private, public or busy. This access is justifiable in cases of emergencies where files have been corrupted or some unexpected catastrophe has occurred. The super user is merely an "overseer" to the entire system. The super user will login periodically to ensure the system is running efficiently.