(*
    This program illustrates various techniques used
    in drawing programs.

    Created: 6/26/88 by Richie Bielak

    Modified:

    Copyright © 1988 by Richie Bielak
    
    This program maybe freely copied, but please leave my
    name in. Thanks....Richie

*)
MODULE Draw;

FROM SYSTEM        IMPORT ADR;
FROM SimpleScreens IMPORT CreateScreen;
FROM SimpleWindows IMPORT CreateWindow;
FROM Intuition     IMPORT
     WindowFlags, IDCMPFlags, IDCMPFlagsSet, WindowFlagsSet, WindowPtr, 
     ScreenPtr, IntuiMessagePtr, CloseWindow, CloseScreen, ShowTitle,
     SetMenuStrip, ClearMenuStrip, MENUNUM, ITEMNUM, MenuNull,
     ReportMouse;
FROM Ports         IMPORT ReplyMsg, WaitPort, GetMsg, MessagePtr;
FROM Views         IMPORT SetRGB4;
FROM Drawing       IMPORT SetAPen;
FROM Rasters       IMPORT SetRast;
FROM Termination   IMPORT ExitGracefully;
FROM DrawMenu      IMPORT MainMenuPtr, DrawMenuType, ActionType;
FROM DrawUtil      IMPORT IsButtonDown;

(* Imports from "Tools" modules begin here *)
IMPORT Pencils;
IMPORT Lines;
IMPORT Figures;

CONST
  NotEnoughMemory = 103D; (* AMIGA DOS error *)

VAR
  sp : ScreenPtr;
  wp : WindowPtr;
  titleOn : BOOLEAN;
  CurrentTool : PROCEDURE (WindowPtr, CARDINAL, CARDINAL);


(* +++++++++++++++++++++++++++++++++++++++++ *)
(* Clean up before exiting.                  *)
PROCEDURE FinalCleanUp ();
  BEGIN
    ClearMenuStrip (wp^);
    CloseWindow (wp^);
    CloseScreen (sp^);
  END FinalCleanUp;

(* +++++++++++++++++++++++++++++++++++++++++ *)
PROCEDURE SetUpColors (sp : ScreenPtr);
  BEGIN
    WITH sp^ DO
      SetRGB4 (ViewPort, 0, 0,  0, 0);  (* Black *)
      SetRGB4 (ViewPort, 1, 14,14,14);  (* Light grey *)
      SetRGB4 (ViewPort, 2, 15, 0, 0);  (* Red *)
      SetRGB4 (ViewPort, 3,  0,15, 0);  (* Green *)
      SetRGB4 (ViewPort, 4,  0, 0,15);  (* Blue *)
      SetRGB4 (ViewPort, 5,  0,15,15);
      SetRGB4 (ViewPort, 6, 15, 0,15);
      SetRGB4 (ViewPort, 7, 15,15, 0);
    END;
  END SetUpColors;

(* +++++++++++++++++++++++++++++++++++++++++ *)
PROCEDURE ProcessMenu (code : CARDINAL; VAR quit : BOOLEAN);
  BEGIN
    CASE DrawMenuType (MENUNUM(code)) OF
      Actions: 
        CASE ActionType (ITEMNUM(code)) OF
          toggle: titleOn := NOT titleOn;
	          ShowTitle (sp^, titleOn); |
          clear:  SetRast (wp^.RPort^, 0) |
          finish: quit := TRUE;
        END; (* CASE *)
      |
      Tools: 
        CASE ITEMNUM(code) OF
	  0: CurrentTool := Pencils.NormalPencil; |
	  1: CurrentTool := Pencils.DottyPencil;  |
          2: CurrentTool := Lines.Fan;            |
          3: CurrentTool := Lines.Line;           |
	  4: CurrentTool := Lines.Polygon;        |
          5: CurrentTool := Figures.Ellipse;      |
          6: CurrentTool := Figures.Rectangle;    
        ELSE
          (* Error *)
	END;
      |
      Colors: SetAPen (wp^.RPort^, ITEMNUM(code))
    END; (* CASE *)
  END ProcessMenu;

(* +++++++++++++++++++++++++++++++++++++++++ *)
PROCEDURE ProcessMessages ();
  VAR
    msgptr : IntuiMessagePtr;
    class  : IDCMPFlagsSet; code : CARDINAL;
    quit   : BOOLEAN;
    x, y   : CARDINAL;
  BEGIN
    quit := FALSE;
    REPEAT
      msgptr := WaitPort (wp^.UserPort^);
      LOOP
        msgptr := GetMsg (wp^.UserPort^);
        IF msgptr = NIL THEN EXIT; END;
        code := msgptr^.Code; class := msgptr^.Class;
        x := msgptr^.MouseX; y := msgptr^.MouseY;
        ReplyMsg (MessagePtr(msgptr));
        IF (class = IDCMPFlagsSet{MenuPick}) AND (code <> MenuNull) THEN
          ProcessMenu(code, quit)
        ELSIF (class = IDCMPFlagsSet{MouseButtons}) THEN
          IF IsButtonDown (code) THEN
            (* Detach menu strip while the tool is being used *)
	    ClearMenuStrip (wp^);
            ReportMouse (wp^, TRUE);
            (* Invoke the current tool *)
            CurrentTool (wp, x, y);
            ReportMouse (wp^, FALSE);
            SetMenuStrip (wp^, MainMenuPtr^);
          END;
        END;
      END (* LOOP *)
    UNTIL quit;
  END ProcessMessages;


BEGIN
  titleOn := TRUE;
  (* Create screen and a window to draw in *)
  sp := CreateScreen (640, 200, 3, 
                      ADR("Draw...V 1.3 June 1989"));
  IF sp = NIL THEN ExitGracefully (NotEnoughMemory) END;

  SetUpColors (sp);

  wp := CreateWindow (0, 0, 640, 200,
                      IDCMPFlagsSet {MenuPick, MouseButtons, MouseMove},
                      WindowFlagsSet {Activate, Borderless, BackDrop},
   		      NIL, sp, NIL);

  IF sp = NIL THEN
    CloseScreen (sp^);
    ExitGracefully (NotEnoughMemory) 
  END;

  (* Set default tool and color *)
  SetAPen (wp^.RPort^, 1);
  CurrentTool := Pencils.NormalPencil;
  
  (* Now do some real work *)
  SetMenuStrip (wp^, MainMenuPtr^);
  ProcessMessages ();
  FinalCleanUp ();
  
  ExitGracefully (1D);
END Draw.

