// SpruceInterpret  (Main interpretation control) 
//
//

get "Spruce.d"
get "SpruceFiles.d"
get "PressFile.d"
get "Streams.d"

// outgoing procedures
external
	[
	Interpret
	ForceBreakPage
	]

// incoming procedures
external
	[
	OpenUp
	OpenForFonts
	CloseDown
	PressDirectories
	FontMakeup

	ShowInit
	ShowPage
	ScanPressPage
	ScanBreakPage
	ShowClose
	EnableComments
	FEEnter
	FEEnterLiteral
	FontPass

	SwapOnSpoolRequest

	PageData

	WindowSetBounds
	WindowSetPosition
	WindowReadBlock
	InitSpruceFile

	DoubleAdd
	MoveBlock
	FSInit
	]

// incoming statics

external
	[
	breakPage
	Capabilities
	comments
	LogoFont
	OverlayTop
	partNumber
	PressFile; BandFile; FontFile
	]

// Main file interpretation control

let Interpret(pDoc) be
	[
	SwapOnSpoolRequest() // ~~
	OpenUp(pDoc)
	EnableComments()

      // D I R E C T O R I E S -- read all Press directories,
      //  and also scan the font dictionary for good matches
	PressDirectories(pDoc)
	SwapOnSpoolRequest() // ~~

      // S C A N -- build bands for the file

	ShowInit(pDoc)
	let p=pDoc>>DocG.Pages
	let np=0

	for i=1 to pDoc>>DocG.nParts do
	   [
	   SwapOnSpoolRequest() // ~~
	   let EL=pDoc>>DocG.EL
	   let part=vec size PE/16
	   let s=vec 1
	   s!0=0; s!1=(i-1)*(size PE/16)
	   DoubleAdd(s, lv pDoc>>DocG.partStart)
	   WindowSetBounds(EL)
	   WindowSetPosition(EL, s)
	   WindowReadBlock(EL, part, size PE/16)
	   if part>>PE.Type eq PETypePage then
		[
		np=np+1
		partNumber = np
		if np ge pDoc>>DocG.UserPageStart &
		   np le pDoc>>DocG.UserPageEnd then
			[
			ShowPage(ScanPressPage, p, part)
			p>>PageG.whichSide = np rem 2  // even = 0, odd = 1, break = 2 (& see below)
			p=p+ size PageG/16
			]
		]
	   ]
	SwapOnSpoolRequest() // ~~
	let q = p - size PageG/16
	if q>>PageG.whichSide eq 1 do q>>PageG.whichSide = 2
	let incr, max = 0, 0
	if (Capabilities & mPimFiles) ne 0 do 
		[
		incr = size PageG/16
		test (Capabilities & mBlackHousing) ne 0
			ifso max = 3
			ifnot max = 2
		]
	if breakPage then for pass = 0 to max do
		ShowPage(ScanBreakPage, p+pass*incr, nil, pass+1)
	p>>PageG.whichSide = 2  // even = 0, odd = 1, break = 2  
	ShowClose()

     // Build font loads on band file, fill in DocG.Fonts entry
	OpenForFonts(pDoc)
	FontMakeup(pDoc)

     // Write out "checkpoint" information on the band file.
	PageData(pDoc)

	CloseDown(pDoc)
	]

// ForceBreakPage(pDoc)
// The SpruceCondition error handling code calls this function when Spruce suspects
//	a problem the user might cure, when the Interpretation overlay is resident, and
//	when this situation has not recursively occurred. This function tries to reinitialize
//	bands file processing, then to generate (Show) only a vestigial Break Page, 
//	including commentary that has been generated. The caller will subsequently try
//	to print this Break Page, then will return control to the spooler, in order to
//	report the problem and restore a clean state.
// If this function is unsuccessful in producing the break page, it will return false or
//	generate a (recursive) error that will be handled correctly elsewhere.
// When this function is called, errorPending is already set.

and ForceBreakPage(pDoc) = valof
  [
  unless breakPage resultis false // Don't bother
  // ~~ save comments over free storage re-init
  MoveBlock(OverlayTop, comments, maxComments+maxCommentWords+1)
  comments = OverlayTop
  OverlayTop = OverlayTop + (maxComments+maxCommentWords+1)
  FSInit() // toss out everything
  ZapFile(PressFile); ZapFile(BandFile); ZapFile(FontFile)

  // a Parody of the regular file interp. activity
  OpenUp(pDoc) // reinitialize bands processing
  pDoc>>DocG.nPages = 1
  pDoc>>DocG.nCopies = 1 // break page only situation
  FEEnterLiteral(pDoc, "Helvetica", 12, 0, 64, 0)
  FEEnter(pDoc, LogoFont)
  FontPass(pDoc)
  ShowInit(pDoc)
	let incr, max = 0, 0
	if (Capabilities & mPimFiles) ne 0 do 
		[
		incr = size PageG/16
		test (Capabilities & mBlackHousing) ne 0
			ifso max = 3
			ifnot max = 2
		]
  for pass = 0 to max do
	ShowPage(ScanBreakPage, (pDoc>>DocG.Pages)+pass*incr, nil, pass+1)
  (pDoc>>DocG.Pages)>>PageG.whichSide = 2  // even = 0, odd = 1, break = 2  
  ShowClose()
  OpenForFonts(pDoc)
  FontMakeup(pDoc)
  PageData(pDoc)
  CloseDown(pDoc)
  resultis true // take it away, printer!
  ]

and ZapFile(sF) be
	[ unless sF return
	let nextCom = sF>>SPruceFile.fParams; unless nextCom return
	nextCom = nextCom>>FParams.nextDiskCommand
	while @nextCom loop
	sF>>SPruceFile.valid = false; sF>>SPruceFile.cbz = 0
	]
  

// DCS, August 26, 1977  10:37 AM, moved from Spruce Main Loop
// August 26, 1977  11:00 AM, add ForceBreakPage
// October 27, 1977  4:46 PM, Pimlico!
// December 7, 1977  9:30 AM, add partNumber count
// December 21, 1977  4:22 PM, readjust disk buffer allocation before font makeup
// November 13, 1978  10:09 AM, invalidate old file structures before ForceBreak
// December 6, 1978  11:25 AM use Capabilities instead of printerDevice on break page pass determination
// March 7, 1979  12:21 PM four ScanBreakPage calls for 4-color puffin
// April 5, 1979  3:45 PM first cut two-sided printing for penguin
// August 1, 1979  3:10 PM, mBlack became mBlackHousing??!
// August 28, 1979  1:53 PM, put revAtt in forced breakpage
// October 3, 1979  4:29 PM, use new PageG structure
// November 16, 1979  2:23 PM, get logo font from LogoFont
//