Program Moire;

	{ This program just draws a Moire pattern in a window.
	  It uses a surprising breadth of functions, so it shows
	  off a bit of what PCQ can do.  And it works to boot. }

{$I "Include/Exec.i" for Forbid, Permit and library things }
{$I "Include/Ports.i" for the Message stuff }
{$I "Include/Intuition.i" for window & screen structures and functions }
{$I "Include/Graphics.i" for drawing stuff }

var
    w  : WindowPtr;
    s  : ScreenPtr;
    m  : MessagePtr;

Function OpenTheScreen() : Boolean;
var
    ns : NewScreenPtr;
begin
    new(ns);

    ns^.LeftEdge := 0;
    ns^.TopEdge  := 0;
    ns^.Width    := 640;
    ns^.Height   := 200;
    ns^.Depth    := 2;
    ns^.DetailPen := 3;
    ns^.BlockPen  := 2;
    ns^.ViewModes := 32768;
    ns^.SType     := CUSTOMSCREEN_f;
    ns^.Font      := nil;
    ns^.DefaultTitle := "Close the Window to End This Demonstration";
    ns^.Gadgets   := nil;
    ns^.CustomBitMap := nil;

    s := OpenScreen(ns);
    dispose(ns);
    OpenTheScreen := s <> nil;
end;

Function OpenTheWindow() : Boolean;
var
    nw : NewWindowPtr;
begin
    new(nw);

    nw^.LeftEdge := 20;
    nw^.TopEdge := 50;
    nw^.Width := 300;
    nw^.Height := 100;

    nw^.DetailPen := -1;
    nw^.BlockPen  := -1;
    nw^.IDCMPFlags := CLOSEWINDOW_f;
    nw^.Flags := WINDOWSIZING_f + WINDOWDRAG_f + WINDOWDEPTH_f +
		 WINDOWCLOSE_f + SMART_REFRESH_f + ACTIVATE_f;
    nw^.FirstGadget := nil;
    nw^.CheckMark := nil;
    nw^.Title := "Feel Free to Re-Size the Window";
    nw^.Screen := s;
    nw^.BitMap := nil;
    nw^.MinWidth := 50;
    nw^.MaxWidth := -1;
    nw^.MinHeight := 20;
    nw^.MaxHeight := -1;
    nw^.WType := CUSTOMSCREEN_f;

    w := OpenWindow(nw);
    dispose(nw);
    OpenTheWindow := w <> nil;
end;

Procedure DoDrawing(RP : RastPortPtr);
var
    x  : Integer;
    Pen : Integer;
    Stop : Integer;
begin

{
	Note that for all the border things I have to use ord() to
use them in calculations.  This is because I have not yet added a
byte type to PCQ (I didn't realize I needed one until I started
using system functions).  Just for your information, I'll point out
that ord() here has the same overhead that mixing byte and integer
types would have anyway.
}

    Pen := 1;
    while true do begin
	Stop := w^.Width - w^.BorderRight;
	for x:= 0 to Stop - w^.BorderLeft do begin
	    SetAPen(RP, Pen);
	    Move(RP, x + w^.BorderLeft, w^.BorderTop);
	    Draw(RP, Stop - x, w^.Height - w^.BorderBottom);
	    Pen := (Pen + 1) mod 4;
	    m := GetMsg(w^.UserPort);
	    if m <> nil then
		return;
	end;
	Stop := w^.Height - w^.BorderBottom;
	for x := 0 to Stop - w^.BorderTop do begin
	    SetAPen(RP, Pen);
	    Move(RP, w^.Width - w^.BorderRight, x + w^.BorderTop);
	    Draw(RP, w^.BorderLeft, Stop - x);
	    Pen := (Pen + 1) mod 4;
	    m := GetMsg(w^.UserPort);
	    if m <> nil then
		return;
	end;
    end;
end;

begin
	{ Note that the startup code of all PCQ programs depends on
	  Intuition, so if we got to this point Intuition must be
	  open, so the run time library just uses the pointer that
	  the startup code created.  Same with DOS, although we don't
	  use that here. }

    GfxBase := OpenLibrary("graphics.library", 0);
    if GfxBase <> nil then begin
	if OpenTheScreen() then begin
	    if OpenTheWindow() then begin
		DoDrawing(w^.RPort);
		Forbid;
		repeat
		    m := GetMsg(w^.UserPort);
		until m = nil;
		CloseWindow(w);
		Permit;
	    end else
		writeln('Could not open the window');
	    CloseScreen(s);
	end else
	    writeln('Could not open the screen.');
	CloseLibrary(GfxBase);
    end else
	writeln('Could not open graphics.library');
end.

