// Bcpl SprucePList.Bcpl 
// Generate and create property lists

//last modified:
//Brian Badenoch January 18, 1980  12:00 PM, Change DUPLEX test
//Brian Badenoch August 8, 1979  12:51 PM, fix "DUPLEX" test
//Rick Tiberi August 3, 1979  11:28 AM

get "Streams.d"
get "SpruceDoc.d"
get "SpruceMisc.d"
get "SprucePrinters.d"

external // defined here
	[
	GenPrinterCapabilities
	GenJobStatus
	ParsePrintInstanceParams
	]

external // defined there
	[
	CopyString
	DoubleShr
	Endofs
	ForEach
	InitPListStream
	MoveBlock
	Nin
	Puts
	ReadCalendar
	ScanPList
	Stateofs
	StringCompare
	WriteBooleanProp
	WriteNumberProp
	WriteStringProp
	Zero
	]

external // statics defined there
	[
	Capabilities
	SproullerQ
	]

// ---------------------------------------------
let GenPrinterCapabilities(buf) = valof
// ---------------------------------------------
[
Zero(buf, 256)
let s = vec lFS; InitPListStream(s, buf, 512)
Puts(s, $( )
let now = vec 1; ReadCalendar(now)
WriteNumberProp(s, "ID", now, true)
WriteBooleanProp(s, "PRINT-INSTANCE", true)
if Capabilities & mTSPrint
	then WriteBooleanProp(s, "DUPLEX", true)
if Capabilities & mColor
	then WriteBooleanProp(s, "COLOR", true)
if Capabilities & mMailbox
	then WriteBooleanProp(s, "MAILBOX", true)
Puts(s, $) )
resultis Stateofs(s) //stream position
]

and
// ---------------------------------------------
let ParsePrintInstanceParams(buf, length, doc) = valof
// ---------------------------------------------
[
let s = vec lFS; InitPListStream(s, buf, length)
resultis ScanPList(s, PrintInstanceParam, doc)
]

and
// ---------------------------------------------
let PrintInstanceParam(name, value, doc) = valof
// ---------------------------------------------
[
if StringCompare(name, "PRINTED-FOR") eq 0 then
	[ manifest length = (size DocG.CreatStr/8)-1
	if value>>STR.length gr length
		then value>>STR.length = length
	CopyString(lv doc>>DocG.CreatStr, value)
	]
if StringCompare(name, "PRINTED-BY") eq 0 then
	[ manifest length = (size DocG.ByStr/8)-1
	if value>>STR.length gr length
		then value>>STR.length = length
	CopyString(lv doc>>DocG.ByStr, value)
	]
if (StringCompare(name, "DUPLEX") eq 0) & ((Capabilities & mTSPrint) ne 0) then
	[
	test (StringCompare(value, "TRUE")) eq 0 ifso doc>>DocG.duplex = true
		ifnot doc>>DocG.duplex = false
	]
if StringCompare(name, "HOLD") eq 0 then
	[ manifest length = (size DocG.Password/8)-1
	if value>>STR.length gr length
		then value>>STR.length = length
	CopyString(lv doc>>DocG.Password, value)
	doc>>DocG.protected = true
	]
if StringCompare(name, "ID") eq 0 then
	[
	Nin(value, lv doc>>DocG.id, true)
	]
if StringCompare(name, "FILE-BYTES") eq 0 then
	[
	let length = vec 1
	Nin(value, length, true)
	for i = 1 to LogPressRecordSize do DoubleShr(length)
	doc>>DocG.nPages = length!1
	]
if StringCompare(name, "COPIES") eq 0 then
	[
	Nin(value, lv doc>>DocG.nCopies)
	]
resultis true
]

and
// ---------------------------------------------
let GenJobStatus(buf) = valof
// ---------------------------------------------
[
let id = vec 1; MoveBlock(id, buf, 2)
let doc = ForEach(SproullerQ, CheckDocId, id)

Zero(buf, 256)
let s = vec lFS; InitPListStream(s, buf, 512)
Puts(s, $( )
WriteNumberProp(s, "ID", id, true)
let string = "Not found"
if doc then
	[
	string = "Pending"
	test doc>>DocG.needsPassword
		ifso string = "Waiting password"
	ifnot test doc>>DocG.printed
		ifso string = "Printed"
	ifnot if doc>>DocG.inProgress
		then string = "In progress"
	]
WriteStringProp(s, "STATUS", string)
Puts(s, $) )
resultis Stateofs(s) //stream position
]

and
// ---------------------------------------------
let CheckDocId(doc, id) = valof
// ---------------------------------------------
[ let docid = lv doc>>DocG.id
if (id!0 eq docid!0) & (id!1 eq docid!1)
	then resultis 3 //use this one; see ForEach
resultis 0
]