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

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

	IMPORT	D_BeachBall
	IMPORT	X_CopyOneHandle
	IMPORT	D_Deref
	IMPORT	D_FastMult
	IMPORT	D_GrowHandle
	IMPORT	D_NeedHand
	IMPORT	P_CheckHand
	IMPORT	P_FixMenus
	IMPORT	T_ClearRulers
	IMPORT	T_CopyParEnd
	IMPORT	T_CurColor
	IMPORT	T_CurFont
	IMPORT	T_CurParHdl
	IMPORT	T_CurStyle
	IMPORT	T_DeletePars
	IMPORT	T_DotLine
	IMPORT	T_DotOffset
	IMPORT	T_DotParag
	IMPORT	T_FixParag
	IMPORT	T_GetObjBound
	IMPORT	T_GetParPtr
	IMPORT	T_GetParSize
	IMPORT	T_GetTextPtr
	IMPORT	T_InvSelect
	IMPORT	T_JunkLeft
	IMPORT	T_JunkRight
	IMPORT	T_LessRoom
	IMPORT	T_MarkOffset
	IMPORT	T_MarkParag
	IMPORT	T_MulParag
	IMPORT	T_NewParHdl
	IMPORT	T_NewPars
	IMPORT	T_PastePar
	IMPORT	T_SetRulers
	IMPORT	T_TextSelect
	IMPORT	T_TrackFont
	IMPORT	T_UnuseRuler
	IMPORT	T_UpdatePars
	IMPORT	P_RedoFlag
	IMPORT	T_InsertFont

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

	ENTRY	T_ClearPrim
	ENTRY	T_CopyPrim
	ENTRY	T_CopyText
	ENTRY	T_MakeParStyle




;------------------------------------------------------------------------------
;
; T_Clear ()
;

T_Clear	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu

		LOCAL CharCount:w,Temp:w,Ptr:l,StyleCount:w,DotPtr:l

		BEGIN

		jsl T_InvSelect
		pushword T_DotOffSet
		lda T_TextSelect
		jeq Exit

		jsl T_MakeParStyle

 		cmpw T_DotOffset,#T_ParHeader
 		beq NoJunk

     	rcall T_JunkLeft,in=(T_MarkParag:a,T_MarkOffset:x)
     	sta T_MarkOffset
		

NoJunk

    	rcall T_JunkRight,in=(T_DotParag:a,T_DotOffset:x)
    	sta T_DotOffset

		in T_DotParag:w,T_DotOffset:w,T_MarkParag:w,T_MarkOffset:w
		out CharCount:w
		xcall T_ClearPrim
		bcs Exit


		stz T_TextSelect
		call T_FixParag,in=(T_DotParag:w,T_DotLine:w,CharCount:w)
		jsl P_FixMenus


Exit	pullword T_DotOffSet
		RETURN
		
		ENDP

		
		
********************************************************************
*
*
* T_MakeParStyle
* This routine takes any style changes at the end of a selection (T_MarkOffSet)
* and puts them in the parheader.
*
* Wednesday, September 6, 1989 4:44:21 PM (SFS)
********************************************************************

T_MakeParStyle	PROC		EXPORT

		LOCAL Temp:w,Ptr:l,StyleCount:w,DotPtr:l

		BEGIN

		cmpw T_DotOffset,#T_ParHeader
		bne Exit

		moveword T_MarkOffSet,Temp
    	rcall T_JunkRight,in=(T_MarkParag:a,T_MarkOffset:x)
		sta T_MarkOffSet
    	cmp Temp
		beq Exit
		
		subword T_MarkOffSet,Temp,StyleCount
		rcall T_GetTextPtr,in=(T_MarkParag:a),out=(Ptr:ax)
		rcall T_GetTextPtr,in=(T_DotParag:a),out=(DotPtr:ax)

FontLoop
		ldy Temp
		lda [ptr],y
		jsr MakeMasterFont
		lda StyleCount
		bne FontLoop

Exit	Return

MakeMasterFont
		and #$ff
		Shortm
		asl a
		tax
		iny
		lda [Ptr],y							;get the change value
		jmp (JumpTable,x)

DoFont
		ldy #T_ParFont
		sta [DotPtr],y
		iny
		inc temp
		phy
		ldy temp
		iny
		lda [Ptr],y
		ply
		dec StyleCount
		bra AllDone
		
DoStyle
		ldy #T_ParStyle
		bra AllDone
		
DoSize
		ldy #T_ParSize
		bra AllDone

DoColor
		ldy #T_ParColor 
		
AllDone
		sta [DotPtr],y
		inc temp
		inc temp
		dec StyleCount
		dec StyleCount
Next	
		longm
		rts
JumpTable
		ds.b 2						;nothing
		dc.w DoFont
		dc.w DoStyle
		dc.w DoSize
		dc.w Docolor
		EndP
		
;------------------------------------------------------------------------------
;
; T_Paste (PasteHdl:l,MoveDot:w)
;

T_Paste	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu

		INPUT PasteHdl:l,MoveDot:w

		LOCAL Ptr:l,NewTextHdl:l,RulerHdl:l,FirstRuler:l,NewPCount:w
		LOCAL Hdl:l,Dest:l,CharCount:w,BytesLess:w,CopySize:w
		LOCAL ParagPtr:l,TextBlock:l,TPtr:l,Offset:w
		LOCAL SPar:w,NewParag:w,NewOffset:w
		
		LOCAL ParagPtr1:l,ParagPtr2:l,ParOffset1:w,ParOffset2:w,ParagNo:w
        LOCAL TextHdl1:l,TextHdl2:l,TextPtr1:l,TextPtr2:l,OldTextHdl:l
        LOCAL TextSize1:w,TextSize2:w,ParDiff:w
		LOCAL TempHdl:l,TempPtr:l,OldDot:w
		
		ERROR  Err
 		BEGIN
		
		stz Err
		jsl T_Clear

* This prevents style changes from leaking over into other text. (SFS 8/30/89)
DoJunk
			moveword T_DotOffSet,OldDot
    		rcall T_JunkRight,in=(T_DotParag:a,T_DotOffset:x)
    		sta T_DotOffset
		
NoJunk
		moveword T_DotParag,SPar

		movelong [PasteHdl],Ptr
		movelong [Ptr]:#T_TextBlock,NewTextHdl
		movelong [Ptr]:#T_RulerHdl,FirstRuler

		cmpw T_DotOffset,#T_ParHeader
		bne NotStart

		rcall T_GetParPtr,in=(SPar:a),out=(ParagPtr:ax)
		movelong [ParagPtr]:#T_RulerHdl,RulerHdl
		movelong FirstRuler,[ParagPtr]:#T_RulerHdl
		rcall T_UnuseRuler,in=(RulerHdl:ax)
		bra DoIt

NotStart
		rcall T_UnuseRuler,in=(FirstRuler:ax)


DoIt
		movelong [PasteHdl],Ptr
		subword [Ptr],#1,NewPCount
		bne MakeNew

		in SPar:w,T_DotOffset:w,NewTextHdl:l
		out CharCount:w
		xcall T_PastePar

		addword a,T_DotOffset,T_MarkOffset
		lda MoveDot
		beq NoMove
		moveword T_MarkOffset,T_DotOffset
NoMove
		call T_FixParag,in=(SPar:w,T_DotLine:w,CharCount:w)
		brl Exit



MakeNew
		lda SPar
        inc a
        sta NewParag
		
		movelong T_CurParHdl,TempHdl
		movelong [TempHdl],TempPtr
		moveword [TempPtr],a
		dec a
		cmp NewParag
		bge ValidPar
		
		dec NewParag

ValidPar


; Make sure that the text from the paragraph with the insertion point
; is in a different text block than the text from the next paragraph.

        rcall T_GetParPtr,in=(SPar:a),out=(ParagPtr1:ax)
        rcall T_GetParPtr,in=(NewParag:a),out=(ParagPtr2:ax)
        movelong [ParagPtr1]:#T_TextBlock,TextHdl1
        movelong [ParagPtr2]:#T_TextBlock,TextHdl2
        moveword [ParagPtr1]:#T_ParOffset,ParOffset1
        moveword [ParagPtr2]:#T_ParOffset,ParOffset2


        cmpl TextHdl1,TextHdl2
        jne Okay


; Allocate the new text block
        movelong [TextHdl1],TextPtr1
        moveword [TextPtr1]:#T_TextSize,TextSize1
        subword a,ParOffset2,TextSize2
        subword TextSize1,TextSize2,TextSize1
        addword TextSize2,#T_BlockHdrSize,TextSize2

        call D_NeedHand,in=(#0:w,TextSize2:w),out=(TextHdl2:l)


; Fill in the new text block

        movelong [TextHdl2],TextPtr2
        moveword TextSize2,[TextPtr2]
        moveword a,[TextPtr2]:#T_TextSize

        movelong [TextHdl1],TextPtr1
        addwl ParOffset2,TextPtr1
        addwl #T_BlockHdrSize,TextPtr2
        subword TextSize2,#4,TextSize2
        tool _BlockMove,in=(TextPtr1:l,TextPtr2:l,#0:w,TextSize2:w)


; Adjust the paragraphs starting at NewParag

        subword ParOffset2,#T_BlockHdrSize,ParDiff
        moveword NewParag,ParagNo

Loop     
        rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr2:ax)
        movelong [ParagPtr2]:#T_TextBlock,OldTextHdl
        cmpl TextHdl1,OldTextHdl
        bne EndLoop
        movelong TextHdl2,[ParagPtr2]:#T_TextBlock
        subword [ParagPtr2]:#T_ParOffset,ParDiff,[ParagPtr2]:#T_ParOffset
        inc ParagNo
        bra Loop
EndLoop 


; Shrink the old text block
        movelong [TextHdl1],TextPtr1
        moveword TextSize1,[TextPtr1]
        moveword a,[TextPtr1]:#T_TextSize
        tool _SetHandleSize,in=(#0:w,TextSize1:w,TextHdl1:l)

Okay    

; Handle the first paragraph
;   Copy the end of it, delete it, and paste in D_New stuff.

		call T_CopyParEnd,in=(SPar:w,T_DotOffset:w),out=(Hdl:l)
		rcall T_GetParSize,in=(SPar:a),out=(a:a)
		subword a,T_DotOffset,a
		dec a					 ;Keep CR
		sta BytesLess
		call T_LessRoom,in=(SPar:w,T_DotOffset:w,BytesLess:w)


		in SPar:w,T_DotOffset:w,NewTextHdl:l
		out a:w
		xcall T_PastePar



; Make room for D_New paragraphs and copy them in

		moveword SPar,NewParag
		inc NewParag
		call T_NewPars,in=(NewParag:w,NewPCount:w)

		movelong [PasteHdl],Ptr
		addlong Ptr,#T_ParInfoSize+2,s
		rcall T_GetParPtr,in=(NewParag:a),out=(Dest:ax)
		addlong Dest,#2,s
		rcall D_FastMult,in=(NewPCount:x,#T_ParInfoSize:y),out=(CopySize:a)
		pushword #0
		pushword a
		_BlockMove


; Handle the paragraph part that got put into Hdl by appending it to the
; last paragraph
		addword SPar,NewPCount,NewParag

		rcall T_GetParPtr,in=(NewParag:a),out=(ParagPtr:ax)
		movelong [ParagPtr]:#T_TextBlock,TextBlock
		movelong [TextBlock],TPtr
		subword [TPtr]:#T_TextSize,#5,NewOffset	 ;No CR

		call T_PastePar,in=(NewParag:w,NewOffset:w,Hdl:l),out=(a:w)
 		lda P_RedoFlag
 		bne N1

		moveword NewParag,T_MarkParag
		moveword NewOffset,T_MarkOffset
N1		
		lda MoveDot
		beq NoMove1
		moveword NewParag,T_DotParag
		moveword NewOffset,T_DotOffset
		bra NoMove2
NoMove1
		moveword OldDot,T_DotOffSet
NoMove2
		call T_UpdatePars,in=(SPar:w,NewParag:w)
Exit

		tool _DisposeHandle,in=(PasteHdl:l)
		stz P_RedoFlag
 		RETURN
		ENDP





;------------------------------------------------------------------------------;
;
; T_Copy () : CopyHdl:l
;

T_Copy	PROC		EXPORT
			;Using P_ObjData
			;Using T_Data

		OUTPUT CopyHdl:l
		LOCAL  Start:w,End:w,Amount:w,Ptr:l
		ERROR  Err

		BEGIN

		stzl CopyHdl
		lda T_TextSelect
		beq Exit

		pushword T_DotOffset
* this garruantees that the correct style changes are always copied (SFS 8/30/89)
     	rcall T_JunkRight,in=(T_DotParag:a,T_DotOffset:x)
    	sta T_DotOffset

		in T_CurParHdl:l,T_DotParag:w,T_DotOffset:w
		in T_MarkParag:w,T_MarkOffset:w
		out CopyHdl:l
		xerr Err
		xcall T_CopyPrim

		pullword T_DotOffset
Exit	RETURN
		ENDP






;------------------------------------------------------------------------------
;
; T_ClearPrim (SPar:w,SOffset:w,EPar:w,EOffset:w) : CharCount:w
;

T_ClearPrim	PROC		EXPORT
			;Using T_TextEqu
			;Using T_Data

		INPUT  SPar:w,SOffset:w,EPar:w,EOffset:w
		OUTPUT CharCount:w
		ERROR  Err

		LOCAL ParCount:w,Hdl:l
		LOCAL Bytes:w,ParagPtr:l

		BEGIN

		stz Err

		subword EPar,SPar,ParCount
		bne Case2

; No CRs are being deleted.  Just use LessRoom

		subword EOffset,SOffset,Bytes
		call T_LessRoom,in=(SPar:w,SOffset:w,Bytes:w)
		brl Exit


Case2
		call T_CopyParEnd,in=(EPar:w,EOffset:w),out=(Hdl:l),err=(Err)
		bcs Exit

		addword SPar,#1,s
		pushword ParCount
		jsl T_DeletePars

		rcall T_GetParSize,in=(SPar:a),out=(a:a)
		dec a					 ; remove CR
		subword a,SOffset,Bytes
		call T_LessRoom,in=(SPar:w,SOffset:w,Bytes:w)


		call T_PastePar,in=(SPar:w,SOffset:w,Hdl:l),out=(CharCount:w)

Exit
		RETURN
		ENDP





;---------------------------------------------------------------------------
;
; T_CopyPrim (SrcHdl:l,SPar:w,SOffset:w,EPar:w,EOffset:w): ParagHdl:l
;

T_CopyPrim	PROC		EXPORT
			;Using T_TextEqu
			;Using T_Data

		INPUT  SrcHdl:l,SPar:w,SOffset:w,EPar:w,EOffset:w
		OUTPUT ParagHdl:l
		ERROR  Err

		LOCAL  ParagPtr:l,SrcPtr:l,TextBlock:l,RulerHdl:l,NewRuler:l
		LOCAL  CurBlock:l,Ptr:l,CurPar:w,NPar:w,LPar:w
		LOCAL  ByteCount:w,Size:w,PCount:w,StartOffset:w
		LOCAL  DotBlock:l,MarkBlock:l,ParSize:w,ParOffset:w
		LOCAL  Estimate:l



		BEGIN

		stzl ParagHdl


		moveword SPar,CurPar
		moveword #100,Estimate
		stz Estimate+2

EstLoop
		rcall T_GetParSize,in=(SPar:a),out=(a:a)
		addword a,#78,a
		addwl a,Estimate
		inc CurPar

		cmpw EPar,CurPar
		bge EstLoop

		call P_CheckHand,in=(Estimate:l),err=(Err)
		jcs Exit



		subword EPar,SPar,LPar
		inc a
		sta PCount
		jsl T_MulParag
		sta ByteCount
		addword a,#2,a

		call D_NeedHand,in=(#0:w,a:w),out=(ParagHdl:l)

		rcall D_Deref,in=(ParagHdl:ax),out=(ParagPtr:ax)
		moveword PCount,[ParagPtr]	 ;set ParagCount


		movelong [SrcHdl],SrcPtr
		lda SPar
		jsl T_MulParag
		addword a,#2,a
		addlong a,SrcPtr,s
		addlong #2,ParagPtr,s
		pushword #0
		pushword ByteCount
		_BlockMove

		rcall T_GetTextPtr,in=(SPar:a),out=(ax:ax)
		call T_TrackFont,in=(ax:l,SOffset:w)


; Make room for paragraph header

		subword SOffset,#T_ParHeader,SOffset

		cmpw PCount,#1
		bne NotOne

		in SPar:w,SOffset:w,EOffset:w,#0:l,#1:w		
		out DotBlock:l,a:w
		xcall T_CopyText
		brl Cont


NotOne
		rcall T_GetParSize,in=(SPar:a),out=(ParSize:a)

		in SPar:w,SOffset:w,ParSize:w,#0:l,#0:w
		out DotBlock:l,a:w
		xcall T_CopyText

		in EPar:w,#0:w,EOffset:w,#0:l,#1:w
		out MarkBlock:l,a:w
		xcall T_CopyText
Cont

		movelong [DotBlock],Ptr
		moveword T_CurFont,[Ptr]:#4
		moveword T_CurStyle,[Ptr]:#6
		movebyte T_CurColor,[Ptr]:#8
		movelong DotBlock,[ParagPtr]:#T_TextBlock
		moveword #4,[ParagPtr]:#T_ParOffset



		moveword SPar,CurPar
		stzl CurBlock


ParLoop
		jsl D_BeachBall

; Copy the Q_Text if not the first or last par

		lda CurPar
		cmp SPar
		beq CopyRuler
		cmp EPar
		beq DoLast

		rcall T_GetParSize,in=(CurPar:a),out=(ParSize:a)

		in CurPar:w,#0:w,ParSize:w,CurBlock:l,#0:w
		out CurBlock:l,ParOffset:w
		xcall T_CopyText

		movelong CurBlock,[ParagPtr]:#T_TextBlock
		moveword ParOffset,[ParagPtr]:#T_ParOffset
		bra CopyRuler


DoLast
		movelong MarkBlock,[ParagPtr]:#T_TextBlock
		moveword #4,[ParagPtr]:#T_ParOffset


; Copy the ruler if necessary

CopyRuler
		movelong [ParagPtr]:#T_RulerHdl,RulerHdl
		lda RulerHdl+2
		and #$8000
		bne Copied

		call X_CopyOneHandle,in=(RulerHdl:l),out=(NewRuler:l)

		pushlong T_CurParHdl
		movelong ParagHdl,T_CurParHdl

		subword CurPar,SPar,NPar
		call T_SetRulers,in=(NewRuler:l,RulerHdl:l,NPar:w,LPar:w,#0:w)

		pulllong T_CurParHdl
Copied


		movelong #0,[ParagPtr]:#T_LinesHdl


		addwl #T_ParInfoSize,ParagPtr
		inc CurPar
		cmpw CurPar,EPar
		jle ParLoop


		tool _HUnlock,in=(ParagHdl:l)


; Clean up marks
		pushlong T_CurParHdl
		movelong ParagHdl,T_CurParHdl
		call T_ClearRulers,in=(#0:w,LPar:w)
		pulllong T_CurParHdl

Exit	RETURN
		ENDP





;------------------------------------------------------------------------------
;
; T_CopyText (ParagNo:w,Start:w,End:w,TextBlock:l,AddCR:w) : D_NewText:l
;
; Only works on the current Q_Text thread.
; Assumes the Q_Text fits in the block.

T_CopyText	PROC		EXPORT

		INPUT  ParagNo:w,Start:w,End:w
		INPUT  TextBlock:l,AddCR:w
		OUTPUT D_NewText:l,ParOffset:w

		LOCAL  TextPtr:l,BPtr:l,AddSize:w,OldSize:w,NewSize:w

		BEGIN

		subword End,Start,a
		ldy AddCR
		beq No
		inc a
No	sta AddSize


		cpzl TextBlock
		bne Made

NewBlock
		call D_NeedHand,in=(#4:l),out=(TextBlock:l)
		jcs Exit

		moveword #4,OldSize
		bra AddIt


Made
		movelong [TextBlock],BPtr
		moveword [BPtr],OldSize

		addword a,AddSize,a
		bcs NewBlock
		cmp #$C00
		bge NewBlock



AddIt
		addword AddSize,OldSize,NewSize
		call D_GrowHandle,in=(#0:w,a:w,TextBlock:l)
		bcs Exit

		rcall T_GetTextPtr,in=(ParagNo:a),out=(TextPtr:ax)

		lda Start
		addlong a,TextPtr,s			  ;Src
		movelong [TextBlock],BPtr
		lda OldSize
		addlong a,BPtr,s				 ;Dest
		pushword #0
		pushword AddSize
		_BlockMove

		moveword NewSize,[BPtr]
		moveword a,[BPtr]:#2

		lda AddCR
		beq No2
		ldy NewSize
		dey
		movebyte #CR,[BPtr]:y
No2
		movelong TextBlock,D_NewText

		subword NewSize,AddSize,ParOffset


Exit	RETURN
		ENDP





;-------------------------------------------------------------------------------
;
; T_CpyOrClrObj  (ObjPtr:l,D_DoCopy:w) : CopyHdl:l
;
; Makes a copy of the Q_Text for the object or clears it from the Q_Text thread,
; depending on whether D_DoCopy is set or not.

T_CpyOrClrObj	PROC		EXPORT
			;Using P_ObjData
			;Using T_Data

		INPUT  ObjPtr:l,D_DoCopy:w
		OUTPUT CopyHdl:l
		ERROR  Err

		LOCAL  SPar:w,SOffset:w,EPar:w,EOffset:w,IsEmpty:w


		BEGIN +B

		stz Err
		pushlong T_CurParHdl
		movelong [ObjPtr]:#P_ParagHdl,T_CurParHdl

		call T_GetObjBound,in=(ObjPtr:l,#1:w),out=(SPar:w,SOffset:w)
		call T_GetObjBound,in=(ObjPtr:l,#0:w),out=(EPar:w,EOffset:w)

		stz IsEmpty
		cmpw SPar,EPar
		bne NotEmpty
		cmpw SOffset,EOffset
		bne NotEmpty
		inc IsEmpty
NotEmpty


		lda D_DoCopy
		bne @Copy


		lda IsEmpty
		bne Exit
		call T_ClearPrim,in=(SPar:w,SOffset:w,EPar:w,EOffset:w),out=(a:w)
		bra Exit


@Copy

		lda IsEmpty
		bne MakeNew
		in  T_CurParHdl:l,SPar:w,SOffset:w,EPar:w,EOffset:w
		out CopyHdl:l
		xerr Err
		xcall T_CopyPrim
		bra Exit

MakeNew
		call T_NewParHdl,out=(CopyHdl:l)


Exit	pulllong T_CurParHdl


		RETURN
		ENDP
		END

