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

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

	IMPORT	D_AlertBox
	IMPORT	D_BLForgetLists
	IMPORT	D_BLGetSel
	IMPORT	D_BLMakeList
	IMPORT	D_BLModalDialog
	IMPORT	D_BLSelect
	IMPORT	CaretOff
	IMPORT	D_CloseDialog
	IMPORT	D_EscFilter
	IMPORT	D_FastMult
	IMPORT	W_GetDsString
	IMPORT	D_GetNewModalDialog
	IMPORT	D_GrowHandle
	IMPORT	W_indexPtr
	IMPORT	W_MakeCaret
	IMPORT	D_MemoryError
	IMPORT	W_MergeDlg
	IMPORT	W_MergeDocName
	IMPORT	W_MergeDocWin
	IMPORT	D_NeedHand
	IMPORT	W_NoDBs
	IMPORT	D_NumWins
	IMPORT	W_PasteStr
	IMPORT	D_SendMessage
	IMPORT	D_StringBuffer
	IMPORT	D_UnLock
	IMPORT	W_UpdateAfter
	IMPORT	W_WhichDBlen
	IMPORT	W_WhichDBname
	IMPORT	D_WinNameTable
	IMPORT	D_WinPtrTable
	IMPORT	W_dbNames
	IMPORT	W_DbSelectDlg
	IMPORT	W_dsBobList
	IMPORT	W_dsDialog
	IMPORT	W_dsNumItems
	IMPORT	W_EndLine
	IMPORT	W_EndOffset
	IMPORT	W_EndPar
	IMPORT	W_mfBobList
	IMPORT	W_mfDialog
	IMPORT	W_mfNumItems
	IMPORT	W_Selected
	IMPORT	W_StartLine
	IMPORT	W_StartOffset
	IMPORT	W_StartPar

********************************************************************
*
*	Includes...
*
*
*
*
* Monday, May 1, 1989 7:29:57 AM
********************************************************************

****************************************************************
*
*   W_StripDBName
*
****************************************************************
W_StripDBName	PROC	EXPORT

	input	srcstr:l,dststr:l
	BEGIN

	lda	[srcstr]
	and	#$00FF
	SubWord	a,#7,[dststr]
	tay
	
	addwl	#1,srcstr	 	; copy the string (w/o W_Leading space)

	shortm
loop
	lda	[srcstr],y
	sta	[dststr],y
	dey
	bne	loop

	longm

	RETURN
	ENDP

****************************************************************
*
*   W_PickMergeDB -- choose a merge database document
*
****************************************************************
W_PickMergeDB	PROC	EXPORT
		;Using	D_WindowData
		;Using	W_PMergeData
		;Using	W_MergeDlgData

	local	ArraySize:w,Index:w,DBIndex:w,WinsSeen:w,Item:w
	local	WinArrayHand:l,WinArrayPtr:l,StrArrayHand:l,StrArrayPtr:l
	local	DvrString:l,MyString:l,WinPtr:l
	error	err
	BEGIN	+b

	stz	err
	stz	Index
	stz	DBIndex
	stz	WinsSeen
	MoveWord	#0,>W_dsNumItems

; First delete the old Merge Database.

	lda	W_MergeDocWin
	ora	W_MergeDocWin+2
	beq	makeArrays

	tool	_DisposeHandle,in=(W_MergeDocName:l)
	stzl	W_MergeDocName
	stzl	W_MergeDocWin

; Allocate 2 arrays, one for the window ptrs and one for the window strings.

makeArrays
	lda	>D_NumWins
	mul4	a
	sta	ArraySize

	call	D_NeedHand,in=(#0:w,ArraySize:w),out=(WinArrayHand:l),err=err
	jcs	exit

	call	D_NeedHand,in=(#0:w,ArraySize:w),out=(StrArrayHand:l),err=err
	jcs	cleanup1

; Cycle through the windows and make a list of all the DB windows.
; Our lists will be similar to the driver's.

winloop	moveLong	>D_WinPtrTable:Index,WinPtr
	cpzl	WinPtr
	jeq	nextwin2

	tool	_GetWRefCon,in=(WinPtr:l),out=(a:l)
	and	#$FF00
	cmp	#$0300
	jne	nextwin

	lda	>W_dsNumItems
	inc	a
	sta	>W_dsNumItems

; allocate handle for window string

	tool	_GetWTitle,in=(WinPtr:l),out=DvrString:l
	lda	[DvrString]
	and	#$00FF
	SubWord	a,#6,a			; -6 = -7 + 1

	call	D_NeedHand,in=(#0:w,a:w),out=(MyString:l),err=err
	jcs	cleanup2

	Call	W_StripDBName,in=(DvrString:l,[MyString]:l)

	MoveLong	[WinArrayHand],WinArrayPtr
	MoveLong	[StrArrayHand],StrArrayPtr

	ldx	Index
	ldy	DBIndex
	MoveWord	MyString,[StrArrayPtr]:y
	MoveWord	>D_WinPtrTable:x,[WinArrayPtr]:y
	iny
	iny
	MoveWord	MyString+2,[StrArrayPtr]:y
	MoveWord	>D_WinPtrTable+2:x,[WinArrayPtr]:y
	iny
	iny
	sty	DBIndex

nextwin	inc	WinsSeen
nextwin2	AddWord	Index,#4,Index

	CmpWord	WinsSeen,>D_NumWins
	jlt	winloop

; We've built our arrays, did we find any DB windows? If not warn user that no DB's were found.

	lda	>W_dsNumItems
	bne	somethere
	call	D_AlertBox,in=(#OkBox:w,#W_NoDBs:l),out=(x:w)
	inc	err
	brl	cleanup2

; Found at least one DB window. Save string handle. Put up select DB dialog.

somethere	MoveLong	StrArrayHand,>W_dbNames

	Call	D_GetNewModalDialog,in=(#W_DbSelectDlg:l),out=(>W_dsDialog:l)
	Call	D_BLMakeList,in=(#W_dsBobList:l)
	Call	D_BLSelect,in=(#W_dsBobList:l,#0:w)
	Call	D_BLModalDialog,in=(#D_EscFilter+$80000000:l),out=(Item:w)
	Call	D_CloseDialog,in=(>W_dsDialog:l)

; Check if user canceled if so clean up and return with err=#1.

	CmpWord	Item,#1
	beq	okay
canceled	inc	err
	bra	cleanup3

; Check if anything selected. If not treat as a cancel.

okay	call	D_BLGetSel,in=(#W_dsBobList:l),out=(a:w)
	cmp	#-1
	beq	canceled

; Get merge document name and window into WP globals.

	Mul4	a
	sta	Index
	MoveLong	[WinArrayHand],WinArrayPtr
	MoveLong	[StrArrayHand],StrArrayPtr
	MoveLong	[StrArrayPtr]:Index,W_MergeDocName
	MoveLong	[WinArrayPtr]:Index,W_MergeDocWin

; Dispose of bob list.

cleanup3	jsl	D_BLForgetLists

; Dispose of string array and any string handles we have allocated.

cleanup2	moveLong	[StrArrayHand],StrArrayPtr
	bra	@test
@loop	subword	a,#4,DBIndex
	tay
	cmpl	[StrArrayPtr]:y,W_MergeDocName
	beq	@test
	tool	_DisposeHandle,in=([StrArrayPtr]:DBIndex:l)
@test	lda	DBIndex
	bne	@loop
	tool	_DisposeHandle,in=(StrArrayHand:l)

; Dispose of the window array.

cleanup1	tool	_DisposeHandle,in=(WinArrayHand:l)

exit	RETURN
	ENDP

****************************************************************
*
*   W_VerifyMergeDB -- make sure there is a valid merge document
*	selected and update the document name if necessary
*
****************************************************************
W_VerifyMergeDB	PROC	EXPORT
		;Using	D_WindowData	  ; << Driver data segment
		;Using	W_PMergeData
		;Using	W_MergeDlgData

	local	index:w,winnum:w,winptr:l
	local	strptr:l,strhnd:l,mystring:l
	error	err
	BEGIN

	stz	err

	lda	W_MergeDocWin
	ora	W_MergeDocWin+2
	jeq	closed

	stz	winnum
	stz	index

winloop	cmpw	winnum,>D_NumWins
	jeq	closed
			
	movelong	>D_WinPtrTable:index,winptr
	
	addword	index,#4,index

	cpzl	winptr
	beq	winloop

	cmpl	winptr,W_MergeDocWin	; is it still a valid window?
	beq	foundit

	inc	winnum
	bra	winloop


foundit
	spacelong
	pushlong	winptr
	_GetWRefCon
	ply
	pla
	and	#$ff00
	cmp	#$0300			; is it still a DB window?
	bne	closed

; if so, assume it's the same, but it may have a new name
	tool	_GetWTitle,in=(winptr:l),out=(strptr:l)

	lda	[strptr]
	and	#$00FF
	SubWord	a,#6,a			; -6 = -7 + 1

	Call	D_GrowHandle,in=(#0:w,a:w,W_MergeDocName:l),err=(err)
	bcs	exit

	movelong	W_MergeDocName,mystring
	Call	W_StripDBName,in=(strptr:l,[mystring]:l)
	bra	exit

closed
	Call	W_PickMergeDB,err=err

exit
	RETURN
	ENDP

****************************************************************
*	Put the field name into MergeStr+1 << KLUDGE >>	   ;
****************************************************************
W_GetMfString	PROC	EXPORT
		;Using	D_UtilData	<<driver<<
		;Using	W_PMergeData
		;Using	W_MergeDlgData

	input	which:w
	local	temp:l
	BEGIN	+b

	movelong	W_MergeDocWin,MessWin

	asl	which
	asl	which
	ldy	which
	movelong	>W_indexPtr,temp
	movelong	[temp]:y,MessIndex

	spacelong
	pushword	#3		; (DB)
	pushword	#$1303
	pushlong	#FieldMess
	jsl	D_SendMessage
	ply
	ply

	RETURN

FieldMess
MessWin	DS.B	4
MessIndex	DS.B	4
	DC.L	D_StringBuffer+1

	ENDP

****************************************************************
*
*   W_AddMergeField
*
****************************************************************
W_AddMergeField	PROC	EXPORT
		;Using	D_UtilData	; <<driver<<
		;Using	WPglobals
		;Using	W_PMergeData
		;Using	W_MergeDlgData

	local	item:w,strlen:w,temp:l,index:l
	error	err
	BEGIN	+b

; Clear error status, turn off caret, and verify that merge db exists.

	jsl	CaretOff
	call	W_VerifyMergeDB,err=err
	jcs	quit

; Activate DB merge window, then request number of fields and records. Don't care about # records.

	call	D_SendMessage,in=(#3:w,#$1305:w,W_MergeDocWin:l),out=(ax:l)
	call	D_SendMessage,in=(#3:w,#$1301:w,W_MergeDocWin:l),out=(a:w,a:w)
	bne	gotfields

; If no useable fields in merge document then warn user and exit.

	MoveLong	W_MergeDocName,temp
	tool	_ParamText,in=([temp]:l,#0:l,#0:l,#0:l)
	call	D_AlertBox,in=(#OkBox:w,#NoFields:l),out=(a:w)
	brl	nofield

; Request fields indexes from DB.

gotfields	sta	>W_mfNumItems
	call	D_SendMessage,in=(#3:w,#$1302:w,W_MergeDocWin:l),out=(Index:l),err=err
	jcs	nofield		

	tool	_Hlock,in=(Index:l)
	movelong	[index],>W_indexPtr
	MoveLong	W_MergeDocName,temp
	MoveLong	[temp],ax
	movelong	ax,temp

; Make sure we only use first 31 characters of a name.

	lda	[temp]
	and	#$00FF
	cmp	#31
	blt	gotsize
	lda	#31
gotsize	sta	strlen

; Move name from first entry in indexes list to whichDBname.

	addwls	#1,temp
	pushlong	#W_WhichDBname
	pushword	#0
	pushword	strlen
	_BlockMove

	addword	strlen,#10,>W_WhichDBlen

	call	D_GetNewModalDialog,in=(#W_MergeDlg:l),out=(>W_mfDialog:l)
	call	D_BLMakeList,in=(#W_mfBobList:l)
	call	D_BLSelect,in=(#W_mfBobList:l,#0:w)
	call	D_BLModalDialog,in=(#D_EscFilter+$80000000:l),out=(item:w)
	call	D_CloseDialog,in=(>W_mfDialog:l)

; If user cancels from dialog or nothing selected then simply exit; disposing of allocated memory.

	cmpw	item,#1
	jne	exit
	call	D_BLGetSel,in=(#W_mfBobList:l),out=(a:w)
	cmp	#-1
	beq	exit
	sta	item

; Put field name for the given item in D_StringBuffer+1.

	call	W_GetMfString,in=(item:w)
	pushword	item
	jsl	W_GetMfString	

; Mangle string to have "<" & ">" around it.

	lda	>D_StringBuffer   	
	and	#$ff00
	ora	#'<'
	xba
	inc	a
	inc	a
	sta	>D_StringBuffer
	and	#$ff
	tax			; (x=length)
	lda	#'>'
	sta	>D_StringBuffer,x

; If nothing selected then set end paragraph, line, and offset information.

	lda	W_Selected
	bne	pasteit

	moveword	W_StartPar,W_EndPar
	moveword	W_StartLine,W_EndLine
	moveword	W_StartOffset,W_EndOffset

pasteit	spaceword
	spaceword
	spaceword
	spaceword
	pushlong	#D_StringBuffer
	jsl	W_PasteStr
	plx
	pullword	W_StartOffset
	pullword	W_StartLine
	pullword 	W_StartPar

	pushword	W_StartPar
	pushword	W_StartLine
	jsl	W_UpdateAfter

	jsl	W_MakeCaret	; put the W_Caret in the right place!

; Dispose of the indexes provided by DB and the bob list.

exit	tool	_DisposeHandle,in=(Index:l)
	jsl	D_BLForgetLists

; Deactivate DB merge window.

nofield	call	D_SendMessage,in=(#3:w,#$1306:w,W_MergeDocWin:l),out=(ax:l)

quit	cmpw	err,#$201
	bne	@exit
	jsl	D_MemoryError

@exit	RETURN

NoFields	str '^0 contains no merge fields.'

	ENDP
	END

