module Tools;

(****
* Module Tools contains all the operations for the Tools menu bar used with the  
* private and public layers for both the instructor and student versions.
*)

from View import Layer, Enabler, PrivateLayer, PublicLayer, Shape;

from InstructorVersion import LectureLayer;

object PostItLog is
     components:  pi:PostIt* and count:PostItCount;
     description: (* A PostItLog is composed of a list of PostIts and a counter for the total number of PostIts. *);
end PostItLog;

object PostIt is
     components:  number:PostItNumber and note:PostItNote and select:Selected;
     description: (* A PostIt is composed of a PostItNote and a PostItNumber and an object, Selected, to show that the tool has been selected. *);
end PostIt;

object PostItNumber is integer;

object PostItNote is string;

object PostItCount is integer;

object Selected is boolean
     description: (* Selected is used to determine whether a tool has been turned on or off. *);
end Selcted;

operation MakePostIt is
     inputs:  newPostIt:PostIt and log:PostItLog;

     outputs:  log':PostItLog;

     preconditions:  newPostIt.select = true and

    			private.enable=true xor public.enable=true and 

			lectureLayer.enable=true and

			newPostIt.note!=nil and

			forall(newPostIt' in log) newPostIt'.number!=newPostIt.number;

     postconditions:  log'.count=log.count+1 and

			newPostIt'.number=log'.count and

			newPostIt'=newPostIt and

			private'!=private xor public'!=public;

     description: (* To add a newPostIt to the log, the post it data can't be empty and the private or public layer it corresponds to must be enabled as well as the lecture layer. *);
end MakePostIt;

object FreehandLine is
     components: lineWidth:LineWidth and color:Color;
     description: (* A FreehandLine consists of a LineWidth and Color. *);
end FreehandLine;

object LineWidth is integer
     components: select:Selected;
     description:  (* LineWidth can be one of five possible sizes (1 through 5).*);
end LineWidth;

operation SelectLineWidth is
     inputs: lineWidth:LineWidth;

     outputs: lineWidth':LineWidth;

     preconditions: lineWidth.select = true;

     postconditions: lineWidth'.select = false;

     description: (* This operation sets the line width if the tool is selected and after the line width is set the tool is deactivated. *);
end SelectColor;

object Color is
     components: select:Selected;
     description: (* Color is an abstract object and must be selected to be used. * );
end Color;

operation SelectColor is
     inputs: color:Color;

     outputs: color':Color;

     preconditions: color.select = true and whichTool.select = true;

     postconditions: color'.select = false;

     description: (* This operation sets the color to whichever the user selects if the color tool is selected and once a color is set the tool is deactivated. Note that the color for the eraser tool can not be changed and is always clear. *);
end SelectColor;

object SelectionBox is
     components: height:Height and width:Width and boxContent:Content and select:Selected and shape:Shape;
     description:  (* A SelectionBox consists of a Shape, a Height, and a Width, and must be selected to be used. *);
end SelectionBox;

object Content is
     description: (* This is an abstract component that basically takes a screen shot and is just an image. *);
end Content;

object Height is integer;

object Width is integer;

operation DrawSelectionBox is
     inputs: box:SelectionBox;

     outputs: box':SelectionBox;

     preconditions: box.boxContent=nil and box.length=0 and box.width=0 and box. select=true and box.shape=nil;

     postconditions: box'.select=false and box'.boxContent=box.boxContent and box'.shape=box.shape;

     description: (* A selection box is drawn if the selection box tool is selected. *);
end DrawSelectionBox;

object Pencil inherits from FreehandLine
     description: (* A Pencil is composed of a FreehandLine object with a default LineWidth(=1) and Color(=black). *);
end Pencil;

object Highlighter inherits from FreehandLine
     description: (* A Highligher is composed of a FreehandLine with a default LineWidth(=2) and Color(=yellow). *);
end Highlighter;

object Eraser inherits from FreehandLine
     description:  (* An Eraser is composed of a FreehandLine with a default LineWidth(=2) and default Color(=clear). *);
end Eraser;

object WhichTool is 
     components: select: Selected and shape:Shape and pencil:Pencil or highlighter:Highlighter or eraser:Eraser;
     description: (* WhichTool is composed of one of three tools: pencil, highlighter, or eraser. *);
end WhichTool;

object WhichLayer is 
     components: private:PrivateLayer or public:PublicLayer;
     description: (* WhichLayer identifies the layer that will be drawn on. *);
end WhichLayer;

operation Draw is
     inputs: whichTool:WhichTool and whichLayer:WhichLayer;

     outputs: whichLayer':WhichLayer;

     preconditions: whichTool.shape=nil and whichTool.select=true and private.enable=true xor public.enable=truel;

     postconditions: whichTool'.shape=whichTool.shape and private'!=private or public'!=public;

     description:  (* The draw operation is used for the pencil, highlighter, and eraser since they all have the same characteristics. WhichTool selects one of the three tools and WhichLayer selects the layer to be drawn on.*);
end Draw;

object SearchText is string;

object SearchResult is string;

operation Search is
     inputs:  searchText:SearchText and lectureLayer:LectureLayer and searchResult:SearchResult;

     outputs:  searchResult':SearchResult;

     preconditions:  searchText!=nil and lectureLayer.enable=true and searchResult=nil;

     postconditions:  searchResult'=searchText;

     description: (* The search operation is activated when the magnifying glass tool is selected. *);
end Search;

end Tools;