(*Student Feedback*)

module Feedback;
	from Time import TimePeriod;
	from ScheduleM import Schedule, ScheduleList, Term;
	from Database import course;
	
	export all;


	object NotEnoughSections is
	    components: b: boolean;
	    description: (* Whether or not the student stated that there weren't not enough sections of the course. *);
	end NotEnoughSections;

	object ClassRequests is
	    components: tp: TimePeriod;
	    description: (* The days that the student requested more classes, and the times as well if the student selected any. *);
	end ClassRequests;

	object AdditionalComments is
	    components: s: string*;
	    description: (* The additional comments that the student entered in the "Additional Comments" text box. *);
	end AddtionalComments;




	object FeedbackObject is	    
	    components: t: Term and c: course and nes: NotEnoughSections and cr: ClassRequests and ac: AdditionalComments;
	    description: (* A FeedbackObject has a Term. If it is for specific course, it has a Course.
                  	    If the student said that there weren't enough sections, then it contains NotEnoughSections.
            	            If the student gave the days or days and times that they wanted the class, then it has ClassRequests.
      	                    If it is a general comment or if the student gave additional comments, then it has AdditionalComments.
      	                    Those values that it does not have are nil. *);
	end FeedbackObject;





	operation GetFeedback is
	    inputs: sl: ScheduleList, fo: FeedbackObject;
	    outputs: sl': ScheduleList; 
	    precondition: sl != nil and sl.s != nil  (* The Schedule List must contain at least one schedule. *) and
	    	          fo != nil  (* There must be a feedback object. *) and
	    	          fo.t != nil  (* The feedback object must have a term. *) and
	    	          (
	    	           if (fo.c != nil)  (* If the feedback is for a specific course, then.... *)
	    	                   
	    	           then (fo.nes != nil or fo.cr != nil or fo.ac != nil)  (* there must actually be feedback of some kind. *)
	    	                   
	    	           else (fo.nes = nil and fo.cr = nil and fo.ac != nil)  (* Else if the feedback is a general commment, for the
	    	                                                                    term as a whole, then the feedback object must have
	    	                                                                    additional comments and no other kind of comments. *)
	                  );
	    postcondition: exists (s in sl'.s) fo in s.fo and  (* There exists a schedule s in the outuput schedule list (sl')
	                                                            such that there is a feedback object (fo') in it that is
	                                                            equal to the input feedback object (fo). *)
	                   
	                   (forall (s2:Schedule | s2 != s)  (* There is exists a schedule s2 that is not the schedule s such that.... *)
	                    
	                    if (s2 in sl.s)  (* If the schedule s2 was in the input schedule list sl,then.... *)
	                    
	                    then (s2 in sl'.s) (* it must be in the output schedule list sl'. *)
	                    
	                    else not (s2 in sl'.s) (* Else if schedule s2 was not in the input schedule list (sl), then it is
	                                              not in the output schedule list (sl'). *)
	                   );
	    description: (* The info for the FeedbackObject is gotten from the user and added to a schedule in the
	                    schedule list (whichever schedule the user commented on). *);
	end GetFeedback;
end Feedback;