(******

* Module File defines the objects and operations relate to file
* processing in the grader system.
******)

object FileSpace is File*
   description: (* 
      A FileSpace is an abstract model of a file space in the 
      operating environment in which the grader tool is run.
   *);
end;

object File is 
   components: name:FileName and permissions:FilePermissions and
      file_type:FileType and data:FileData;
   description: (*
      A File is an abstraction of a file stored in the file 
      space.
   *);
end File;
-- IS CURRENT TAG?

object FileName is string
   description: (*
      The name of a file. The string representation is an
      abstraction of file names used in specific operating
      environments. 
   *);
end;

object FilePermissions is
      is_readable:IsReadable and
      is_writeable:IsWritable
   description: (*
      FilePermissions indicate whether a file is readable and/or
      writable.
*);
end;

object IsReadable is boolean
   description: (*
      Flag indicating whether a file is readable, which is 
      required to be true during FileOpen.
*);
end;

object IsWritable is boolean
   description: (*
      Flag indicating whether a file is writable, which is 
      required to be true during FileSave.
*);
end;

object FileType is
      grader_type:GraderType or
      other_type:OtherType
   description: (*
      The type of file data is either GraderType data or any 
      other type of data
*);
end FileType;

object GraderType 
   description: (*
      File data typeing tag indicating that a file contains
      grader data created by the Grader Tool.
*);
end GraderType;

object OtherType
   description: (*
      File data typing tag indicating that a file contains data
      other that grader data created by the grader tool.
*);
end OtherType;

object FileData is Class
   description: (*
      The abstract representation of grader-type FileData is a
      Class object. Grader Tool implementors may use any 
      concrete file data rep that accurately holds Classes.
*);
end FileData;

operation FileNew is 
    inputs: uws:UserWorkSpace;
    outputs: uws':UserWorkSpace;

    description: (*
       Add a new Class to the workspace and make it current.
*);
    precondition: ;
    postcondition: 
       (*
        * The output workspace has a new Class and that Class 
        * is current. 
        *)
       uws'.gradebooks[1] = nil;
           -- make it current
end FileNew;

operation FileOpen is
   inputs: fs:FileSpace, fn:FileName, uws:UserWorkSpace;
   outputs: uws':UserWorkSpace;

   description: (*
      Open an existing class file of the given name and put
      the data from that file in the workspace.
   *);

   precondition: 
      (*
       * A file of the given name exists in the given file space
       * the file is readable, and the file's data are grader 
       * type
       *)
      exists (file in fs)
         (file.name = fn) and
         file.permissions.is_readable and
         file.file_type?grader_type;

   postcondition: 
      (*
       * The output workspace has a new Class containing the
       * data of the input file, and that Class is current. 
       *)
        exists(f:File)
            exists(f in fs)
                f.name = fn and f.data = uws'.gradebooks[1];

end FileOpen;

operation FileClose is
   inputs: uws:UserWorkSpace;
   outputs: uws':UserWorkSpace;
   description: (*
      Close the current Class if it does not require saving.
   *);
   precondition:
      (*
       * The Class does not require saving.
       *)
      not (uws.gradebooks[1].requires_saving);
   postcondition:
      (*
       * The current class is deleted from the workspace. 
       *)
      (not (uws.gradebooks[1] in uws'.gradebooks)) ;

end FileClose;

operation FileSave is
   inputs: fs:FileSpace, uws:UserWorkSpace;
   outputs: fs':FileSpace, uws':UserWorkSpace;
   description: (*
      If the class in the given workspace requires saving, save
      it in the given file space.
   *);
   precondition:
      (*
       * The given workspace requires saving and is writable
       *)
      (uws.gradebooks[1].requires_saving) and 
      (uws.gradebooks[1].permissions.is_writeable); 
   postcondition: 
      (*
       * There is a grader-type file in the resulting FileSpace
       * containing the current workspace class as its file data
       * In the resulting workspace, the requires saving 
       * indicator is false
       *)
      (exists (file in fs')
         (file.data = uws'.gradebooks[1])
         
      );
end FileSave;