-- Compiler GriffinMain/n
-- m.stone May 12, 1981 4:58 PM
-- Tiberi December 12, 1979 12:00 PM

DIRECTORY
GriffinDefs: FROM "GriffinDefs",
GeneralDisplayDefs: FROM "GeneralDisplayDefs",
GriffinMemoryDefs: FROM "GriffinMemoryDefs",
StringDefs: FROM "StringDefs",
PointDefs: FROM "PointDefs",
RefreshDefs: FROM "RefreshDefs",
OpDefs: FROM "OpDefs",
ScreenDefs: FROM "ScreenDefs",
IODefs: FROM "IODefs",
StreamDefs: FROM "StreamDefs",
ImageDefs: FROM "ImageDefs",
FrameDefs: FROM "FrameDefs",
SegmentDefs: FROM "SegmentDefs",
MenuDefs: FROM "MenuDefs",
ObjectDefs: FROM "ObjectDefs",
CursorDefs: FROM "CursorDefs",
GriffinFileDefs: FROM "GriffinFileDefs",
GriffinFontDefs: FROM "GriffinFontDefs",
GriffinInputDefs: FROM "GriffinInputDefs";

GriffinMain: PROGRAM
IMPORTS GriffinDefs, MenuDefs, CursorDefs,
GriffinInputDefs, StringDefs, OpDefs, ScreenDefs,
ImageDefs, ObjectDefs, RefreshDefs, StreamDefs, IODefs, FrameDefs, GriffinFileDefs
EXPORTS GriffinDefs =
BEGIN OPEN GriffinDefs, PointDefs,RefreshDefs;

X: CARDINAL = PointDefs.X;
Y: CARDINAL = PointDefs.Y;
errorCount: CARDINAL ← 0;

downStroke: GriffinInputDefs.InputEvent;
item: MenuDefs.MenuItemHandle ← NIL;
mouseDown: BOOLEAN ← FALSE;
overSameItem: BOOLEAN ← FALSE;
aborted: BOOLEAN ← FALSE;
MyInputEventProc: GriffinInputDefs.InputEventProc ← HandleInputEvent;
topMenu: MenuDefs.MenuHandle←NIL;
quitMenu: MenuDefs.MenuHandle←NIL;
hiddenMenu: MenuDefs.MenuHandle←NIL;
messageMenu: MenuDefs.MenuHandle←NIL;
messageItem: MenuDefs.MenuItemHandle←NIL;

ToggleShowMenu: MenuDefs.MenuProc =
BEGIN OPEN StringDefs, MenuDefs, GriffinDefs;
UpdateMenu: PROCEDURE[menu: MenuHandle, show: BOOLEAN] =
BEGIN
IF show THEN BEGIN
ShowMenu[menu];
END
ELSE BEGIN
HideMenu[menu];
END;
END;
UpdateItem: PROCEDURE[item: MenuItemHandle] =
BEGIN
IF IsSelected[item] THEN Deselect[item] ELSE Select[item];
END;
UpdateBoth: PROCEDURE[menu: MenuHandle, item: MenuItemHandle] =
BEGIN
UpdateItem[item];
UpdateMenu[menu, IsSelected[item]];
END;

string: STRING = MenuString[item];
SELECT TRUE FROM
EqualStrings[string, "Edit"] =>
BEGIN
IF IsSelected[item] THEN BEGIN
item: MenuItemHandle;
item ← FindItemByString[editMenu,"Spline Type"];
IF IsSelected[item] THEN BugItem[item];
END;
UpdateItem[item];
UpdateMenu[editMenu, IsSelected[item]];
UpdateMenu[shapeMenu, IsSelected[item]];
END;
EqualStrings[string, "Objects"] =>
UpdateBoth[objectMenu, item];
EqualStrings[string, "Style"] =>
BEGIN
IF IsSelected[item] THEN BEGIN
item: MenuItemHandle;
item ← FindItemByString[GriffinDefs.styleMenu,"Text Style"];
IF IsSelected[item] THEN BugItem[item];
item ← FindItemByString[GriffinDefs.styleMenu,"Color Style"];
IF IsSelected[item] THEN BugItem[item];
item ← FindItemByString[GriffinDefs.styleMenu,"Shape Style"];
IF IsSelected[item] THEN BugItem[item];
END;
UpdateBoth[styleMenu, item];
END;
EqualStrings[string, "Files"] =>
UpdateBoth[filesMenu, item];
EqualStrings[string, "Transform"] =>
UpdateBoth[xformMenu, item];
EqualStrings[string, "Overlap"] =>
UpdateBoth[overlapMenu, item];
EqualStrings[string, "View"] =>
UpdateBoth[viewMenu, item];
ENDCASE=> ERROR;
RestoreScreen[];
END;

FindItemByString: PROCEDURE[menu: MenuDefs.MenuHandle,string: STRING] RETURNS [mitem: MenuDefs.MenuItemHandle]=
BEGIN OPEN MenuDefs;
IsItem: MenuProc = BEGIN
IF StringDefs.EquivalentString[MenuString[item],string] THEN mitem ← item;
END;
ForAllMenuItems[menu,IsItem];
END;

Quit: MenuDefs.MenuProc =
BEGIN
ScreenDefs.ClearScreen[];
hiddenMenu←item.menu;
hiddenMenu.visible ← FALSE;
quitMenu.visible ← TRUE;
MenuDefs.PlotMenu[quitMenu];
END;

YesQuit: MenuDefs.MenuProc =
BEGIN
--GeneralDisplayDefs.pMonitorHead↑ ← NIL;
--WaitAWhile[500];
ImageDefs.StopMesa[];
END;

WaitAWhile: PROCEDURE[millisecs: CARDINAL] =
BEGIN
i,j: CARDINAL;
FOR i IN [0..millisecs] DO
FOR j IN [0..2000] DO ENDLOOP;
ENDLOOP;
END;

NoQuit: MenuDefs.MenuProc =
BEGIN
hiddenMenu.visible ← TRUE;
quitMenu.visible ← FALSE;
ScreenDefs.ClearScreen[];
ObjectDefs.ReplotAllObjects;
END;

UserMessage: PUBLIC SIGNAL [string: STRING] = CODE;

GriffinFull: PUBLIC SIGNAL = CODE;

ShowUserMessage: PUBLIC PROCEDURE[string: STRING] =
BEGIN
MenuDefs.SetMenuString[messageItem, string];
MenuDefs.ShowMenu[messageMenu];
MenuDefs.HighlightMenuItem[messageItem];
RestoreScreen[];
END;

AbortCleanup: PROCEDURE =
BEGIN
CursorDefs.SetCursor[pointingCursor];

IF item # NIL
THEN MenuDefs.ClearMenuItem[item];
item ← NIL;
mouseDown ← FALSE;
overSameItem ← FALSE;
END;

ReleaseHandleInputEvent: GriffinInputDefs.InputEventProc =
BEGIN ENABLE
BEGIN
UserMessage =>
BEGIN
ShowUserMessage[string];
AbortCleanup;
CONTINUE;
END;
GriffinFull =>
BEGIN
ShowUserMessage["Griffin is out of space. Save your file!"];
AbortCleanup;
CONTINUE;
END;
ANY =>
BEGIN
errorCount ← errorCount+1;
IF errorCount=1 THEN BEGIN
[] ← GriffinFileDefs.OpenPortfolio ["GriffinError", TRUE];
[] ← GriffinFileDefs.AddFigure [1];
GriffinFileDefs.ClosePortfolio;
RemCm["// Griffin error. File GriffinError.Griffin written"];
END;
IF errorCount =2 THEN RemCm["// Fatal Griffin error. No file could be written"];
IF errorCount > 2 THEN ImageDefs.AbortMesa[];
CONTINUE;
END
END;

IHandleInputEvent[event];
END;

HandleInputEvent: GriffinInputDefs.InputEventProc =
BEGIN ENABLE
BEGIN
UserMessage =>
BEGIN
ShowUserMessage[string];
AbortCleanup;
CONTINUE;
END;
GriffinFull =>
BEGIN
ShowUserMessage["No more room! Save and quit."];
AbortCleanup;
CONTINUE;
END;
END;
IHandleInputEvent[event];
END;

--want to have two wraps on it, one for debug and one for release
--this is the proc that actually does the work

IHandleInputEvent: GriffinInputDefs.InputEventProc = {
up,down: ScrPt;

SELECT event.type FROM
red,yellow,blue =>
BEGIN
EndTypeIn[];
downStroke ← event;
mouseDown ← TRUE;
overSameItem ← TRUE;
item ← MenuDefs.OverWhichItem[event.pt];
IF item # NIL THEN MenuDefs.HighlightMenuItem[item];
END;
multiple =>
BEGIN
aborted←TRUE;
AbortCleanup;
CursorDefs.SetCursor[abortCursor];
END;
up=>
BEGIN
IF aborted THEN
BEGIN
aborted←FALSE;
AbortCleanup;
RETURN
END;
CursorDefs.SetCursor[busyCursor];
mouseDown ← FALSE;
overSameItem ← FALSE;
down ← downStroke.pt;
up ← event.pt;
IF item # NIL THEN --downstroke was over menu
BEGIN
IF MenuDefs.IsOverItem[up, item]
THEN MenuDefs.BugItem[item];
MenuDefs.ClearMenuItem[item];
CursorDefs.SetCursor[pointingCursor];
item ← NIL;
RETURN
END;
SELECT downStroke.type FROM
red =>
BEGIN
down ← GriffinDefs.Grid[down];
up ← GriffinDefs.Grid[up];
IF event.shifted
THEN OpDefs.CopyObjects[down,up]
ELSE OpDefs.MoveObjects[down,up];
END;
yellow =>
BEGIN
down ← GriffinDefs.Grid[down];
up ← GriffinDefs.Grid[up];
IF item = NIL THEN IF event.shifted
THEN OpDefs.DeleteControlPoint[down,up]
ELSE OpDefs.PlaceControlPoint[up];
END;
blue =>
IF item = NIL THEN IF event.shifted
THEN OpDefs.DeselectObjects[down,up]
ELSE OpDefs.SelectObjects[down,up];
ENDCASE;
item ← NIL;
CursorDefs.SetCursor[pointingCursor];
END;
newPosition =>
IF mouseDown AND item # NIL
THEN IF MenuDefs.IsOverItem[event.pt, item]
THENBEGIN
IF ~ overSameItem THEN MenuDefs.HighlightMenuItem[item];
overSameItem ← TRUE;
END
ELSEBEGIN
IF overSameItem THEN MenuDefs.ClearMenuItem[item];
overSameItem ← FALSE;
END;

keyStroke =>
BEGIN
CursorDefs.SetCursor[busyCursor];
TypeIn[event.key];
CursorDefs.SetCursor[pointingCursor];
END;
ENDCASE;
};

HideMessage: MenuDefs.MenuProc =
BEGIN
MenuDefs.HideMenu[messageMenu];
RestoreScreen[];
END;

--Procedure so can catch all init errors
StartGriffin: PROCEDURE =
BEGIN
CursorDefs.SetCursor[busyCursor];
START GriffinInit;
topMenu ← MenuDefs.CreateMenu[horizontal, [100,30], NIL];
[]←MenuDefs.AddMenuItem[topMenu,"Edit",ToggleShowMenu];
[]←MenuDefs.AddMenuItem[topMenu,"Objects",ToggleShowMenu];
[]←MenuDefs.AddMenuItem[topMenu,"Style",ToggleShowMenu];
[]←MenuDefs.AddMenuItem[topMenu,"Files",ToggleShowMenu];
[]←MenuDefs.AddMenuItem[topMenu,"Transform",ToggleShowMenu];
[]←MenuDefs.AddMenuItem[topMenu,"Overlap",ToggleShowMenu];
[]←MenuDefs.AddMenuItem[topMenu,"View",ToggleShowMenu];
[]←MenuDefs.AddMenuItem[topMenu,"Quit",Quit];

quitMenu ← MenuDefs.CreateMenu[horizontal, [60,80], "Quit! [Confirm]"];
[]←MenuDefs.AddMenuItem[quitMenu,"Yes",YesQuit];
[]←MenuDefs.AddMenuItem[quitMenu,"No",NoQuit];

messageMenu ← MenuDefs.CreateMenu[vertical, [150, 400], NIL];
messageItem ← MenuDefs.AddMenuItem[messageMenu, "Aborted.",
HideMessage];

CursorDefs.SetCursor[pointingCursor];
MenuDefs.ShowMenu[topMenu];
RestoreScreen[];
END;

RemCm: PROCEDURE[string: STRING]=
BEGIN OPEN StreamDefs;
diskHandle: DiskHandle;
diskHandle ← NewByteStream ["REM.CM", Write + Append];
IODefs.SetOutputStream[diskHandle];
IODefs.WriteLine[string];
TruncateDiskStream [diskHandle];
ImageDefs.StopMesa[];
END;

--images will get the smooth wrap. ie. exit with bugs, etc
IF FrameDefs.IsBound[ImageDefs.MakeImage]
THEN {MyInputEventProc ← ReleaseHandleInputEvent;
ImageDefs.MakeImage["Griffin.Image"]};

StartGriffin[];
GriffinInputDefs.Input[MyInputEventProc];
END.