*****************************************************************************************************
* WP Copy/Paste Routines
* 
*    This file contains the routines used by WP to handle cutting and pasting.
*
*****************************************************************************************************

	load 	'macros.dump'
	include 	'driver.equ'
	include 	'wp.equ'
	include	'scrap.equ'
	
	IMPORT	D_BeachBall
	IMPORT	D_Deref
	IMPORT	D_GrowLHandle
	IMPORT	D_KillFont
	IMPORT	D_MemoryError
	IMPORT	D_UndoMemError
	IMPORT	D_Unlock

	IMPORT	W_CalcDocRect
	IMPORT	W_CalcFBytes
	IMPORT	W_CalcPages
	IMPORT	W_CollapseRulers
	IMPORT	W_CurDoc	
	IMPORT	W_DelSelect
	IMPORT	W_EndLine
	IMPORT	W_EndOffset
	IMPORT	W_EndPar
	IMPORT	W_FindFont
	IMPORT	W_FindLine
	IMPORT	W_GetAddr
	IMPORT	W_GetDoc
	IMPORT	W_GetParRec
	IMPORT	W_JunkLeft
	IMPORT	W_JunkRight
	IMPORT	W_LastP
	IMPORT	W_LessRoom
	IMPORT	W_LineToTopPixel
	IMPORT	W_MakeCaret
	IMPORT	W_MakeCr
	IMPORT	W_MakeEmptyBlock
	IMPORT	W_MakeRoom
	IMPORT	W_MakeLines
	IMPORT	W_MaxP
	IMPORT	W_PHandle
	IMPORT	W_PPtr
	IMPORT	W_PasteLine
	IMPORT	W_PasteOffset
	IMPORT	W_PastePar
	IMPORT	W_PtToText
	IMPORT	W_PutOnScreen
	IMPORT	W_ReadFont
	IMPORT	W_Selected
	IMPORT	W_SelectOff
	IMPORT	W_SetFullREct
	IMPORT	W_StartLine
	IMPORT	W_StartOffset
	IMPORT	W_StartPar
	IMPORT	W_UnUseRuler
	IMPORT	W_UndoEndLine
	IMPORT	W_UndoEndOffset
	IMPORT	W_UndoEndPar
	IMPORT	W_UndoOff
	IMPORT	W_UndoOn
	IMPORT	W_UndoStartLine
	IMPORT	W_UndoStartOffset
	IMPORT	W_UndoStartPar
	IMPORT	W_UndoHandle
	IMPORT	W_UpdateText
	IMPORT	W_UseRuler
	IMPORT	W_View
	IMPORT	W_WpCopy
	IMPORT	W_WriteFBytes2

	IMPORT	X_DisposeScrap
	IMPORT	X_PostScrap
	IMPORT	X_SwitchFont
	
	IMPORT	caretOff

	ENTRY	W_PasteText
	ENTRY	W_SplitBlock

*****************************************************************************************************
; W_MyPaste	( WindowPtr:long, Scrap:long, Type:word, Paste:word, Where:long )
;
;    This is the main paste vector for WP.  If the given scrap is of the correct type it will be
; pasted into the document for the given window. If Paste is 1 then use the Where field to
; determine where in the window the paste should take place. If Paste is 2 then paste is coming
; from an import. Memory errors are returned. Where is in window local coordinates.

W_MyPaste	PROC	EXPORT
	;Using 	wpglobals

	input 	window:l,Scrap:l,type:w,Paste:w,where:l
	local 	rect:r,ParCnt:w,WPtr:l,par:w,OldDoc:l
	error 	err
	begin 	+b

; Make sure that the scrap is a WP scrap if not dispose of it and exit with error #1.

	stz	err
	cmpw 	type,#WPText
	beq 	savedoc
	inc 	err
	call	X_DisposeScrap,in=(Type:w,Scrap:l)
	brl 	_exit
	
; Save current document so it can be restored before exiting. Turn carret off and clear the undo.

savedoc	movelong	W_CurDoc,OldDoc
	tool	_SetPort,in=(W_CurDoc:l)
	jsl 	caretOff
	jsl 	W_UndoOff

; Set port to given window and kill current font. Bring in document information.

	tool	_SetPort,in=(window:l)
	jsl 	D_KillFont
	call	W_GetDoc,in=(window:l)

; Strip page breaks if we are pasting into the header or footer of the document. Note: PageBreaks
; are guaranteed to always have a carriage return after them. ( ie next paragraph is guaranteed to be
; a real paragraph - no consecutive page breaks paragraph blocks ). Also Page break paragraphs will
; have for their text blocks the same text block used for the text before the page break.

	lda 	W_View
	jeq 	NoKillPB
	movelong 	[scrap],WPtr
	moveword 	[WPtr],ParCnt
	addwl	#2,WPtr

parloop	cmpw 	[WPtr]:#W_pAttr,#W_PgBrk
	bne 	nextpar

	movelong 	#0,[WPtr]:#W_pLineHand
	moveword 	#0,[WPtr]:#W_pAttr
	moveword 	#1,[WPtr]:#W_pLastLine
	movelong 	[WPtr]:#W_pBytes+W_pRulerHand,[WPtr]:#W_pRulerHand
	call	W_UseRuler,in=(#1:w,[WPtr]:#W_pBytes+W_pRulerHand:l)

nextpar	addwl	#W_pBytes,WPtr
	dec 	ParCnt
	bne 	parloop

; If placement type paste then deselect current text and move insertion point to new place in text
; before doing the paste.

NoKillPB	cmpw 	paste,#1
	bne 	noplace

	jsl 	W_SelectOff
	call	W_PtToText,in=(Where:l),out=(W_StartPar:w,W_StartLine:w,W_StartOffset:w)
	jsl 	W_MakeCaret

; Make sure the given paragraph line is on the screen. Get current document rect and adjust top of
; rect based to top pixel of start line.

noplace	call	W_PutOnScreen,in=(W_StartPar:w,W_StartLine:w,#0:l)
	call	W_CalcDocRect,in=(!rect:l)
	call	W_LineToTopPixel,in=(W_StartPar:w,W_StartLine:w),out=(rect:w,a:w)

; If directional paste or import then deselect and don't allow undo.

	lda 	paste
	beq 	RegUndo
	jsl 	W_DelSelect
	brl 	NoUndo

; Clear undo handle. If something is selected then save copy of it in undo handle. If we can't get
; enough memory for undo copy then ask if should continue anyway.

RegUndo	stzl 	W_UndoHandle
	lda 	W_Selected
	beq 	NoSelD

	spacelong
	pushword 	W_StartPar
	pushword 	W_StartLine
	pushword 	W_StartOffset
	pushword 	W_EndPar
	pushword 	W_EndLine
	pushword 	W_EndOffset
	jsl 	W_WpCopy
	sta	err
	pla
	plx
	bcc	putcopy
	
	call	D_UndoMemError,out=(a:w)
	cmp	#OK
	beq	noundo
	brl	exit

; Save copy of selected text in undo handle then delete selected text from document.

putcopy	movelong	ax,W_UndoHandle
	jsl 	W_DelSelect

; Enable undo menu item and place undo text. Remember undo information to restore selection.

NoSelD	call	W_UndoOn,in=(#W_PasteUndo:w)
	moveword 	W_StartPar,W_UndoStartPar
	moveword 	W_StartLine,W_UndoStartLine
	moveword 	W_StartOffset,W_UndoStartOffset

; Paste the scrap into the document. If memory error then return error to driver.

NoUndo	pha
	pha
	pha
	pushlong 	Scrap
	pushword 	W_StartPar
	pushword 	W_StartLine
	pushword 	W_StartOffset
	jsl 	W_PasteText
	sta	err
	bcc 	NoErr
	pla
	pla
	pla
	bra 	exit

; Successfully pasted text into document. Set new values for start offset, line, and paragraph.

NoErr	pullword 	W_StartOffset
	pullword 	W_StartLine
	pullword 	W_StartPar

; Save end position after paste into the undo information.

	moveword 	W_StartPar,W_UndoEndPar
	moveword 	W_StartLine,W_UndoEndLine
	moveword 	W_StartOffset,W_UndoEndOffset

; Erase the clip and erase the document rect; then update its contents.

	tool	_ClipRect,in=(!rect:l)
	tool	_EraseRect,in=(!rect:l)
	jsl 	W_UpdateText

; Set clip rect to port rect; put up caret; and collapse rulers.

exit	jsl 	W_SetFullRect
	jsl 	W_MakeCaret
	jsl	W_CollapseRulers

; Restore old document.

	call	W_GetDoc,in=(OldDoc:l)
_exit	return
	
	ENDP

*****************************************************************************************************
; W_GetCopy	( ): CopyHandle:xy
;
;   This routine will return a wpscrap for the current selection. A-reg will contain any errors and
; carry flag is set accordingly.

W_GetCopy	PROC	EXPORT

	spacelong
	pushword 	W_StartPar
	pushword 	W_StartLine
	pushword 	W_StartOffset
	pushword 	W_EndPar
	pushword 	W_EndLine
	pushword 	W_EndOffset
	jsl 	W_WpCopy
	plx
	ply
	rts
	
	ENDP

*****************************************************************************************************
; W_MyCut	( WindowPtr:long ):ImageRoutine:long
;
;    This routine is the cut vector entry point. It will copy the current selection and then delete
; it from the document. If not enough memory exists to copy then user will be asked told not enough
; memory to undo and be asked to continue or not. ImageRoutine is the routine to be called to draw
; the outline of what is being copied.

W_MyCut	PROC	EXPORT
	;Using 	wpglobals

	input 	window:l
	local 	Handle:l,OldDoc:l
	output 	ImageRoutine:l
	error	err
	begin 	+b

; Remember old active document and set document and port for given window.

	stzl	ImageRoutine
	movelong	W_CurDoc,OldDoc
	call	W_GetDoc,in=(Window:l)
	tool	_SetPort,in=(Window:l)

; If nothing is current selected then simply exit.

	lda 	W_Selected
	jeq 	exit

; Attempt to copy the current selection. If we can't get copy then return memory error to the driver.

	jsr	W_GetCopy
	sta	err
	jcs	exit
	movelong	xy,handle

; Can perform the copy so now clear caret and undo.

	jsl 	CaretOff
	jsl 	W_UndoOff

; Try and get copy for undo. If we can't then ask user whether we should continue or not.

	jsr	W_GetCopy
	sta	err
	bcc	putundo
	call	D_UndoMemError,out=(a:w)
	cmp	#OK
	beq	noundo
	stz	err
	tool	_DisposeHandle,in=(handle:l)
	bra	exit

; Have enough memory for undo copy. Save it in undo handle and setup undo menu item.

putundo	movelong	xy,W_UndoHandle
	call	W_UndoOn,in=(#W_CutUndo:w)

; Post the scrap, point to our image routine, set clip rect to the entire port, and delete the
; current selection.

noundo	call	X_PostScrap,in=(#WPText:w,Handle:l)

;	movelong 	#W_MyImage,ImageRoutine
	jsl 	W_SetFullREct
	jsl 	W_DelSelect

; Restore old document.

exit	call	W_GetDoc,in=(OldDoc:l)
	return
	
	ENDP

*****************************************************************************************************
; W_MyCopy	( WindowPtr:long ):ImageRoutine:long, Type:word, Scrap:long
;
;    This routine is the copy vector entry point. It will copy the current selection. Memory errors
; are returned. ImageRoutine is the routine to draw an image of the scrap for dragging. Passes back
; zero for no scrap. 

W_MyCopy	PROC	EXPORT
	;Using	WPGlobals

	input 	window:l
	output 	ImageRoutine:l,stype:w,OutHandle:l
	error 	err
	begin 	+b

; Clear error status and return scrap type. Save current document on stack and set current document
; to the given window's document. (and port)

	stz 	err
	stz 	stype
	stzl	ImageRoutine
	pushlong 	W_CurDoc
	call	W_GetDoc,in=(window:l)
	tool	_SetPort,in=(window:l)

; If nothing is selected then ignore call.

	lda 	W_Selected
	jeq 	exit

; Turn off caret and clear undo buffer.

	jsl 	CaretOff
	jsl 	W_UndoOff

; Get copy of current selection. If error then exit returning error to driver, else return wpscrap
; and type. Set Imageroutine.

	jsr	W_GetCopy
	sta	err
	bcs	exit

	movelong	xy,outhandle
	moveword 	#WPText,stype
;	movelong 	#W_MyImage,ImageRoutine

; Restore old document.

exit	jsl	  W_GetDoc

	return

	ENDP

*****************************************************************************************************
; W_MyImage	( Where:long )
;
;   This routine draw a rect 0,0,50,120 at where. 
; Note: No longer used.
;
;W_MyImage	PROC	EXPORT
;	input 	where:l
;	local 	rect:r
;	begin 	+b
;
;	movelong 	where,rect
;	addword 	where,#50,rect+4
;	addword 	where+2,#120,rect+4+2
;	tool	_FrameRect,in=(!Rect:l)
;
;	return
;
;	ENDP

*****************************************************************************************************
; W_PasteText ( Handle:l, Par:w, Line:w, Offset:w ): EndPar:w, EndLine:w, EndOffset:w
;
;   This routine does the actually work of pasting a scrap handle @ the given paragraph, line, and
; offset. The ending paragraph, line, and offset are returned. Memory errors are returned as well.

W_PasteText	PROC	EXPORT
	;Using 	wpglobals

	input 	handle:l,par:w,line:w,offset:w
	output 	Outpar:w,Outline:w,Outoffset:w
	local 	ptr:l,ParRec1:l,ParRec2:l,Block1:l,Block2:l
	local 	col1:w,font1:l,col2:w,font2:l,FBytes:l,TPtr:l
	local 	bytes:l,NewLastP:w,NewMaxP:w,NewPars:w,temp:w
	local 	BegRul:w,EndRul:w,RulRec:l,Offset1:w,Offset2:w,Ptr2:l
	local 	TextPtr:l,NewSize:l
	error 	err
	begin

; Save paragraph, line, and offset in global variables. Spin the beach ball.

	moveword 	par,W_PastePar
	moveword 	line,W_PasteLine
	moveword 	offset,W_PasteOffset
	jsl 	D_BeachBall

; Clear error status, flags, and high word of byte counters.

	stz 	err
	stz 	bytes+2
	stz 	FBytes+2
	stz 	BegRul
	stz 	EndRul

; Lock down the scrap handle. Point ParRec1 to first paragraph entry in scrap.

	rcall	D_Deref,in=(handle:ax),out=(ptr:ax)
	addlong 	#2,ptr,ParRec1

; Point ParRec2 to last paragraph entry in scrap.

	spacelong
	lda 	[ptr]
	dec 	a
	pha
	pushword 	#W_pBytes
	_Multiply
	addlong 	s,ParRec1,ParRec2

; Check if first paragraph entry is a page break. If it is we will need to add a carriage return
; paragraph to the scrap before we can process it.

	cmpw 	[ParRec1]:#W_pAttr,#W_PgBrk
	bne	NoTopPB
	jsr	addcrtop
	jcs	killscrap

NoTopPB	call	W_JunkLeft,in=(par:w,line:w,offset:w),out=(a:w)
	sta 	Offset1
	sta 	W_PasteOffset
	cmp 	#W_TextHeader
	bne 	NoBR
	inc 	BegRul
	
NoBr	call	W_JunkRight,in=(par:w,line:w,offset:w),out=(x:w)
	stx	Offset2
	lda	par
	jsl 	W_GetAddr
	movelong 	ax,Ptr2
	cmpb 	[Ptr2],#cr
	bne 	NoEr
	inc 	EndRul
	
NoEr	rcall	D_Deref,in=([ParRec1]:ax),out=(Block1:ax)
	rcall	D_Deref,in=([ParRec2]:ax),out=(Block2:ax)


;get font stuff

	pha
	pha
	pha

	pha
	pha
	pha
	pushword par
	pushword line
	pushword Offset1
	jsl W_FindFont
	lda par
	ldx Offset1
	jsl W_GetAddr
	phx
	pha
	lda par
	ldx Offset2
	jsl W_GetAddr
	phx
	pha
	jsl W_ReadFont
	moveword 1:s,col1
	moveLong 3:s,font1
	pushlong handle
	jsl X_SwitchFont

; done font stuff

	moveword W_LastP,NewLastP
	moveword W_MaxP,NewMaxP

	lda [ptr]
	cmp #2
	bcc NoCheck
	sec
	sbc #2	   ;check for a possible future mem error
	sta NewPars
	clc
	adc W_LastP
	sta NewLastP
	inc a
	inc a
	cmp W_MaxP
	bcc NoCheck
	clc
	adc #5
	sta NewMaxP

	tool	_Multiply,in=(NewMaxP:w,#W_pBytes:w),out=(NewSize:l)
	call	D_GrowLHandle,in=(NewSize:l,W_PHandle:l),out=(W_PPtr:l),err=err
	bcc 	NoCheck
	brl	killscrap

NoCheck	moveword NewMaxP,W_MaxP
	subword Offset2,Offset1,x
	beq NoKillF
	moveword Offset1,offset
	pushword par
	pushword offset
	phx
	jsl W_LessRoom

NoKillF	movelong [Block1]:#W_BHeader,Font2
	moveword [Block1]:#W_BHeader+4,a
	and #$ff
	sta col2

	call	W_CalcFBytes,in=(font1:l,col1:w,font2:l,col2:w),out=(Fbytes:w)
	jsl 	D_BeachBall

	lda [ptr]
	cmp #1
	jeq JustOne

; this is for the case that there is a cr

	pushword Par
	pushword line
	pushword offset
	jsl W_MakeCr

	pushword par
	jsl W_SplitBlock

	jsl D_BeachBall

	subword [Block1]:#W_BUsed,#W_BHeader+W_TextHeader+1,bytes

	pushword par
	pushword offset
	addword bytes,FBytes,s
	jsl W_MakeRoom

	movelong [Block1]:#W_BHeader,font2
	moveword [Block1]:#W_BHeader+4,a
	and #$ff
	sta col2

	lda par
	ldx offset
	jsl W_GetAddr
	movelong ax,TPtr

	pha
	pushword par
	pushword offset
	pushlong Font1
	pushword col1
	pushlong Font2
	pushword col2
	jsl W_WriteFBytes2
	subword fbytes,s,fbytes

	addlong Block1,#W_BHeader+W_TextHeader,s
	addlong TPtr,FBytes,s
	pushword #0
	pushword bytes
	_BlockMove

	jsl D_BeachBall

	lda par
	inc a
	ldx #0
	jsl W_GetAddr
	movelong ax,TPtr

	movelong [Block2]:#W_BHeader,[TPtr]
	moveword [Block2]:#W_BHeader+3,[TPtr]:#3
	subword [Block2]:#W_BUsed,#W_BHeader+W_TextHeader+1,bytes

	spacelong
	spaceword
	pushlong font2
	pushword col2
	addlong Block2,#W_BHeader+W_TextHeader,TPtr
	pushlong TPtr
	addlong TPtr,bytes,s
	jsl W_ReadFont
	pullword col2
	pullLong font2

	pha
	pushlong font2
	pushword col2
	pushlong font1
	pushword col1
	jsl W_CalcFBytes
	pullword FBytes

	lda par
	inc a
	pha
	pushword #W_TextHeader
	addword bytes,FBytes,s
	jsl W_MakeRoom

	jsl D_BeachBall

	pushlong TPtr
	lda par
	inc a
	ldx #W_TextHeader
	jsl W_GetAddr
	movelong ax,TPtr
	phx
	pha
	pushword #0
	pushword bytes
	_BlockMove

	jsl D_BeachBall

	pha
	lda par
	inc a
	pha
	addword #W_TextHeader,bytes,s
	pushlong font2
	pushword col2
	pushlong font1
	pushword col1
	jsl W_WriteFBytes2
	subword fbytes,s,fbytes

	addword TPtr,bytes,a
	addword a,FBytes,TPtr
	lda par
	inc a
	ldx #0
	jsl W_GetAddr
	sta temp
	subword TPtr,temp,OutOffset

	pushlong [ParRec1]
	_DisposeHandle

	pushlong [ParRec2]
	_DisposeHandle

	jsl D_BeachBall

	lda BegRul
	beq NotInCr

	rcall	W_GetParRec,in=(par:a),out=(RulRec:ax)
	call	W_UnUseRuler,in=(#1:w,[RulRec]:#W_pRulerHand:l)
	movelong 	[ParRec1]:#W_pRulerHand,[RulRec]:#W_pRulerHand
	bra 	DoneRul

NotInCr	call	W_UnUseRuler,in=(#1:w,[ParRec1]:#W_pRulerHand:l)

DoneRul	lda EndRul
	beq NotInCr2

	lda par
	inc a
	jsl W_GetParRec
	movelong ax,RulRec

	call	W_UnUseRuler,in=(#1:w,[RulRec]:#W_pRulerHand:l)
	movelong 	[ParRec2]:#W_pRulerHand,[RulRec]:#W_pRulerHand
	bra 	DoneRul2

NotInCr2	call	W_UnUseRuler,in=(#1:w,[ParRec2]:#W_pRulerHand:l)

DoneRul2	jsl D_BeachBall

	lda [ptr]
	cmp #2
	jeq W_AllSet

	lda par
	inc a
	jsl W_GetParRec
	movelong ax,TPtr
	phx
	pha
	lda par
	inc a
	clc
	adc NewPars
	jsl W_GetParRec
	movelong ax,Block2
	phx
	pha
	lda W_LastP
	inc a
	jsl W_GetParRec
	movelong ax,Block1
	sublong Block1,TPtr,s
	_BlockMove

	jsl D_BeachBall

	moveword NewLastP,W_LastP
	inc W_LastP

	addlong ParRec1,#W_pBytes,Block2
	pushlong Block2
	pushlong TPtr
	sublong ParRec2,Block2,s
	_BlockMove

	brl W_AllSet


;It is a special case of a paste within the par

JustOne
	subword [Block1]:#W_BUsed,#W_BHeader+W_TextHeader+1,bytes
	jeq 	killscrap

	pushword par
	pushword offset
	lda FBytes
	asl a
	addword a,bytes,s
	addword a,offset,OutOffset
	jsl W_MakeRoom

	jsl D_BeachBall

	rcall	W_GetAddr,in=(par:a,offset:x),out=(TPtr:ax)

	pha
	pushword par
	pushword offset
	pushlong Font1
	pushword col1
	pushlong Font2
	pushword col2
	jsl W_WriteFBytes2
	subword OutOffset,1:s,OutOffset
	subword fbytes,s,fbytes
	addlong fbytes,TPtr,TPtr

	addlong #W_BHeader+W_TextHeader,Block1,s
	pushlong TPtr
	pushlong bytes
	_BlockMove

	jsl D_BeachBall

	pha
	pushword par
	addword offset,fbytes,a
	addword a,bytes,s
	pushlong Font2
	pushword col2
	pushlong Font1
	pushword col1
	jsl W_WriteFBytes2
	subword OutOffset,s,OutOffset

;if W_target par was just a cr, use the ruler from copy
;	  lda BegRul
;	  beq NoDo
;	  lda EndRul
;	  beq NoDo
;
;	  lda par
;	  jsl W_GetParRec
;	  movelong ax,RulRec
;
;	  pushword #1
;	  pushlong [RulRec]:#W_pRulerHand
;	  jsl W_UnUseRuler
;
;	  movelong [ParRec1]:#W_pRulerHand,[RulRec]:#W_pRulerHand
;
;	  bra SkipRulDisp

NoDo	tool	_DisposeHandle,in=([ParRec1]:#W_pRulerHand:l)

SkipRulDisp
	tool	_DisposeHandle,in=([ParRec1]:l)

	jsl D_BeachBall

W_AllSet	;	
	lda [ptr]
	dec a
	addword a,par,OutPar

PLoop

	jsl D_BeachBall

	call	W_MakeLines,in=(par:w)

	subword OutPar,par,a
	cmp #3
	bcc NoThow

	rcall	W_GetParRec,in=(par:a),out=(ParRec1:ax)
	
	Cmpw	[ParRec1]:#W_pAttr,#W_PgBrk
	beq	@1

	tool	_DisposeHandle,in=([ParRec1]:#W_pLineHand:l)

@1	movelong #0,[ParRec1]:#W_pLineHand

NoThow
	inc par
	cmpw OutPar,par
	bcs PLoop

	call W_FindLine,in=(OutPar:w,OutOffset:w),out=(OutLine:w)

	jsl W_SetFullREct

	jsl D_BeachBall

	jsl W_CalcPages

	jsl D_BeachBall

	tool	_DisposeHandle,in=(handle:l)
	bra	exit

; Memory error occured dispose of scrap.

killscrap	rcall	D_Unlock,in=(handle:ax)
	call	X_DisposeScrap,in=(#WPText:w,Handle:l)

exit	return
;....................................................................................................
; addcrtop - add carriage return paragraph entry at the beginning of the scrap. Will return carry set
; 	 if memory errors occured while trying to add carriage return paragraph entry.

; Grow scrap by two paragraph entries in size.

addcrtop	spacelong
	addlong 	#W_pBytes*2,ParRec2,ParRec2
	sublong 	ParRec2,ptr,s
	pushlong 	handle
	jsl 	D_GrowLHandle
	sta	err
	pullLong 	ptr
	bcc	@newpar1
	rts

; Get new pointer to first and last paragraph entries.

@newpar1	addlong 	#2,ptr,ParRec1

	spacelong
	lda 	[ptr]
	dec 	a
	pha
	pushword 	#W_pBytes
	_Multiply
	addlong 	s,ParRec1,ParRec2
	addlong 	#W_pBytes,ParRec2,ParRec2   

; Before we munge the scrap lets make sure we will be able to get the new text block we will need if
; not return with memory error.

	spacelong
	jsl 	W_MakeEmptyBlock
	sta 	err
	bcc	@domove			; new text block left on stack until
	pulllong	a			; after block move is done.
	rts

; Move up all paragraph entries one entry block in size.

@domove	pushlong 	ParRec1
	addlong 	ParRec1,#W_pBytes,s
	sublong 	ParRec2,ParRec1,s
	_BlockMove
	
; Fill carriage return paragraph entry default values. Use ruler from carriage return paragraph
; after the page break.

	pulllong	[ParRec1]
	moveword 	#W_BHeader,[ParRec1]:#W_pOffset
	moveword 	#0,[ParRec1]:#W_pAttr
	movelong 	#0,[ParRec1]:#W_pLineHand
	moveword 	#1,[ParRec1]:#W_pLastLine
	movelong 	[ParRec1]:#W_pRulerHand+W_pBytes+W_pBytes,[ParRec1]:#W_pRulerHand
	call	W_UseRuler,in=(#1:w,[ParRec1]:#W_pRulerHand:l)

; Set default values for empty text block.

	movelong 	[ParRec1],Block1
	movelong 	[Block1],TextPtr
	addword 	#W_TextHeader+1,[TextPtr]:#W_BUsed,[TextPtr]:#W_BUsed
	addwl	#W_BHeader,TextPtr
	moveword 	#W_StandFont,[TextPtr]
	moveword 	#W_StandStyle,[TextPtr]:#2
	moveword 	#Black,[TextPtr]:#4
	movebyte 	#cr,[TextPtr]:#W_TextHeader

; Bump the scrap paragraph entries count. Return with carry clear.

	lda 	[ptr]
	inc 	a
	sta 	[ptr]
	clc
	rts
;....................................................................................................

	ENDP


****************************************************************
* W_SplitBlock(par) will make sure that par and par+1 have different blocks
W_SplitBlock	PROC	EXPORT
	;Using wpglobals

	input par:w
	local ParRec1:l,Blockhand:l,BlockPtr:l
	local W_offset:w,bytes:w
	begin

CheckAgain
	lda par
	jsl W_GetParRec
	movelong ax,ParRec1

	cmpl [ParRec1],[ParRec1]:#W_pBytes
	bne NoProb

	movelong [ParRec1],BlockHand
	movelong [BlockHand],BlockPtr

	pushword par
	pushword #W_TextHeader
	subword [BlockPtr],[ParRec1]:#W_pOffset+W_pBytes,a
	dec a
	pha
	sta bytes
	jsl W_MakeRoom

	pushword par
	pushword #W_TextHeader
	pushword bytes
	jsl W_LessRoom

	brl CheckAgain

NoProb
	return

	ENDP
	END

