-- ArrayToolImpl.mesa
--  last edit                July 11, 1984 9:06:28 am PDT  Sturgis

DIRECTORY
   Dependencies USING[CreateDependencySet, DependencySet],
   Displayer USING[BuildDisplayer, ButtonDefiningProc, PaintDisplayerContents, SetDisplayerContents],
   Expressions USING[HCellIdSet, IdTable, MakeHCellIdSet, MakeIdTable],
   GCell USING[CreateGCellArray, GetArraySelection, GetGCellArray, GetGCellArrayColumn, GetGCellArrayRow, GetGCellArrayShape, SetAGCellProc, SetGCellArray, SetGCellArrayColumn, SetGCellArrayRow],
   NewCalcGlobal USING[Displayer, Document, DocumentProcs, DocumentPublicBody],
   Rope USING[ROPE],
   StructureNodes USING[Action, StructureNode],
   ViewerClasses USING[Viewer];
  

ArrayToolImpl: MONITOR IMPORTS Displayer, Dependencies, Expressions, GCell EXPORTS GCell =



-- NOTE NOTE NOTE NOTE NOTE NOTE

-- NOTE: !!!!! WHEN CONVERTING TO OBJECT MONITOR, Set and Get Selection must also be entry procedures. !!!!   NOTE NOTE

-- ALSO, Array tool will have to set entry TRUE on calls to Get and Set GCellArray.



BEGIN OPEN Dependencies, ViewerClasses;

	

-- array tool code, temporary home
-- when moving out to its own module, change calls to Get and Set GCellArray to have "entry" = TRUE.

ArrayToolPrivateBody: TYPE = RECORD[
   dSet: DependencySet,
   gcaSn: StructureNodes.StructureNode,
   displayer: NewCalcGlobal.Displayer,
   container: Viewer,
   structure: Viewer
   ];

ArrayToolDisplayerProcs:  REF NewCalcGlobal.DocumentProcs ← NEW[NewCalcGlobal.DocumentProcs ← [ExecuteInArrayToolMonitor, ComputeArrayToolTotals, NIL, AdjustArrayTool]];

BuildArrayTool: PUBLIC PROCEDURE = 
   BEGIN ENABLE UNWIND => NULL;
   dSet: DependencySet ← CreateDependencySet[];
   ids: Expressions.IdTable ← Expressions.MakeIdTable[];
   hCellIds: Expressions.HCellIdSet ← Expressions.MakeHCellIdSet[];
   arrayToolPrivate: REF ArrayToolPrivateBody ← NEW[ArrayToolPrivateBody];
   documentPublic: NewCalcGlobal.Document ← NEW[NewCalcGlobal.DocumentPublicBody←[dSet, ids, hCellIds, arrayToolPrivate, ArrayToolDisplayerProcs]];
   
	[arrayToolPrivate.displayer, arrayToolPrivate.container, arrayToolPrivate.structure] ← Displayer.BuildDisplayer[documentPublic, arrayToolPrivate, "arrayTool", DefineArrayToolButtons];
   
   
         
   [arrayToolPrivate.gcaSn] ← GCell.CreateGCellArray[documentPublic, arrayToolPrivate.displayer, arrayToolPrivate.structure];
   Displayer.SetDisplayerContents[arrayToolPrivate.displayer, "arrayTool", arrayToolPrivate.gcaSn];
   
   documentPublic.procs.adjust[documentPublic];
   END;
   
   
DefineArrayToolButtons: Displayer.ButtonDefiningProc =
   BEGIN
   arrayToolPrivate: REF ArrayToolPrivateBody ← NARROW[owner];
   
   defineProcButton[name: "total", proc: ATComputeTotals];
   defineProcButton[name: "adjust", proc: ATAdjust];
   newLine[];
   newLine[];
   defineStructureOpButton[InsertColumn];
   defineStructureOpButton[AppendColumn];
   defineStructureOpButton[DeleteColumn];
   newLine[];
   defineStructureOpButton[InsertRow];
   defineStructureOpButton[AppendRow];
   defineStructureOpButton[DeleteRow];
   newLine[];
   newLine[];
   defineProcButton[name: "GetArray", proc: GetArray];
   defineProcButton[name: "SetArray", proc: SetArray];
   newLine[];
   defineProcButton[name: "GetRow", proc: GetArrayRow];
   defineProcButton[name: "SetRow", proc: SetArrayRow];
   newLine[];
   defineProcButton[name: "GetColumn", proc: GetArrayColumn];
   defineProcButton[name: "SetColumn", proc: SetArrayColumn];
   newLine[];
   END;
   
GetArray: ENTRY PROCEDURE[arg: REF ANY] =
   	BEGIN ENABLE UNWIND => NULL;
   	document: NewCalcGlobal.Document ← NARROW[arg];
   	tool: REF ArrayToolPrivateBody ← NARROW[document.private];
   	sourceGCA: StructureNodes.StructureNode;
   	
   	Ship: PROCEDURE[nColumns, nRows: CARDINAL, GetOneCell: PROCEDURE[GCell.SetAGCellProc]] =
   		BEGIN
   		GCell.SetGCellArray[tool.gcaSn, nColumns, nRows, GetOneCell];
   		END;
   		
   	[ , sourceGCA, , ] ← GCell.GetArraySelection[];
   	IF sourceGCA = NIL THEN RETURN;
   	IF sourceGCA = tool.gcaSn THEN RETURN;
   	GCell.GetGCellArray[sourceGCA, Ship];
   	document.procs.adjust[document];
   	END;
   
GetArrayRow: ENTRY PROCEDURE[arg: REF ANY] =
   	BEGIN ENABLE UNWIND => NULL;
   	document: NewCalcGlobal.Document ← NARROW[arg];
   	tool: REF ArrayToolPrivateBody ← NARROW[document.private];
   	sourceGCA: StructureNodes.StructureNode;
   	J: CARDINAL;
   	
   	Ship: PROCEDURE[nColumns, nRows: CARDINAL, GetOneCell: PROCEDURE[GCell.SetAGCellProc]] =
   		BEGIN
   		IF nRows # 1 THEN ERROR;
   		GCell.SetGCellArray[tool.gcaSn, nColumns, nRows, GetOneCell];
   		END;
   		
   	[ , sourceGCA, , J] ← GCell.GetArraySelection[];
   	IF sourceGCA = NIL THEN RETURN;
   	IF sourceGCA = tool.gcaSn THEN RETURN;
   	GCell.GetGCellArrayRow[sourceGCA, J, Ship, FALSE];
   	document.procs.adjust[document];
   	END;
   
GetArrayColumn: ENTRY PROCEDURE[arg: REF ANY] =
   	BEGIN ENABLE UNWIND => NULL;
   	document: NewCalcGlobal.Document ← NARROW[arg];
   	tool: REF ArrayToolPrivateBody ← NARROW[document.private];
   	sourceGCA: StructureNodes.StructureNode;
   	I: CARDINAL;
   	
   	Ship: PROCEDURE[nColumns, nRows: CARDINAL, GetOneCell: PROCEDURE[GCell.SetAGCellProc]] =
   		BEGIN
   		IF nColumns # 1 THEN ERROR;
   		GCell.SetGCellArray[tool.gcaSn, nColumns, nRows, GetOneCell];
   		END;
   		
   	[ , sourceGCA, I, ] ← GCell.GetArraySelection[];
   	IF sourceGCA = NIL THEN RETURN;
   	IF sourceGCA = tool.gcaSn THEN RETURN;
   	GCell.GetGCellArrayColumn[sourceGCA, I, Ship, FALSE];
   	document.procs.adjust[document];
   	END;
   
 SetArray: ENTRY PROCEDURE[arg: REF ANY] =
   	BEGIN ENABLE UNWIND => NULL;
   	document: NewCalcGlobal.Document ← NARROW[arg];
   	tool: REF ArrayToolPrivateBody ← NARROW[document.private];
   	targetDisplayer: NewCalcGlobal.Displayer;
   	targetGCA: StructureNodes.StructureNode;
   	
   	Ship: PROCEDURE[nColumns, nRows: CARDINAL, GetOneCell: PROCEDURE[GCell.SetAGCellProc]] =
   		BEGIN
   		GCell.SetGCellArray[targetGCA, nColumns, nRows, GetOneCell];
   		END;
   		
   	[targetDisplayer, targetGCA, , ] ← GCell.GetArraySelection[];
   	IF targetGCA = NIL THEN RETURN;
   	IF targetGCA = tool.gcaSn THEN RETURN;
   	GCell.GetGCellArray[tool.gcaSn, Ship];
   	document.procs.adjust[document];
   	END;
  
SetArrayRow: ENTRY PROCEDURE[arg: REF ANY] =
   	BEGIN ENABLE UNWIND => NULL;
   	document: NewCalcGlobal.Document ← NARROW[arg];
   	tool: REF ArrayToolPrivateBody ← NARROW[document.private];
   	targetDisplayer: NewCalcGlobal.Displayer;
   	targetGCA: StructureNodes.StructureNode;
   	J: CARDINAL;
   	toolRows, toolColumns: CARDINAL;
   	
   	Ship: PROCEDURE[nColumns, nRows: CARDINAL, GetOneCell: PROCEDURE[GCell.SetAGCellProc]] =
   		BEGIN
   		IF nRows # 1 THEN ERROR;
   		GCell.SetGCellArrayRow[targetGCA, nColumns, J, GetOneCell, FALSE];
   		END;
   		
   	[targetDisplayer, targetGCA, , J] ← GCell.GetArraySelection[];
   	IF targetGCA = NIL THEN RETURN;
   	IF targetGCA = tool.gcaSn THEN RETURN;
   	[nRows: toolRows, nColumns: toolColumns] ← GCell.GetGCellArrayShape[tool.gcaSn];
   	IF toolRows # 1 THEN RETURN;
   	IF toolColumns # GCell.GetGCellArrayShape[targetGCA].nColumns THEN RETURN;
   	GCell.GetGCellArrayRow[tool.gcaSn, 1, Ship, FALSE];
   	document.procs.adjust[document];
   	END;
  
SetArrayColumn: ENTRY PROCEDURE[arg: REF ANY] =
   	BEGIN ENABLE UNWIND => NULL;
   	document: NewCalcGlobal.Document ← NARROW[arg];
   	tool: REF ArrayToolPrivateBody ← NARROW[document.private];
   	targetDisplayer: NewCalcGlobal.Displayer;
   	targetGCA: StructureNodes.StructureNode;
   	I: CARDINAL;
   	toolRows, toolColumns: CARDINAL;
   	
   	Ship: PROCEDURE[nColumns, nRows: CARDINAL, GetOneCell: PROCEDURE[GCell.SetAGCellProc]] =
   		BEGIN
   		IF nColumns # 1 THEN ERROR;
   		GCell.SetGCellArrayColumn[targetGCA, I, nRows, GetOneCell, FALSE];
   		END;
   		
   	[targetDisplayer, targetGCA, I, ] ← GCell.GetArraySelection[];
   	IF targetGCA = NIL THEN RETURN;
   	IF targetGCA = tool.gcaSn THEN RETURN;
   	[nRows: toolRows, nColumns: toolColumns] ← GCell.GetGCellArrayShape[tool.gcaSn];
   	IF toolColumns # 1 THEN RETURN;
   	IF toolRows # GCell.GetGCellArrayShape[targetGCA].nRows THEN RETURN;
   	GCell.GetGCellArrayColumn[tool.gcaSn, 1, Ship, FALSE];
   	document.procs.adjust[document];
   	END;
   	
 ATComputeTotals: ENTRY PROCEDURE[arg: REF ANY] =
   BEGIN ENABLE UNWIND => NULL;
	NULL;
	END;
	
ATAdjust: ENTRY PROCEDURE[arg: REF ANY] =
   BEGIN ENABLE UNWIND => NULL;
	document: NewCalcGlobal.Document ← NARROW[arg];
   tool: REF ArrayToolPrivateBody ← NARROW[document.private];
	document.procs.adjust[document];
	END;


ExecuteInArrayToolMonitor: ENTRY PROCEDURE[document: NewCalcGlobal.Document, p: PROC] =
	{ENABLE UNWIND => NULL; p[]};
	
	
ComputeArrayToolTotals: PROCEDURE[document: NewCalcGlobal.Document] = {NULL};

AdjustArrayTool: PROCEDURE[document: NewCalcGlobal.Document] =
	BEGIN
	arrayToolPrivate: REF ArrayToolPrivateBody ← NARROW[document.private];
	Displayer.PaintDisplayerContents[arrayToolPrivate.displayer];
   END;
 
END..


-- July 10, 1984 2:11:45 pm PDT: Sturgis, created ArrayToolImpl, from NewCalcImpl.
-- RTE: July 11, 1984 9:06:18 am PDT: a tight loop, involving AdjustArrayTool and DisplayToolImpl.AfterStructureOp.  Modified AdjustArrayTool to call Displayer.PaintDisplayerContents directly.