(****
 *
 * Module InstructorDB defines the major Instructor database objects of the scheduling tool.
 *
 *)

module InstructorDB;

from InstructorPref import InstructorPref;
export InstructorDB;
export all;

  
  object InstructorDB
    components: InstructorEntry*;
    description: (*
        The InstructorDB is the database for each schedule.  It contains all
        of the avaiable instructors    
    *);
  end;

  object InstructorEntry
  	 components: instructorpref:InstructorPref and disabilities:Disabilities and firstname:FirstName and lastname:LastName and department:Department and 
    deptofficenum:DeptOfficeNum and email:EMail and wtus:WTUs and notes:Notes;
  	 description: (*
  	 		The InstructorEntry object consists of the instructor's preferences, any diabilities, their 
         first and last name, department, office number, e-mail, available WTUs, and any notes.
  	 *);
  end;
  
  object Disabilities
  	 components: mobility:Mobility and vision:Vision and hearing:Hearing and dexterity:Dexterity;
  	 description: (*
  	 		The Disabilities object has the disabilities that an instructor can be classified under.
  	 *);
  end;
  
  object FirstName = string;
  object LastName = string;
  object Department = string;
  object DeptOfficeNum = string;
  object EMail = string;
  object WTUs = integer;
  object Notes = string;
  
  object Mobility = boolean;
  object Vision = boolean;
  object Hearing = boolean;
  object Dexterity = boolean;

operation AddEntry
    inputs: idb:InstructorDB, ie:InstructorEntry;
    outputs: idb':InstructorDB;
    description: (* This operation adds an instructor entry to the instructor 
    database.*);

    precondition:
        (*
         * There is no record in the input InstructorDB with the same name and email address as the
         * record to be added.  The Department, instructor Number, and WTUs must not be empty.
         *)
        (not (exists (ie' in idb) ie'.firstname = ie.firstname and ie'.email = ie.email and ie'.lastname = ie.lastname))
	and
	ie.email != nil and ie.firstname != nil and ie.lastname != nil and ie.wtus != nil;

    postcondition:
        (*
         * A instructor entry is in the output db if and only if it is the new
         * record to be added or it is in the input db.
         *)
        forall (ie':InstructorEntry)
           (ie' in idb') iff ((ie' = ie) or (ie' in idb));

  end;

  operation RemoveEntry
    inputs: idb:InstructorDB, ie:InstructorEntry;
    outputs: idb':InstructorDB;
    description: (* This operation removes an entry from the instructor 
    database.*);
    precondition: (* The entry is in the database*)
    (ie in idb);
    postcondition: (* The entry is not in the database, but all other entries are still there *)
    (forall (ie':InstructorEntry)
            (ie' in idb') iff ((ie' != ie) and (ie' in idb)));

  end;

  operation ChangeEntry
    inputs: idb:InstructorDB, oldIE:InstructorEntry, newIE:InstructorEntry;
    outputs: idb':InstructorDB;
    description: (* This operation removes the old entry and adds a new entry to the database.*);

    precondition: (* Old entry must exist in the database, don't care if the new entry is the same as the old one.  Also, same conditions as adding
    * a new entry *)
    (oldIE in idb) and newIE.email != nil and newIE.firstname != nil and newIE.lastname != nil and newIE.wtus != nil;

    postcondition:
                 (*The old entry does not exist, the new entry does exist, and the other entries are still in there *) 
    (forall (ie':InstructorEntry)
            (ie' in idb') iff ((ie' != oldIE) and ((ie' in idb) or (ie' = newIE))));
  end;

end InstructorDB;