	load 'macros.dump'
	include 'driver.equ'
	include 'wp.equ'

;-----------------------------------------------
;
;   Imported addresses
;
;-----------------------------------------------

	IMPORT	D_BeachBall
	IMPORT	CaretOff
	IMPORT	D_ClearPrintFlags
	IMPORT	D_CloseWordBox
	IMPORT	X_CopyWPScrap
	IMPORT	W_CurDoc
	IMPORT	W_DeleteRange
	IMPORT	X_DisposeWPScrap
	IMPORT	W_FindLine
	IMPORT	W_GetAddr
	IMPORT	D_GetPrintHandle
	IMPORT	D_KillFont
	IMPORT	W_LastP
	IMPORT	W_MakeCaret
	IMPORT	D_MemoryError
	IMPORT	D_NeedHandle
	IMPORT	W_PasteText
	IMPORT	D_PrJobDialog
	IMPORT	W_PrintDoc
	IMPORT	D_PrintToIW
	IMPORT	D_PrintToLW
	IMPORT	W_RecutDoc
	IMPORT	W_SelectOff
	IMPORT	W_SelectOn
	IMPORT	D_SendMessage
	IMPORT	D_SetCursor
	IMPORT	W_UpdateDoc
	IMPORT	W_VerifyMergeDB
	IMPORT	D_WordBox
	IMPORT	W_EndLine
	IMPORT	W_EndOffset
	IMPORT	W_EndPar
	IMPORT	W_PHandle
	IMPORT	W_PPtr
	IMPORT	W_Selected
	IMPORT	W_StartLine
	IMPORT	W_StartOffset
	IMPORT	W_StartPar
	import	D_MyID
	import	D_ToolID

;-----------------------------------------------
;
;   Forward addresses and entries
;
;-----------------------------------------------

	ENTRY	W_GetFieldScrap
	ENTRY	W_MergeDocName
	ENTRY	W_MergeDocWin
	ENTRY	W_PutFieldData
	ENTRY	W_fieldstr
	ENTRY	W_numrecStr
	ENTRY	W_oldphand
	ENTRY	W_oldelin
	ENTRY	W_oldeoff
	ENTRY	W_oldepar
	ENTRY	oldsel
	ENTRY	W_oldslin
	ENTRY	W_oldsoff
	ENTRY	W_oldspar
	ENTRY	W_pmMessage
	ENTRY	W_recStr


********************************************************************
*
*	Includes...
*
* Wednesday, May 3, 1989 2:28:52 AM
********************************************************************




****************************************************************
*
*   W_PrintMerge
*
****************************************************************
W_PrintMerge	PROC		EXPORT
			;Using	D_GlobalData
			;Using	WPGlobals
			;Using	W_PMergeData

		local	hsize:l,scrap:l,docscrap:l
		local	numrecs:w,rec:w,temp:l
		local	par:w,oldLastP:w,IWFlag:w,LWFlag:w
		error	oops

		begin	+b

; Verify that a merge database window exists. If not then simply exit.

		stz	  oops
		jsl	  W_VerifyMergeDB
		bcc	  gotdoc
		brl	  bye

; Tell D_DB to swap in its active data. { D_Startup Message }

gotdoc	tool	_PurgeAll,in=(>D_MyId:w)
		tool	_PurgeAll,in=(>D_ToolID:w)
		tool	_CompactMem
		
		spacelong
		pushword #3			  
		pushword #$1305		  
		pushlong W_MergeDocWin
		jsl	  D_SendMessage
		pulllong ax

; Ask D_DB for the number of records/fields currently active in W_Document { Count }

		spacelong
		pushword #3			  
		pushword #$1301		  
		pushlong W_MergeDocWin
		jsl	  D_SendMessage
		pullword numrecs
		plx

; Convert number of records into a string to be displayed in word box.

gotnum	pushword numrecs
		pushlong #W_numrecStr+1
		pushword #4			  ; length
		pushword #0			  ; unsigned
		_Int2Dec

; Get job dialog. If user cancels or error occurs in job dialog then exit 
; after shutting down the database.

		spaceword
		spacelong
		pushlong W_CurDoc
		jsl	  D_GetPrintHandle
		jsl	  D_PrJobDialog
		sta	  oops
		pla
		jeq	  D_Shutdown
		lda	  oops
		jne	  D_Shutdown

; D_Save current print flags; clear them initially.

		lda	  >D_PrintToIW
		sta	  IWFlag
		lda	  >D_PrintToLW
		sta	  LWFlag
		jsl	  D_ClearPrintFlags

; Get size of W_Document paragraph array W_Handle and D_Save old W_Document paragraph W_Handle.

		spacelong
		pushlong W_PHandle
		_GetHandleSize
		pulllong hsize
		movelong W_PHandle,W_oldphand	   

; Make sure port is set to current D_WP W_Document.

		pushlong W_CurDoc
		_SetPort

		jsl D_KillFont			 ; SRP, et al, 4/6/89

; D_Save globals that will be changed so they can be restored latter.

		moveword W_Selected,oldsel		
		moveword W_StartPar,W_oldspar	   
		moveword W_StartLine,W_oldslin
		moveword W_StartOffset,W_oldsoff
		moveword W_EndPar,W_oldepar
		moveword W_EndLine,W_oldelin
		moveword W_EndOffset,W_oldeoff
		moveword W_LastP,oldLastP					 ; added by MRH (3/13/89)

; Turn W_Caret off and deselect.

		jsl	  CaretOff
		jsl	  W_SelectOff

; Fake a D_WP scrap containing the entire W_Document; initially allocated as X_Locked.

		spacelong				
		addlong  hsize,#2,s	  
		pushword #$8000		  
		jsl	  D_NeedHandle
		sta	  oops
		pulllong docscrap
		jcs	  restoreSelect

; Fake the D_WP scrap W_Document by putting the paragraph count in front of a copy
; of the W_Document paragraph array.

		movelong [docscrap],temp
		moveword W_LastP,[temp]	

		pushlong W_PPtr			; the rest is the same as the W_Document
		addlong  temp,#2,s	   	;  paragraph block!
		pushlong hsize
		_BlockMove
		pushlong docscrap
		_HunLock

		jsl	  D_BeachBall

; D_Main loop - for every record in the database do...

		moveword #0,rec
recloop	cmpw	 rec,numrecs	 
		jeq	  done

		jsr	  DisplayRecNum

; Copy the scrap of the original W_Document. If not enough memory to copy scrap then
; warn user and abort print merge.

		spacelong
		pushlong docscrap
		jsl	  X_CopyWPScrap
		sta	  oops
		pulllong scrap
		bcc	  gotscrap
		jsl	  D_CloseWordBox
		jsl	  D_MemoryError
		brl	  done

; Successfully copied WPscrap copy of W_Document. This is the copy in which we are going
; to replace merge fields with their corresponding data from the D_DB. Make D_WP think the
; copy is the current W_Document.

gotscrap	pushlong scrap
		_Hlock
		movelong scrap,W_PHandle
		movelong [scrap],W_PPtr

; Remove paragraph count from start of scrap so it looks like a W_Document and recut it
; just in case.

		addlong  W_PPtr,#2,s	   
		pushlong W_PPtr
		pushlong hsize
		_BlockMove

		jsl	  W_RecutDoc

; Replace all occurances of <fieldnames> with actual data in W_Document.

		pushword rec			 ; put in the real field data
		jsl	  W_PutFieldData
		sta	  oops
		bcs	  noprint

; Restore job dialog print D_State information. D_Save current port on stack before
; calling W_PrintDoc and restore the port afterward. W_PrintDoc is D_WP's print routine.

		lda	  IWFlag
		sta	  >D_PrintToIW
		lda	  LWFlag
		sta	  >D_PrintToLW

		SpaceLong
		PushLong	W_CurDoc
		_GetWTitle
		_PrSetDocName

		spacelong				
		_GetPort
		pushlong W_CurDoc
		jsl	  W_PrintDoc		
		sta	  oops
		_SetPort
		jsl	  D_KillFont
		jsl	  D_ClearPrintFlags

; Put paragraph count back in so W_Document looks like a scrap again then dispose it.

noprint	pushlong W_PPtr			
		addlong  W_PPtr,#2,s
		pushlong hsize
		_BlockMove
		movelong [scrap],temp
		moveword W_LastP,[temp]

		pushlong scrap		  
		jsl	  X_DisposeWPScrap

; Restore original paragraph count and D_Close the word box.

		moveword oldLastP,W_LastP					; added by MRH (3/13/89)
		jsl	  D_CloseWordBox

; If any errors occured while printmerging then exit loop else increment current
; record being merged and loop back for more.

		lda	  oops
		bne	  done
		inc	  rec
		brl	  recloop

; All through printing. Dispose of D_WP scrap copy of original W_Document.

done	pushlong docscrap		
		_DisposeHandle

; Restore the old W_Document.

		movelong W_oldphand,W_PHandle	   
		movelong W_oldphand,temp
		movelong [temp],W_PPtr
		moveword oldLastP,W_LastP					; added by TJH (4/3/89)

		jsl	  W_RecutDoc

; If we did not have any errors then check PrError for one.

		lda	  oops			
		bne	  restoreSelect   
		spaceword			   
		_PrError
		pla
		sta oops

; Restore original selection and insertion Q_Point information.

restoreSelect	moveword W_oldspar,W_StartPar	   
		moveword W_oldslin,W_StartLine	  
		moveword W_oldsoff,W_StartOffset
		moveword W_oldepar,W_EndPar
		moveword W_oldelin,W_EndLine
		moveword W_oldeoff,W_EndOffset
		moveword oldsel,W_Selected
		beq	  no_select
		jsl	  W_SelectOn
		bra	  D_Update

; Bring the W_Caret back if nothing W_Selected.

no_select	jsl	  W_MakeCaret

; Make sure D_WP doc is active port then force D_Update & clear D_Update event.

D_Update	pushlong W_CurDoc
		_SetPort
		pushlong W_CurDoc
		jsl	  W_UpdateDoc
		pushlong W_CurDoc
		_BeginUpdate
		pushlong W_CurDoc		  
		_EndUpdate

; Tell D_DB it can swap out active data again. { D_Shutdown }

D_Shutdown	spacelong
		pushword #3			  ; (D_DB)
		pushword #$1306		  ; deactivate merge doc
		pushlong W_MergeDocWin
		jsl	  D_SendMessage
		pulllong ax

; Restore Arrow D_Cursor and quit routine.

bye	pushword #ArrowCursor
		jsl	  D_SetCursor

		return

*--------------------------------------------------------------*
DisplayRecNum
		lda	  rec
		inc	  a
		pha
		pushlong #W_recStr+1
		pushword #4			  ; length
		pushword #0			  ; unsigned
		_Int2Dec
		
		MoveLong	W_MergeDocName,temp

		pushlong [temp]
		pushlong #W_numrecStr
		pushlong #W_recStr
		pushlong #0
		_ParamText

		pushlong #W_pmMessage
		jsl	  D_WordBox

		rts

		ENDP

****************************************************************
*
*   W_PutFieldData(rec:w) -- replace the field markers in the
*		current D_WP W_Document with data from record #rec in the
*		merging D_DB W_Document.
*
****************************************************************
W_PutFieldData	PROC		EXPORT
			;Using	WPglobals
			;Using	W_PMergeData

		input	rec:w
		local	par:w,slin:w,soff:w
		local	elin:w,eoff:w
		local	paddr:l,scrap:l
		error	oops

		begin

		pushlong W_CurDoc		  ; set the port for W_PasteText
		_SetPort

		moveword #1,par
ploop	moveword #W_TextHeader,soff

samepar	lda	  par
		ldx	  #0
		jsl	  W_GetAddr
		movelong ax,paddr

		ldy	  soff
cloop1	lda	  [paddr],y
		and	  #$ff
		cmp	  #'<'
		beq	  gotleft
		cmp	  #$20			; printing W_Char?
		bge	  nextchar1
crapout	cmp	  #$d			 ; CR?
		beq	  nextpar
		cmp	  #$9			 ; TAB?
		beq	  nextchar1
		cmp	  #$1			 ; font change?
		bne	  skip1
		iny
skip1	iny
nextchar1	iny
		bra	  cloop1

nextpar	inc	  par

		jsl	  D_BeachBall

		cmpw	 par,W_LastP
		ble	  ploop
		brl	  exit

gotleft	sty	  soff				; I found the beginning!  Look for a
		iny					  	; D_Close bracket, accumulating the field
		moveword #0,W_fieldstr	; name.
		ldx	  #0

cloop2	lda	  [paddr],y
		and	  #$ff
		cmp	  #'>'
		beq	  gotright
		cmp	  #$20				; printing W_Char?
		bge	  nextchar2
		brl	  crapout		 	; Anything else is illegal.

nextchar2	iny
		inc	  W_fieldstr			; change length
		inx
		cpx	  #254
		jge	  cloop1		  	; too long
		sta	  W_fieldstr,x	  	; put it into the string
		bra	  cloop2

gotright	lda	  W_fieldstr		; Is anything there at all?
		jeq	  cloop1		  	; '<>' is illegal!
		iny					  	; W_Skip the '>'
		sty	  eoff

		spacelong
		pushword rec
		pushlong #W_fieldstr
		jsl	  W_GetFieldScrap
		sta	  oops
		pulllong scrap
		jcs	  nopaste

		spaceword
		pushword par
		pushword soff
		jsl	  W_FindLine
		pullword slin

		spaceword
		pushword par
		pushword eoff
		jsl	  W_FindLine
		pullword elin

		spaceword
		spaceword
		spaceword
		pushword par
		pushword slin
		pushword soff
		pushword par
		pushword elin
		pushword eoff
		jsl	  W_DeleteRange
		pullword eoff
		pullword slin
		ply

		lda	  scrap
		ora	  scrap+2
		beq	  nopaste

		spaceword
		spaceword
		spaceword
		pushlong scrap
		pushword par
		pushword slin
		pushword eoff
		jsl	  W_PasteText
		pullword eoff
		ply
		ply

nopaste	moveword eoff,soff
		brl	  samepar

exit	return

		ENDP

****************************************************************
*
*   W_GetFieldScrap(rec:w,fname:l) -> scrap:l
*
****************************************************************
W_GetFieldScrap	PROC		EXPORT
			;Using	W_PMergeData

		input	rec:w,fname:l
		output   scrap:l
		error	oops

		begin

		movelong W_MergeDocWin,gfMessRec
		moveword rec,gfMessRec+4
		movelong fname,gfMessRec+6

		spacelong
		pushword #3
		pushword #$1304
		pushlong #gfMessRec
		jsl	  D_SendMessage
		sta	  oops
		pulllong scrap

		return

gfMessRec		DS.B 10

		ENDP

****************************************************************
*
*   W_PMergeData
*
****************************************************************
W_PMergeData	PROC		EXPORT
		EXPORT	oldsel
		EXPORT	W_oldspar
		EXPORT	W_oldslin
		EXPORT	W_oldsoff
		EXPORT	W_oldepar
		EXPORT	W_oldelin
		EXPORT	W_oldeoff
		EXPORT	W_oldphand
		EXPORT	W_pmMessage
		EXPORT	W_MergeDocName
		EXPORT	W_MergeDocWin
		EXPORT	W_numrecStr
		EXPORT	W_recStr
		EXPORT	W_fieldstr

oldsel		DS.B 2
W_oldspar		DS.B 2
W_oldslin		DS.B 2
W_oldsoff		DS.B 2
W_oldepar		DS.B 2
W_oldelin		DS.B 2
W_oldeoff		DS.B 2
W_oldphand	DS.B 4

W_pmMessage	str 'Merging from ''^0'' (record ^2 of ^1)...'

W_MergeDocName		DC.L	0
W_MergeDocWin		DC.L	0
W_numrecStr			str '    '
W_recStr			str '    '

W_fieldstr		DS.B 256

		ENDP
		END

