// ReName.sr

get "BRAVO1.DF"
get "AltoFileSys.d";
get "vm.DF";
get "ST.DF";
get "DIR.DF";
get "bfs.def";

// Incoming procedures

external
	[ move
	BravoCreateFile
	stcopy
// 	BrMakeLogEntry
	LeaderPage
	NextSn
	EnumerateFp
	ActOnPages
	InitializeCbStorage
	DoDiskCommand
	GetCb
	errhlta
	opens
	RealDA
	movec
	assignbp
	remakevmtb
	clearbp
	hpfree
	hpalloca
	AppendVer
	sbwsize
	]


// Incoming statics

external
	[ mpfnof
	DCread
	cfaSysDirEnd
	eofDA
	DCwriteLabel
	fillInDA
	dnbp
	rgvpa
	rgbs
	rglastused
	macbp
	mpfnsb
	]


// Outgoing procedures

external
	[ ReName
	]

// Outgoing statics

external	[ vfptrNew
	vfptrOld
	] 

// Outgoing statics

static	[ vfptrNew
	vfptrOld
	] 

// R E N AM E
//
let ReName(nmd,sbFile,ver) be
[ let fptrNew = lv nmd >> NMD.afptr
let fptrOld = vec lFP; move(fptrNew,fptrOld,lFP)
nmd >>NMD.ver = ver; stcopy(lv nmd >> NMD.asbFile,sbFile)
if mpfnof ! fndir eq ofNil then
	[ opens(fndir,lv cfaSysDirEnd >> CFA.fp,false,true)
	(mpfnof ! fndir) >> OF.wf = true
	] 
NextSn(lv fptrNew >> FP.serialNumber)
BravoCreateFile(nmd,false)
// BrMakeLogEntry(fptrOld,typLogRenameFile,fptrNew)
LeaderPage(fptrOld,nmd,false)
ChangeFptr(fptrOld,fptrNew)
InvalidateFptr(fptrOld,fptrNew)
UpdateFn(fptrOld,fptrNew,sbFile,ver)
] 

// U P D A T E F I D
//
and UpdateFn(fptrOld,fptrNew,sbFile,ver) be
[ let fileIdNew = vec 3; FptrToFileId(fileIdNew,fptrNew)
let fileIdOld = vec 3; FptrToFileId(fileIdOld,fptrOld)
for fn = 0 to maxfn-1 do
	[ if mpfnof ! fn eq ofNil then loop
	let tfileId = lv ((mpfnof ! fn) >> OF.fileid)
	if FfileIdsEq(fileIdOld,tfileId) then
		[ move(fileIdNew,tfileId,3)
		hpfree(mpfnsb ! fn);
		mpfnsb ! fn = hpalloca(sbwsize(sbFile)+4)
		stcopy(mpfnsb ! fn,sbFile)
		AppendVer(mpfnsb ! fn,ver)
		] 
	] 
] 

and FfileIdsEq(fileId1,fileId2) = valof
[ for i = 0 to 2 do
	if fileId1 ! i ne fileId2 ! i then resultis false
resultis true
] 

and FptrToFileId(fileId,fptr) be
[ fileId ! 0 = fptr >> FP.version;
move(lv fptr >> FP.serialNumber,fileId+1,2); 
] 

// U P D A T E F I L E P T R
//
and InvalidateFptr(fptrOld,fptrNew) be
[ vfptrOld = fptrOld
vfptrNew = 0;
EnumerateFp(compareFileids)
unless vfptrNew eq 0 then
	movec(vfptrNew,vfptrNew+2,-1) 
] 

// C O M P A R E F I L E I D S
//
and compareFileids(filePtr) be
[ for i = 0 to 2 do
	if (filePtr ! i ne vfptrOld ! i) then return
vfptrNew = filePtr
] 

// C H A N G E F P T R
//
and ChangeFptr(fptrOld,fptrNew) be
[ let daFirst = RealDA(fptrOld >> FP.leaderVirtualDa)
let pgnFirst = 0; let fileIdOld = vec 3; let fileIdNew = vec 3
FptrToFileId(fileIdOld,fptrOld); FptrToFileId(fileIdNew,fptrNew)
let mpBpgnCa = vec maxbp+2; 
let n = 0
for bp = 0 to macbp-1 do
	[ if rglastused ! bp eq -1 then loop
	if (rgbs ! bp) << BS.dirty then clearbp(bp)
	mpBpgnCa ! n = dnbp ! bp
	rgvpa ! bp = -1
	n = n+1
	] 
if n eq 0 then errhlta(200)
remakevmtb()
let daPrev = 0
while daFirst ne eofDA do
	[ let mpPgnDa=vec maxbp+3; 
	movec(mpPgnDa, mpPgnDa+maxbp+1, fillInDA)
	mpPgnDa=mpPgnDa-pgnFirst+1; mpPgnDa!pgnFirst=daFirst
	mpPgnDa!(pgnFirst-1)=daPrev
	let nc = nil
	let lastPageFound=ActOnPages(mpBpgnCa-pgnFirst, mpPgnDa, fileIdOld, pgnFirst,
	  pgnFirst+n-1, DCread, lv nc, 0)

	let zone=vec CBzoneLength;
	InitializeCbStorage(zone, CBzoneLength, pgnFirst,
	  Wretry, true)
Wretry:	for i=zone>>CBZ.currentPage to lastPageFound do
		[
		let cb=GetCb(zone)
		cb>>CB.label.next=mpPgnDa!(i+1)
		cb>>CB.label.previous=mpPgnDa!(i-1)
		cb>>CB.label.numChars=(i eq lastPageFound ?
		  nc, #1000)
		DoDiskCommand(cb, mpBpgnCa!(i-pgnFirst),mpPgnDa!i, fileIdNew, i, DCwriteLabel)
		]
	while rv zone>>CBZ.queueHead ne 0 do GetCb(zone)

	pgnFirst=lastPageFound+1; daFirst=mpPgnDa!pgnFirst
	daPrev=mpPgnDa!(pgnFirst-1)
	]
]