// format1.sr


get "BRAVO1.DF"
get "FORMAT.DF"
get "CHAR.DF"
get "MSG.DF"
get "DISPLAY.DF"


// Incoming procedures

external	[
	format
	ult;
	ugt;
	mult;
	divmod;
	abs;
	min;
	max;
	errhlta
	binsearcha
	umin;
	umax;
	FChInSb
	mpDlDld
	xtoxd;
	]


// Incoming statics

external	[
	fmsg;
	msgtbl;
	rgxw;
	rgfinfo;
	vmaccr;
	vww;
	vxd;
	vxdlast;
	vxdfirst;
	vxdwidth;
	vcplast;
	vcpatxdl;
	vcpatxdr;
	vcpfirst;
	vdl;
	vtl;
	vfchoflow
	vYdofDl
	fontvis;
	rgcpfirst;
	rgyfirst;
	macww;
	vxleftmargstd;
	mpWwWwd;
	]


// Outgoing procedures

external	[
//	extendmsgtbl
	formatx;
	formatcp;
	formaty;
	XtbFromDxtb
	XtbFromTc
	mapxdxr;
	makefmsg
	widthvis
	ldToSgTop
	maxBlBlNew
	]


// Outgoing statics

external	[
	vdxtbStd
	]


// Local statics

static	[
	vdxtbStd
	]


// local manifests

manifest	[ 
	wtypenum= 1
	wtypetext= 2
	] 


// E X T E N D M S G T B L
// 
// let extendmsgtbl() be 
// [
// vfchoflow = true
// fmsg ! 0 = -1
// fmsg = fmsg-2
// ] 
 

// F O R M A T X
// catalogue no. = 112 
let formatx(ww,dl,xa) be
[
let wtype= nil
let wwd = mpWwWwd ! ww
// vupdatemag = vupdatemag % (vmag ne wwd>>WWD.mag)
let cpfirst = rgcpfirst ! dl;
test (vtl >> TL.ww eq ww) & (vtl >> TL.cpfirst eq cpfirst) & (vtl >> TL.mode eq modex) ifnot
	format(ww,cpfirst,modex)
ifso	vmaccr = vtl >> TL.maccr;
let xd = xa-xaudleft+wwd>>WWD.xdUd;
let xdcount = (mpDlDld(dl))>>DLD.xdFirst
vcpatxdr = cpfirst;
vcpatxdl = vcpatxdr;
let cr = 0;
fmsg = msgtbl;
let txw = nil;
let finfo = 0;
let cratxdl = 0
	[
	txw = rgxw ! cr;
	xdcount = xdcount+xtoxd(txw);
	if (xdcount gr xd) then
		break;
	if cr+1 ge vmaccr then
		break;
	finfo = rgfinfo ! cr
	cr = cr+1;
	test (txw eq 0) & (finfo << FINFO.newmsg) ifso
		[
		fmsg = fmsg+2;
		vcpatxdr = vcpatxdr + fmsg >> FMSG.runlen;
		]
	ifnot	[
		vcpatxdr = vcpatxdr+1;
//		unless finfo<<FINFO.ovstrike do
//			[
			vcpatxdl = vcpatxdr;
			cratxdl = cr
//			]
		]
	] repeat
vxdwidth = xtoxd(rgxw ! cr);
vxd = xdcount-vxdwidth;
if vxdwidth ls 0 then vxdwidth = 0;
let cratxdr = cr;
cr = cratxdl
vxdfirst = vxd;
test FChInSb((rgfinfo!cr)<<FINFO.char,"0123456789")
	ifso wtype= wtypenum
	ifnot wtype= wtypetext
until Wordsep(wtype,cr) do
	[
	cr = cr-1;
	vxdfirst = vxdfirst-xtoxd(rgxw ! cr);
	] 
if wtype eq wtypenum then 
	[ vxdfirst = vxdfirst + xtoxd(rgxw!cr); cr= cr+1 ]
vcpfirst = vcpatxdl - (cratxdl - cr);
vxdlast = xdcount-1;
cr = cratxdr + 1;
until Wordsep(wtype,cr) do
	[
	vxdlast = vxdlast+xtoxd(rgxw ! cr);
	cr = cr+1;
	] 
vcplast = vcpatxdr + (cr - cratxdr) - 1;
] 

// W O R D S E P
and Wordsep(wtype,cr) = valof
[
if wtype eq wtypetext then resultis (rgfinfo!cr)<<FINFO.trans ne 0
if wtype eq wtypenum then 
	resultis not FChInSb((rgfinfo!cr)<<FINFO.char,"0123456789.")
]


// F O R M A T C P

and formatcp(ww,dl,cp) be
[
let wwd = mpWwWwd ! ww
// vupdatemag = vupdatemag % (vmag ne wwd>>WWD.mag)
let tcp = rgcpfirst ! dl;
test (vtl >> TL.ww eq ww) & (vtl >> TL.cpfirst eq tcp) & (vtl >> TL.mode eq modex) ifnot
	format(ww,tcp,modex)
ifso	vmaccr = vtl >> TL.maccr;
let dld = mpDlDld(dl);
let xdcount = dld>>DLD.xdFirst;
let xdLast = dld>>DLD.xdLast;
let cr = 0;
let txw = nil;
fmsg = msgtbl;
	[
	txw = rgxw ! cr;
	test (txw eq 0) & (rgfinfo ! cr) << FINFO.newmsg ifso
		[
		fmsg = fmsg+2;
		tcp = tcp+fmsg >> FMSG.runlen;
		]
	ifnot	tcp = tcp+1;
	if ugt(tcp, cp) then break;
	xdcount = xdcount+xtoxd(txw);
	cr = cr+1;
	if (cr ge vmaccr) % (xdcount gr xdLast) then 
		[
		vxd = xdLast
		vxdwidth = 0;
		return;
		]
	] repeat
vxd = xdcount;
vxdwidth = txw rshift 5;
] 


// F O R M A T Y
// catalogue no.
and formaty(y) be
[ 
//for ww = 0 to macww-1 do
//	[ vww = ww;
//	if (rgylast ! ww ge y) then break;
//	] 
// let ty = rgyfirst ! 0;
// let dlfirst = rgdlfirst ! 0;
// vww = -1;
// for dl = 0 to rgdllast ! (macww-1) do
// 	[ vdl = dl;
// 	if dl eq dlfirst then
// 		[ vww = vww+1;
// 		dlfirst = rgmaxdl ! vww;
// 		ty = ty+heightbar;
// 		] 
// 	ty = ty+rgheightd ! dl;
// 	if ty gr y then break;
// 	] 
// if vww eq -1 then vww = 0;
// vdl = umin(rgdllast ! vww,vdl);
y = umin(rgyfirst ! macww, umax(y, rgyfirst ! 0))
vww = min(macww-1,binsearcha(rgyfirst, macww, y))
vdl = -1
vYdofDl = rgyfirst ! vww+2 // 2 for black line
let yd = vYdofDl
let wwd = mpWwWwd ! vww
let dld = mpDlDld(wwd>>WWD.dlFirst)
for dl = wwd>>WWD.dlFirst to wwd>>WWD.dlLast do
	[
	vdl = dl
	vYdofDl = yd
	yd = yd+dld>>DLD.dYdBm+dld>>DLD.ld
	if yd gr y then break
	dld = dld+lDld
	]
]


// X T B   F R O M   D X T B

and XtbFromDxtb(x, dxtb) = valof
[
let xRelative = x - vxleftmargstd + dxtbMin - 1
let tmod = nil
let itb = divmod(abs(xRelative), dxtb, lv tmod)
itb = (xRelative ls 0 ? -itb, itb) + 1
resultis vxleftmargstd + mult(itb, dxtb)
] // end XtbFromDxtb


// X T B   F R O M   T C

and XtbFromTc(x, tc, ttbl, ptcResult; numargs carg) = valof
[
let mpitbxtb = lv ttbl>>TTBL.ampitbxtb
let itbMac = ttbl>>TTBL.cw-1
if tc eq tcPlain then
	[
	let tx = x + dxtbMin
	let xtb = xtbNil
	let tcResult = tcPlain
	for titb = 0 to itbMac-1 do
		[
		let txtb = mpitbxtb ! titb
		if txtb ne xtbNil & txtb ge tx &
		    (xtb eq xtbNil % txtb ls xtb) then
			[
			xtb = txtb
			tcResult = titb+1
			]
		]
	if xtb eq xtbNil then
		xtb = XtbFromDxtb(x, vdxtbStd)
	if carg eq 4 then rv ptcResult = tcResult
	resultis xtb
	]
let itb = tc-1
let xtb = itb ls itbMac ? mpitbxtb ! itb, xtbNil
if xtb eq xtbNil then
	xtb = 0
resultis xtb
] // end XtbFromTc


// M A P X D X R
// max written open for speed:
and mapxdxr(xdhd, xdfirst, xd) = (xd-xdhd)-
	((xdfirst-xdhd gr xaudleft ? xdfirst-xdhd, xaudleft)
	& #177760)+dxaleft;


// M A K E F M S G

and makefmsg(mode, arg1, arg2; numargs n) be
[
fmsg = fmsg + msgsiz;
unless ult(fmsg-msgtbl, maxfmsg-3) do
	[
	vfchoflow = true
	fmsg ! 0 = -1
	fmsg = fmsg-2
	]
test mode eq modex ifso
	[
	if n ne 2 then errhlta(191)
	fmsg >> FMSG.runlen = arg1;
	]
ifnot	[
	if n ne 3 then errhlta(192);
	fmsg >> FMSG.look1 = arg1;
	fmsg >> FMSG.look2 = arg2;
	]
] 


// W I D T H V I S

and widthvis(char) = valof
[
if char gr #40 then errhlta(193);
let qdxa = rv (fontvis + char + fontvis ! char)
resultis (qdxa & #177776) lshift 4;
]


// L D T O S G T O P

and ldToSgTop(sg, newTop, newBl, newOfset) = valof
[
let dld = min(newTop-sg>>SG.topmax, min(sg>>SG.ldTop, newOfset))
if dld gr 0 then
	sg>>SG.ldTop = sg>>SG.ldTop-dld
resultis max(sg>>SG.topmax, newTop)
]


// M A X B L B L N E W

and maxBlBlNew(sg, newTop, newBl, newOfset) = max(sg>>SG.blmax, newBl)


// L D N E X T T O B L

and ldNextToBl(sg, newTop, newBl, newOfset) = valof
[
let dld = min(newBl-sg>>SG.blmax, min(sg>>SG.ldNext, -newOfset))
if dld gr 0 then
	sg>>SG.ldNext = sg>>SG.ldNext-dld
resultis max(sg>>SG.blmax, newBl)
]


// D O   O V S T R I K E
// 
// and DoOvstrike(mode, crFirst, crLast, xwFirst, pdx) be
// [
// if mode eq modex then
// 	[
// 	rgxw ! crLast = rgxw ! crFirst
// 	for cr = crFirst to crLast-1 do
// 		rgxw ! cr = 0
// 	return
// 	]
// let xwTot = rgxw ! crFirst
// let xCenter = xwFirst rshift 1
// let xCurrent = 0
// for cr = crFirst to crLast-1 do
// 	[
// 	let xw = rgxw ! (cr+1)
// 	let xChar = xCenter - xw rshift 1
// 	if mode ne modehc then
// 		[
// 		xChar = xChar + 16 & #177740
// 		rv pdx = max(rv pdx, max(xChar+xw-xwTot, -xChar))
// 		]
// 	rgxw ! cr = xChar - xCurrent
// 	xCurrent = xChar
// 	]
// rgxw ! crLast = xwTot - xCurrent
// ] end DoOvstrike