-- StructureNodes.mesa
-- Last Edited by: Sturgis, July 30, 1984 10:14:28 am PDT
-- Last Edited by: Maxwell, March 8, 1983 11:28 am

DIRECTORY
 IO USING[STREAM],
 Rope USING[ROPE];


StructureNodes: DEFINITIONS =

BEGIN OPEN IO;

Action: TYPE = {MarkCellInteresting, InsertColumn, AppendColumn, DeleteColumn, InsertRow, AppendRow, DeleteRow, InsertSlot, AppendSlot, DeleteSlot, InsertPage, AppendPage, DeletePage, MakeSummaryPage, CreateGCellArray, CreateHCellArray, CreateSummaryHCellArray, SubstituteOnPage, SubstituteInArray, SubstituteInRow, SubstituteInColumn, SetRowControlToControl, SetRowControlToText, SetRowControlToAddItem, SetRowControlToSum, SetColControlToControl, SetColControlToText, SetColControlToAddZero, SetColControlToAddItem, SetColControlToSubItem, SetColControlToLeftValTimesExp, SetColControlToLeftVal, SetColControlToSum, SetColControlToTotal, SetColControlToIdGetsTotal, SetColControlToIdGetsSum, SetColControlToIdGetsLv, ToggleControlVisibility, SetZeroValueText, SetPageId, SetArrayId,

-- following are not represented by buttons
MoveSelectionToNext, MoveSelectionToPrevious, NoteItemSelection, NoteArraySelection, NullAction};

StructureNode: TYPE = REF StructureNodeBody;
StructureNodeBody: TYPE = RECORD[ref: REF ANY, procs: REF StructureNodeProcs];

StructureNodeProcs: TYPE = RECORD[

 -- first the old display node procs

 CheckForDirtyData: PROCEDURE[node: StructureNode],
 PreShow: PROCEDURE[node: StructureNode] RETURNS[lead, height: INTEGER, space, L, A, B, R, W: INTEGER],
 ShowLine: PROCEDURE[node: StructureNode, L, R, W: INTEGER, lineX: INTEGER, to: STREAM],
 PrePrePaint: PROCEDURE[node: StructureNode] RETURNS[lead, height: INTEGER, space, L, A, B, R, W: INTEGER],
 PrePaint: PROCEDURE[node: StructureNode, y, x, L, R, W: INTEGER, pass: PrePaintPass],
 Paint: PROCEDURE[node: StructureNode, dirtyOnly: BOOLEAN],
 UnPaint: PROCEDURE[node: StructureNode],
 NoteEnclosingCell: PROCEDURE[StructureNode, DACell],
 NoteCoordinates: PROCEDURE[node: StructureNode, da: DisplayArray, I, J: CARDINAL],

 -- now the old logical node procs

 Save: PROCEDURE[StructureNode, --to--STREAM],
 Act: PROCEDURE[info: StructureNode, I, J: CARDINAL, action: Action, p1, p2: REF ANY] RETURNS[StructureNode, CARDINAL, CARDINAL], -- returns nil if action successful
 Substitute: PROCEDURE[info: StructureNode, newText, oldText: Rope.ROPE],
 Abandon: PROCEDURE[StructureNode],
 Verify: PROCEDURE[StructureNode]
 ];

PrePaintPass: TYPE = {first, second};


-- following deals with a display array

DACell: TYPE = REF DACellBody;
DACellBody: TYPE;

RowHandle: TYPE = REF RowHandleBody;
RowHandleBody: TYPE;

ColHandle: TYPE = REF ColHandleBody;
ColHandleBody: TYPE;


DisplayArray: TYPE = REF DisplayArrayBody;
DisplayArrayBody: TYPE;

CreateDisplayArray: PROCEDURE[StructureNode] RETURNS[StructureNode, DisplayArray];
AbandonDisplayArray: PROCEDURE[DisplayArray];

AddColumnAt: PROCEDURE[da: DisplayArray, I: CARDINAL];
AddRowAt: PROCEDURE[da: DisplayArray, J: CARDINAL];
DeleteColumnAt: PROCEDURE[da: DisplayArray, I: CARDINAL];
DeleteRowAt: PROCEDURE[da: DisplayArray, J: CARDINAL];

SetElementAt: PROCEDURE[da: DisplayArray, I, J: CARDINAL, sn: StructureNode, info: REF ANY];
GetElementAt: PROCEDURE[da: DisplayArray, I, J: CARDINAL] RETURNS[sn: StructureNode, info: REF ANY];

SetRowInfoAt: PROCEDURE[da: DisplayArray, J: CARDINAL, info: REF ANY] RETURNS[RowHandle];
GetRowInfoAt: PROCEDURE[da: DisplayArray, J: CARDINAL] RETURNS[REF ANY];
GetRowNumber: PROCEDURE[RowHandle] RETURNS[CARDINAL];

SetColInfoAt: PROCEDURE[da: DisplayArray, I: CARDINAL, info: REF ANY] RETURNS[ColHandle];
GetColInfoAt: PROCEDURE[da: DisplayArray, I: CARDINAL] RETURNS[REF ANY];
GetColNumber: PROCEDURE[ColHandle] RETURNS[CARDINAL];

MarkElementDirty: PROCEDURE[da: DisplayArray, I, J: CARDINAL];





GetContextDA: PROCEDURE[da: DisplayArray] RETURNS[StructureNode, --I-- CARDINAL, --J-- CARDINAL]; -- this procedure is called from a parallel structure, when that structure fails to accept an offered action.


-- following procedure is called from a node pointed to by dac, when that node fails to accept an offered action. The node received dac via a previous DisplayNodeProcs.NoteEnclosingCell.

GetContextDACell: PROCEDURE[dac: DACell] RETURNS[--enclosing structure-- StructureNode, --I of dac-- CARDINAL, --J of dac-- CARDINAL, --contents of dac-- StructureNode];





-- following error may get generatred during loading

BadFormatLoadFile: ERROR;

END..

-- September 24, 1982 2:22 pm: Sturgis, started StructureNodes, a reorganization of StructureNode, from scratch
-- September 26, 1982 5:18 pm: add some display array actions
-- October 2, 1982 4:15 pm: add a procedure (to be exported by newcalcimpl) to inform about selections.
-- October 2, 1982 4:23 pm: also replace get enclosing da cell with a procedure that tries an action, and if it fails, then returns inclosing information.
-- RTE: October 3, 1982 12:49 pm: unable to do AppendRow on a GCellArray. Problem is that existing selection mechanism is tooo indirect, and there was no appropriate context for the GCellArray, since it was at the splice into the old structures. Decided to rearange the selection mechanism so that controller calls Act directly on a logical node, which, when it fails to perform the act, returns the enclosing context. Thus change a few procedrue calls to make this possible. Remove DoAct on a DACell, dd GetContext on a DACell and on a DisplayArray. Arrange for LN.Act to return enclosing context when it fails to perform the act. Also, NoteSelection now deliveres a LogicalNode, rather than a DACell.
-- change: October 6, 1982 5:12 pm: remove NoteSelection (moving to GCell).
-- October 8, 1982 12:21 pm: add column of rows
-- October 10, 1982 1:42 pm: move action and BadFormatLoadFile in from StructureNode, thus we will be able to do away with StructureNode.
-- October 11, 1982 2:21 pm: remove gcellarray procedures (to gcell.mesa).

-- October 14, 1982 3:50 pm: load and create column of rows now in GCell interface.
-- October 20, 1982 3:54 pm: add Insert, delete, and append Page actions
-- October 22, 1982 2:30 pm: add col and row info and handles. To support row and column summers.
-- October 26, 1982 4:44 pm: add moveSelectionToNext, and Previous.
-- change: November 2, 1982 4:21 pm: add assorted substituteActions, and two REF ANY params to LogicalNodeProcs.Act (to carry substitution action ropes).
-- November 3, 1982 3:09 pm: add Substitute to Logical nodes procs.
-- November 3, 1982 5:55 pm: add NullAction
-- November 14, 1982 1:41 pm: add NoteItemSelection and NoteArraySelection
-- February 25, 1983 2:46 pm: to save entries in ref count table, convert to a single node type, structureNode, rather than two (logical node, displaynode). there will be problems for gcell arrays.
-- February 27, 1983 2:05 pm: unfortunately, GCellArrays must store the gcell as well as an IdTable in each slot.
-- February 28, 1983 10:23 am: temporary until next fix, arrange for GetContextDAC to also return the StructureNode pointed to by the DAC. This will allow current selection mechanisms to continue to work.
-- February 28, 1983 2:08 pm: add "NoteCoordinates" structure node routines. Will be called each time coordinates change.
-- March 8, 1983 11:28 am: add UnPaint to StructureNode Procs, and add MarkElementDirty to DisplayArray procedures..
-- June 28, 1984 3:16:13 pm PDT: add CreateHCellArray.
-- July 17, 1984 4:56:01 pm PDT: add a Paint phase to follow PrePaint, so that final painting occur without constant flushing of Viewers cache.
-- July 30, 1984 10:14:33 am PDT: add MarkCellInteresting