-- PageListImpl.mesa
--  last edit                July 22, 1984 2:01:25 pm PDT  Sturgis

DIRECTORY
	ButtonCells USING[CreateBCell, ReLabelBCell],
	Convert USING[RopeFromCard],
   HCells USING[AppendHCellArrayInGroup, ConnectHCellArrayInGroup, CreateHCellArrayModeledAfter, CreateSummaryHCellArray, InsertHCellArrayInGroup, ReadCellText],
   IO USING[atom, char, Close, CR, FF, GetChar, GetRefAny, STREAM, int, Put, RIS, rope, RopeFromROS, ROS],
   NewCalcGlobal USING[Displayer, Document, DocumentProcs, 
   	CheckForDirtyDataInPage, ConnectInstalledItemArrays, ConnectLoadedItemArrays, CountOpenSlotsInPage, CreatePageDisplayer, DestroyPageDisplayer, GetHCellArrayAtSlot, InstallHCellArrayAtAnOpenSlot, GenerateSummaryArrays, LoadPageDisplayer, NoteNewPageMode, NoteNewPageName, NoteNewPageNumber, PageDisplayer, PageMode, RepaintOpenPage, SavePageDisplayer, ShowPageDisplayer, VerifyPageDisplayer],
   Rope USING[Cat, ROPE],
   StructureNodes USING[Action, AddColumnAt, AddRowAt, BadFormatLoadFile, CreateDisplayArray, DACell, DeleteRowAt, DisplayArray, GetContextDA, GetElementAt, PrePaintPass, SetElementAt, StructureNode, StructureNodeBody, StructureNodeProcs],
   ViewerClasses USING[Viewer];
  

PageListImpl: PROGRAM IMPORTS ButtonCells, Convert, HCells, IO, NewCalcGlobal, Rope, StructureNodes EXPORTS NewCalcGlobal =


BEGIN OPEN IO, NewCalcGlobal, ViewerClasses;

PageList: TYPE = REF PageListBody;
PageListBody: TYPE = RECORD[
	document: Document,
 	displayer: NewCalcGlobal.Displayer,
 	vParent: Viewer,
	sn: StructureNodes.StructureNode ← NIL, -- refers to this list itself
	da:  StructureNodes.DisplayArray ← NIL, -- this and next item refer to the associated Display Array
	daSn: StructureNodes.StructureNode ← NIL,
	nPages: CARDINAL ← 0
	];

PageCellInfo: TYPE = REF PageCellInfoBody;
PageCellInfoBody: TYPE = RECORD[
	pageNumberBCell:  StructureNodes.StructureNode,
	pageTitleBCell:  StructureNodes.StructureNode,
	pageModeBCell: StructureNodes.StructureNode,
	mode: PageMode,
	displayer: PageDisplayer
	];

TextForPageMode: ARRAY PageMode OF Rope.ROPE = [" ", "item", "summary"];

PageListStructureNodeProcs: REF StructureNodes.StructureNodeProcs ← NEW[StructureNodes.StructureNodeProcs ← [PageListCheckForDirtyData, PageListPreShow, PageListShowLine, PageListPrePrePaint, PageListPrePaint, PageListPaint, PageListUnPaint, PageListNoteEnclosingCell, PageListNoteCoordinates, SavePageList, ActPageList, SubstituteInPageList, AbandonPageList, VerifyPageList]];


CreatePageList: PUBLIC PROCEDURE[document: Document, displayer: NewCalcGlobal.Displayer, vParent: Viewer] RETURNS[StructureNodes.StructureNode] =
	BEGIN
	pgs: PageList ← NEW[PageListBody ← [
		document: document, 
		displayer: displayer,
		vParent: vParent
		]];
	pgs.sn ← NEW[StructureNodes.StructureNodeBody ← [pgs, PageListStructureNodeProcs]];
	[pgs.daSn, pgs.da] ← StructureNodes.CreateDisplayArray[pgs.sn];
	StructureNodes.AddColumnAt[pgs.da, 1];
	StructureNodes.AddColumnAt[pgs.da, 2];
	StructureNodes.AddColumnAt[pgs.da, 3];
	InstallPGSPageAt[pgs, 1, 1, CreatePageDisplayer[document, 1, "", individual], "foo", individual];
	RETURN[pgs.sn];
	END;
	
LoadPageList: PUBLIC PROCEDURE[document: Document, displayer: NewCalcGlobal.Displayer, vParent: Viewer, from: IO.STREAM, version: CARDINAL] RETURNS[StructureNodes.StructureNode] =
	BEGIN
	badChar: CHARACTER;
	case: ATOM;
	pgs: PageList ← NEW[PageListBody ← [
		document: document,
		displayer: displayer,
		vParent: vParent
		]];
	prevSummaryPage: PageDisplayer ← NIL;
	pgs.sn ← NEW[StructureNodes.StructureNodeBody ← [pgs, PageListStructureNodeProcs]];
	[pgs.daSn, pgs.da] ← StructureNodes.CreateDisplayArray[pgs.sn];
	StructureNodes.AddColumnAt[pgs.da, 1];
	StructureNodes.AddColumnAt[pgs.da, 2];
	StructureNodes.AddColumnAt[pgs.da, 3];
	
	DO
	   WHILE (badChar ← IO.GetChar[from]) = '  DO ENDLOOP; -- spin over blanks
      IF badChar # '( THEN StructureNodes.BadFormatLoadFile;
      case ← NARROW[from.GetRefAny[]];
      SELECT case FROM
      	$NamedPage, $NamedItemPage, $NamedSummaryPage =>
      		BEGIN
      		displayer: PageDisplayer;
      		pageName: Rope.ROPE ← HCells.ReadCellText[from];
      		pageMode: PageMode ← SELECT case FROM
      				$NamedPage => individual,
      				$NamedItemPage => groupItem,
      				$NamedSummaryPage => groupSummary,
      				ENDCASE => ERROR;
      		IF (badChar ← IO.GetChar[from]) # '( THEN StructureNodes.BadFormatLoadFile;
      		IF NARROW[from.GetRefAny[], ATOM] # $ColumnOfRows THEN StructureNodes.BadFormatLoadFile;
      		displayer ← LoadPageDisplayer[document, pgs.nPages+1, pageName, pageMode, from, version];
      		IF (badChar ← IO.GetChar[from]) # ') THEN StructureNodes.BadFormatLoadFile;
      		InstallPGSPageAt[pgs, pgs.nPages+1, pgs.nPages, displayer, pageName, pageMode];
      		IF case = $NamedItemPage THEN
      			BEGIN
      			ConnectOneItemArray: PROCEDURE[itemHcaSn: StructureNodes.StructureNode, itemKey: LONG CARDINAL, atRow: CARDINAL] =
      				BEGIN
      				SeeOneSummaryArray: PROCEDURE[summaryHcaSn: StructureNodes.StructureNode, summaryKey: LONG CARDINAL] RETURNS[continue: BOOLEAN] =
      					BEGIN
      					IF summaryKey = itemKey THEN
      						BEGIN
      						HCells.ConnectHCellArrayInGroup[itemHcaSn, summaryHcaSn, atRow];
      						RETURN[FALSE];
      						END
      					  ELSE RETURN[TRUE];
      					END;
      				GenerateSummaryArrays[prevSummaryPage, SeeOneSummaryArray];
      				END;
      			ConnectLoadedItemArrays[displayer, ConnectOneItemArray];
      			END; 
      		SELECT case FROM
      			$NamedSummaryPage => prevSummaryPage ← displayer;
      			$NamedItemPage => NULL;
      			ENDCASE => prevSummaryPage ← NIL;
      		END;
      	$Page =>
      		BEGIN -- pre named page format
      		displayer: PageDisplayer;
      		pageName: Rope.ROPE ← Rope.Cat["page ",  Convert.RopeFromCard[pgs.nPages+1]]; 
      		IF (badChar ← IO.GetChar[from]) # '( THEN StructureNodes.BadFormatLoadFile;
      		IF NARROW[from.GetRefAny[], ATOM] # $ColumnOfRows THEN StructureNodes.BadFormatLoadFile;
      		displayer ← LoadPageDisplayer[document, pgs.nPages+1, pageName, individual, from, version];
      		IF (badChar ← IO.GetChar[from]) # ') THEN StructureNodes.BadFormatLoadFile;
      		InstallPGSPageAt[pgs, pgs.nPages+1, pgs.nPages, displayer, pageName, individual]; 
      		END;
         $ColumnOfRows =>
	      	BEGIN -- pre multi page format
      	displayer: PageDisplayer;
      	pageName: Rope.ROPE ← Rope.Cat["page ",  Convert.RopeFromCard[pgs.nPages+1]];
	      	IF pgs.nPages # 0 THEN StructureNodes.BadFormatLoadFile;
	      	displayer ← LoadPageDisplayer[document, 1, pageName, individual, from, version];
      	InstallPGSPageAt[pgs, pgs.nPages+1, pgs.nPages, displayer, pageName, individual];
	      	END;
         $End => EXIT;
         ENDCASE => StructureNodes.BadFormatLoadFile;
      IF (badChar ← IO.GetChar[from]) # ') THEN StructureNodes.BadFormatLoadFile;
      ENDLOOP;
	RETURN[pgs.sn];
	END;


ShowPageList: PUBLIC PROCEDURE[info: StructureNodes.StructureNode, out: IO.STREAM] =
	BEGIN
   pgs: PageList ← NARROW[info.ref];
   FOR J: CARDINAL IN [1..pgs.nPages] DO
   	info: REF ANY;
		pgcj: PageCellInfo;
		Put[out, rope["page "], int[J]];
		Put[out, char[IO.CR], char[IO.CR]];
		[info: info] ← StructureNodes.GetElementAt[pgs.da, 1, J];
		pgcj ← NARROW[info];
   	ShowPageDisplayer[pgcj.displayer, out];
   	IF J # pgs.nPages THEN Put[out, char[IO.CR], char[IO.FF]];
   	ENDLOOP;
	END;

CheckForDirtyDataInPages: PUBLIC PROCEDURE[info: StructureNodes.StructureNode] =
	BEGIN
   pgs: PageList ← NARROW[info.ref];
   FOR J: CARDINAL IN [1..pgs.nPages] DO
   	info: REF ANY;
		pgcj: PageCellInfo;
		[info: info] ← StructureNodes.GetElementAt[pgs.da, 1, J];
		pgcj ← NARROW[info];
		CheckForDirtyDataInPage[pgcj.displayer];
   	ENDLOOP;
	END;

-- page list, display node interface

PageListCheckForDirtyData: PROCEDURE[node: StructureNodes.StructureNode] = 
	BEGIN
	pgs: PageList ← NARROW[node.ref];
	pgs.daSn.procs.CheckForDirtyData[pgs.daSn];
	END;

PageListPreShow: PROCEDURE[node: StructureNodes.StructureNode] RETURNS[lead, height: INTEGER, space, L, A, B, R, W: INTEGER] = 
	BEGIN
	pgs: PageList ← NARROW[node.ref];
	[lead, height, space, L, A, B, R, W] ← pgs.daSn.procs.PreShow[pgs.daSn];
	END;
	
PageListShowLine: PROCEDURE[node: StructureNodes.StructureNode, L, R, W: INTEGER, lineX: INTEGER, to: STREAM] = 
	BEGIN
	pgs: PageList ← NARROW[node.ref];
	pgs.daSn.procs.ShowLine[pgs.daSn, L, R, W, lineX, to];
	END;
   

PageListPrePrePaint: PROCEDURE[node: StructureNodes.StructureNode] RETURNS[lead, height: INTEGER, space, L, A, B, R, W: INTEGER] = 
	BEGIN
	pgs: PageList ← NARROW[node.ref];
	[lead, height, space, L, A, B, R, W] ← pgs.daSn.procs.PrePrePaint[pgs.daSn];
	END;
   

PageListPrePaint: PROCEDURE[node: StructureNodes.StructureNode, y, x, L, R, W: INTEGER, pass: StructureNodes.PrePaintPass] = 
	BEGIN
	pgs: PageList ← NARROW[node.ref];
	pgs.daSn.procs.PrePaint[pgs.daSn, y, x, L, R, W, pass];
	END;
   

PageListPaint: PROCEDURE[node: StructureNodes.StructureNode, dirtyOnly: BOOLEAN] = 
	BEGIN
	pgs: PageList ← NARROW[node.ref];
	pgs.daSn.procs.Paint[pgs.daSn, dirtyOnly];
	END;
   

PageListUnPaint: PROCEDURE[node: StructureNodes.StructureNode] = 
	BEGIN
	pgs: PageList ← NARROW[node.ref];
	pgs.daSn.procs.UnPaint[pgs.daSn];
	END;
   

PageListNoteEnclosingCell: PROCEDURE[node: StructureNodes.StructureNode, dac: StructureNodes.DACell] = 
	BEGIN
	pgs: PageList ← NARROW[node.ref];
	pgs.daSn.procs.NoteEnclosingCell[pgs.daSn, dac];
	END;
   

PageListNoteCoordinates: PROCEDURE[node: StructureNodes.StructureNode, da: StructureNodes.DisplayArray, I, J: CARDINAL] = 
	BEGIN
	END;
   



-- page list, logical node interface

SavePageList: PUBLIC PROCEDURE[info: StructureNodes.StructureNode, to: IO.STREAM] =
   BEGIN
   pgs: PageList ← NARROW[info.ref];
   FOR J: CARDINAL IN [1..pgs.nPages] DO
   	info: REF ANY;
		pgcj: PageCellInfo;
		[info: info] ← StructureNodes.GetElementAt[pgs.da, 1, J];
		pgcj ← NARROW[info];
   	Put[to, char['(], atom[SELECT pgcj.mode FROM
   			individual => $NamedPage,
   			groupItem => $NamedItemPage,
   			groupSummary => $NamedSummaryPage,
   			ENDCASE => ERROR]];
		SavePageDisplayer[pgcj.displayer, to];
   	Put[to, char[')]];
   	ENDLOOP;
   END;
   
SubstituteInPageList: PROCEDURE[info: StructureNodes.StructureNode, newText, oldText: Rope.ROPE] =
	BEGIN
	ERROR
	END;
   
AbandonPageList: PUBLIC PROCEDURE[info: StructureNodes.StructureNode] =
   BEGIN
   pgs: PageList ← NARROW[info.ref];
   WHILE pgs.nPages # 0 DO RemovePGSPageAt[pgs, pgs.nPages] ENDLOOP;
   END;  
    
ActPageList: PROCEDURE[info: StructureNodes.StructureNode, I, J: CARDINAL, action: StructureNodes.Action, p1, p2: REF ANY] RETURNS[StructureNodes.StructureNode, CARDINAL, CARDINAL] = 
   BEGIN
   pgs: PageList ← NARROW[info.ref];  
   SELECT action FROM
      InsertPage => InstallPGSPageAt[pgs, J, J, NIL, pgs.document.procs.getControlRope[pgs.document, newPageId], GetPGSPageModeFromModel[pgs, J, J]];
      AppendPage => InstallPGSPageAt[pgs, J+1, J, NIL, pgs.document.procs.getControlRope[pgs.document, newPageId], GetPGSPageModeFromModel[pgs, J+1, J]];
      DeletePage => RemovePGSPageAt[pgs, J];
      SetPageId => SetPGSPageId[pgs, J, pgs.document.procs.getControlRope[pgs.document, newPageId]];
      MakeSummaryPage => MakeSummaryPGSPageAt[pgs, J];
      CreateSummaryHCellArray => CreateArrayGroup[pgs, J];
      ENDCASE => 
      	BEGIN
      	cSn: StructureNodes.StructureNode; cI, cJ: CARDINAL;
      	[cSn, cI, cJ] ← StructureNodes.GetContextDA[pgs.da];
      	RETURN[cSn, cI, cJ];
      	END;
   RETURN[NIL, 0, 0];
   END;

VerifyPageList: PROCEDURE[info: StructureNodes.StructureNode] =
   BEGIN
   pgs: PageList ← NARROW[info.ref];
      
   -- for now, we just verify the internal structure of each page, but not the list as a whole
   FOR J: CARDINAL IN [1..pgs.nPages] DO
   	pgc: PageCellInfo ← NARROW[ StructureNodes.GetElementAt[pgs.da, 1, J].info];
   	VerifyPageDisplayer[pgc.displayer, pgc.mode];
   	ENDLOOP;
   END;

-- page list support procedures

-- remark: there is a crock here.  If the displayer argument is NIL, then we know we are not doing a load, therefore an append or insert.  If an itemPage is involved then we connect up the assorted arrays.  However, if it is a load (displayer argument # NIL), then the caller will do the connections.  This should be re-arranged so that the connections are done at the same logical level in both cases.  Also, the NIL argument test is not a clean way to make the decision.

InstallPGSPageAt: PROCEDURE[pgs: PageList, J: CARDINAL, modelJ: CARDINAL, displayer: PageDisplayer, pageName: Rope.ROPE, mode: PageMode] =
	BEGIN
	numberText: Rope.ROPE ← Rope.Cat["page ", Convert.RopeFromCard[J]];
	numBCell: StructureNodes.StructureNode;
	titleBCell: StructureNodes.StructureNode;
	modeBCell: StructureNodes.StructureNode;
	pgc: PageCellInfo; 
	

	[numBCell] ← ButtonCells.CreateBCell[pgs.document, pgs.displayer, pgs.vParent, numberText, "page 99", PageNumberProc, pgs, TRUE];
	[titleBCell] ← ButtonCells.CreateBCell[pgs.document, pgs.displayer, pgs.vParent, pageName, "a long title]", PageTitleProc, pgs, TRUE];
	[modeBCell] ← ButtonCells.CreateBCell[pgs.document, pgs.displayer, pgs.vParent, TextForPageMode[mode], "a long title]", PageModeProc, pgs, TRUE];
	
	IF displayer = NIL THEN
		SELECT mode FROM
			individual => displayer ← CreatePageDisplayer[pgs.document, J, " ", individual];
			groupItem =>
				BEGIN
				modelPageInfo: PageCellInfo ← IF modelJ > pgs.nPages OR modelJ = 0 THEN NIL ELSE NARROW[StructureNodes.GetElementAt[pgs.da, 1, modelJ].info];
				modelOutS: IO.STREAM ← IO.ROS[];
				modelRope: Rope.ROPE;
				modelInS: IO.STREAM;
				pageName: Rope.ROPE;
				badChar: CHARACTER;
				
				ConnectOneItemArray: PROCEDURE[itemHcaSn: StructureNodes.StructureNode, row, col: CARDINAL] =
					BEGIN
					relativeToHcaSn: StructureNodes.StructureNode ← GetHCellArrayAtSlot[modelPageInfo.displayer, row, col];
					SELECT TRUE FROM
						J = modelJ => HCells.InsertHCellArrayInGroup[itemHcaSn, relativeToHcaSn];
						J = modelJ+1 => HCells.AppendHCellArrayInGroup[itemHcaSn, relativeToHcaSn];
						ENDCASE => ERROR;
					END;
					
				SavePageDisplayer[modelPageInfo.displayer , modelOutS];
				modelRope ← IO.RopeFromROS[modelOutS];
				modelInS ← IO.RIS[modelRope];
				-- must skip over some stuff that represents an inconsistencey between SavePageDisplayer and LoadPageDisplayer
				pageName ← HCells.ReadCellText[modelInS];
				IF (badChar ← IO.GetChar[modelInS]) # '( THEN ERROR;
      		IF NARROW[modelInS.GetRefAny[], ATOM] # $ColumnOfRows THEN ERROR;
      		-- now we can proceed
				displayer ← LoadPageDisplayer[pgs.document, J, " ", mode, modelInS, 0];
				ConnectInstalledItemArrays[displayer, ConnectOneItemArray];
				modelInS.Close[];
				END; 
			groupSummary => ERROR;
			ENDCASE => ERROR;
		
	pgc ← NEW[PageCellInfoBody ← [numBCell, titleBCell, modeBCell, mode, displayer]];
	
	pgs.nPages ← pgs.nPages + 1;
	StructureNodes.AddRowAt[pgs.da, J];
	StructureNodes.SetElementAt[pgs.da, 1, J, numBCell, pgc]; -- holds page number text, and info
	StructureNodes.SetElementAt[pgs.da, 2, J, titleBCell, NIL]; -- holds page title texto
	StructureNodes.SetElementAt[pgs.da, 3, J, modeBCell, NIL]; -- holds mode text
	
	FOR JJ: CARDINAL IN (J..pgs.nPages] DO
		info: REF ANY;
		pgcjj: PageCellInfo;
		[info: info] ← StructureNodes.GetElementAt[pgs.da, 1, JJ];
		pgcjj ← NARROW[info];
		ButtonCells.ReLabelBCell[pgcjj.pageNumberBCell, Rope.Cat["page ", Convert.RopeFromCard[JJ]]];
		NoteNewPageNumber[pgcjj.displayer, JJ];
		ENDLOOP;
	
	IF pageName # NIL THEN SetPGSPageId[pgs, J, pageName];
	
	END;
	
GetPGSPageModeFromModel: PROCEDURE[pgs: PageList, J, modelJ: CARDINAL] RETURNS[PageMode] =
	BEGIN
	modelPageInfo: PageCellInfo ← IF modelJ > pgs.nPages OR modelJ = 0 THEN NIL ELSE NARROW[StructureNodes.GetElementAt[pgs.da, 1, modelJ].info]; 
	RETURN[ IF modelPageInfo = NIL THEN individual ELSE SELECT modelPageInfo.mode FROM
			individual => individual,
			groupItem => IF J = pgs.nPages+1 THEN individual ELSE groupItem,
			groupSummary => IF modelJ = J THEN individual ELSE groupItem,
			ENDCASE => ERROR];
	END;
	
RemovePGSPageAt: PROCEDURE[pgs: PageList, J: CARDINAL] =
	BEGIN
	info: REF ANY;
	pgc: PageCellInfo;
	[info: info] ← StructureNodes.GetElementAt[pgs.da, 1, J];
	pgc ← NARROW[info];
	
	IF J # pgs.nPages AND pgc.mode = groupSummary THEN
		BEGIN
		nextPgc: PageCellInfo ← NARROW[StructureNodes.GetElementAt[pgs.da, 1, J+1].info];
		IF nextPgc.mode = groupItem THEN RETURN;
		END;
		
	pgs.nPages ← pgs.nPages - 1;
	StructureNodes.DeleteRowAt[pgs.da, J];
	pgc.displayer ← DestroyPageDisplayer[pgc.displayer];
	
	FOR JJ: CARDINAL IN [J..pgs.nPages] DO
		infojj: REF ANY;
		pgcjj: PageCellInfo;
		[info: infojj] ← StructureNodes.GetElementAt[pgs.da, 1, JJ];
		pgcjj ← NARROW[infojj];
		ButtonCells.ReLabelBCell[pgcjj.pageNumberBCell, Rope.Cat["page ", Convert.RopeFromCard[JJ]]];
		NoteNewPageNumber[pgcjj.displayer, JJ];
		ENDLOOP;
	END;

SetPGSPageId: PROCEDURE[pgs: PageList, J: CARDINAL, newName: Rope.ROPE] =
	BEGIN
	info: REF ANY;
	pgc: PageCellInfo;
	[info: info] ← StructureNodes.GetElementAt[pgs.da, 1, J];
	pgc ← NARROW[info];
	ButtonCells.ReLabelBCell[pgc.pageTitleBCell, newName];
	NoteNewPageName[pgc.displayer, newName];
	END;
	
MakeSummaryPGSPageAt: PROCEDURE[pgs: PageList, J: CARDINAL] =
	BEGIN
	info: REF ANY;
	pgc: PageCellInfo;
	[info: info] ← StructureNodes.GetElementAt[pgs.da, 1, J];
	pgc ← NARROW[info];
	IF pgc.mode = individual THEN 
		BEGIN
		pgc.mode ← groupSummary;
		ButtonCells.ReLabelBCell[pgc.pageModeBCell, TextForPageMode[groupSummary]];
		NoteNewPageMode[pgc.displayer, groupSummary];
		END;
	END;

CreateArrayGroup: PROCEDURE[pgs: PageList, J: CARDINAL] =
	BEGIN
	info: REF ANY;
	pgc: PageCellInfo;
	highJ: CARDINAL ← pgs.nPages; -- tentative
	slotCount: CARDINAL;
	previousHcaSn: StructureNodes.StructureNode ← NIL;
	didIt: BOOLEAN ← FALSE;
	
		
	CreateTheSummaryArray: PROCEDURE[displayer: NewCalcGlobal.Displayer, vParent: ViewerClasses.Viewer, pageName: Rope.ROPE, rowNumber, colNumber: CARDINAL] RETURNS[StructureNodes.StructureNode] =
		BEGIN
		newHcaSn: StructureNodes.StructureNode ← HCells.CreateSummaryHCellArray[pgs.document, displayer, vParent, pageName];
		previousHcaSn ← newHcaSn;
		didIt ← TRUE;
		RETURN[newHcaSn];
		END;
	
	CreateAnItemArray: PROCEDURE[displayer: NewCalcGlobal.Displayer, vParent: ViewerClasses.Viewer, pageName: Rope.ROPE, rowNumber, colNumber: CARDINAL] RETURNS[StructureNodes.StructureNode] =
		BEGIN
		newHcaSn: StructureNodes.StructureNode ← HCells.CreateHCellArrayModeledAfter[previousHcaSn, pgs.document, displayer, vParent, pageName];
		HCells.AppendHCellArrayInGroup[newHcaSn, previousHcaSn];
		previousHcaSn ← newHcaSn;
		didIt ← TRUE;
		RETURN[newHcaSn];
		END;
	
	[info: info] ← StructureNodes.GetElementAt[pgs.da, 1, J];
	pgc ← NARROW[info];
	
	IF pgc.mode # groupSummary THEN RETURN;
	
	FOR JJ: CARDINAL IN (J..pgs.nPages] DO
		jjPgc: PageCellInfo ← NARROW[StructureNodes.GetElementAt[pgs.da, 1, JJ].info];
		IF jjPgc.mode # groupItem THEN {highJ ← JJ-1; EXIT};
		ENDLOOP;
	FOR JJ: CARDINAL IN [J..highJ] DO
		jjPgc: PageCellInfo ← NARROW[StructureNodes.GetElementAt[pgs.da, 1, JJ].info];
		IF (slotCount ← CountOpenSlotsInPage[jjPgc.displayer]) # 1 THEN RETURN;
		ENDLOOP;
	InstallHCellArrayAtAnOpenSlot[pgc.displayer, CreateTheSummaryArray];
	IF NOT didIt THEN ERROR;
	FOR JJ: CARDINAL IN (J..highJ] DO
		jjPgc: PageCellInfo ← NARROW[StructureNodes.GetElementAt[pgs.da, 1, JJ].info];
		didIt ← FALSE;
		InstallHCellArrayAtAnOpenSlot[jjPgc.displayer, CreateAnItemArray];
		IF NOT didIt THEN ERROR;
		ENDLOOP;
	END;
	
PageNumberProc: PROCEDURE[info: REF ANY] = -- runs when the page number is clicked
	BEGIN
	END;
	
PageTitleProc: PROCEDURE[info: REF ANY] = -- runs when the page title is clicked
	BEGIN
	END;
	
PageModeProc: PROCEDURE[info: REF ANY] = -- runs when the page mode is clicked
	BEGIN
	END;
	
RepaintAllOpenPages: PUBLIC PROCEDURE[info: StructureNodes.StructureNode] =
	BEGIN
	pgs: PageList;
	IF info = NIL THEN RETURN; -- probably during initialization of a displayer
	pgs ← NARROW[info.ref];
	FOR JJ: CARDINAL IN [1..pgs.nPages] DO
		info: REF ANY;
		pgcjj: PageCellInfo;
		[info: info] ← StructureNodes.GetElementAt[pgs.da, 1, JJ];
		pgcjj ← NARROW[info];
		RepaintOpenPage[pgcjj.displayer];
		ENDLOOP;
	END;


END..


--  July 20, 1984 8:00:03 am PDT: Sturgis, PageListImpl split from NewCalcImpl