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

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

	IMPORT	D_GrowHandle
	IMPORT	D_MainZPage
	IMPORT	D_NeedHand
	IMPORT	P_ChangePage
	IMPORT	P_ContentRect
	IMPORT	P_DefFont
	IMPORT	P_DefSize
	IMPORT	P_DefStyle
	IMPORT	P_H
	IMPORT	P_Page
	IMPORT	P_V
	IMPORT	T_CurColor
	IMPORT	T_CurFont
	IMPORT	T_CurIndent
	IMPORT	T_CurParHdl
	IMPORT	T_CurRulBits
	IMPORT	T_CurRulHdl
	IMPORT	T_CurRulPtr
	IMPORT	T_CutParag
	IMPORT	T_Deactivate
	IMPORT	T_DotLine
	IMPORT	T_DotObj
	IMPORT	T_DotOffset
	IMPORT	T_DotParag
	IMPORT	T_DotPixs
	IMPORT	T_DrawRuler
	IMPORT	T_EraseCaret
	IMPORT	T_FontFlags
	IMPORT	T_InsertFont
	IMPORT	T_LessRoom
	IMPORT	T_MakeRoom
	IMPORT	T_MarkLine
	IMPORT	T_MarkObj
	IMPORT	T_MarkOffset
	IMPORT	T_MarkParag
	IMPORT	T_MarkPixs
	IMPORT	T_NewAddStyle
	IMPORT	T_NewColor
	IMPORT	T_NewFont
	IMPORT	T_NewRuler
	IMPORT	T_NewSize
	IMPORT	T_Offset2Line
	IMPORT	T_Offset2Pix
	IMPORT	T_TextSelect
	IMPORT	T_TrackFont
	IMPORT	T_UnUseRuler

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

	ENTRY	T_LineHeight
	ENTRY	T_OffThread






;---------------------------------------------------------------------------
; T_MulLine
;

T_MulLine	PROC		EXPORT

		asl a
		asl a
		asl a
		rtl

		ENDP



;---------------------------------------------------------------------------
; T_MulParag
;

T_MulParag	PROC		EXPORT

		asl a
		asl a
		asl a
		pha
		asl a
		clc
		adc 1,s
		plx
		rtl
		ENDP





;-------------------------------------------------------------------------------
;
; T_GetParPtr (ParagNo:a) : ParagPtr:ax
;
; Operates on the current thread.  The ParagHdl is not X_Locked down.

T_GetParPtr	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu
			;Using D_GlobalData

ParagHdl	equ  0
ParagPtr	equ  4

		phd
		pha
		lda >D_MainZPage
		tcd

		movelong T_CurParHdl,ParagHdl
		movelong [ParagHdl],ParagPtr

		pla
		jsl T_MulParag
		addwl a,ParagPtr
		movelong ParagPtr,ax

		pld
		rtl

		ENDP




;-------------------------------------------------------------------------------
;
; T_GetTextPtr (ParagNo:a) : TextPtr:ax
;
; Operates on the current thread.  The TextHdl is not X_Locked down.

T_GetTextPtr	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu
			;Using D_GlobalData


ParagHdl	equ  0
ParagPtr	equ  4
TextHdl	equ  8
TextPtr	equ  12

		phd
		pha
		lda >D_MainZPage
		tcd

		movelong T_CurParHdl,ParagHdl
		movelong [ParagHdl],ParagPtr

		pla
		jsl T_MulParag
		addwl a,ParagPtr

		movelong [ParagPtr]:#T_TextBlock,TextHdl
		movelong [TextHdl],TextPtr
		moveword [ParagPtr]:#T_ParOffset,a
		addwl a,TextPtr
		movelong TextPtr,ax

		pld
		rtl

		ENDP




;-------------------------------------------------------------------------------
;
; T_GetRulBits (ParagNo:a) : RulBits:a
;
; Operates on the current thread.

T_GetRulBits	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu
			;Using D_GlobalData

ParagPtr	equ  20
RulerHdl	equ  24
RulerPtr	equ  28

		phd
		pha
		lda >D_MainZPage
		tcd

		pla
		rcall T_GetParPtr,in=(a:a),out=(ParagPtr:ax)
		movelong [ParagPtr]:#T_RulerHdl,RulerHdl
		movelong [RulerHdl],RulerPtr
		moveword [RulerPtr]:#T_RulBits,a

		pld
		rtl

		ENDP




;-----------------------------------------------------------------------------
;
; T_GetSpacing (RulBits:a; Ascent:x; Descent:y) : Spacing:a
;

T_GetSpacing	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu
			;Using D_GlobalData

RulBits	equ  0
Ascent	equ  2
Descent	equ  4
TextHeight	equ  6

		phd
		pha
		lda >D_MainZPage
		tcd

		stx Ascent
		sty Descent

		pullword RulBits
		and #T_CustSpace
		bne Custom

		lda RulBits
		and #T_Single
		bne Single
		lda RulBits
		and #T_Double
		bne Double

Triple
		addword Ascent,#2,a
		bra Exit

Double
		lda Ascent
		lsr a
		addword a,#2,a
		bra Exit

Single
		lda #1
		bra Exit


Custom
		addword Ascent,Descent,TextHeight

		lda RulBits
		xba
		and #T_GetCustSpace
		inc a					 ; 1-64
		subword a,TextHeight,a
		bpl Exit

NoSpace	lda #0

Exit
		pld
		rtl

		ENDP






;------------------------------------------------------------------------------
;
; T_LockRuler (ParagPtr:ax)
;

T_LockRuler	PROC		EXPORT
			;Using D_GlobalData
			;Using T_Data
			;Using T_TextEqu

ParagPtr	equ  0
RulerHdl	equ  4
RulerPtr	equ  8

		phd
		pha
		lda >D_MainZPage
		tcd

		pla
		movelong ax,ParagPtr

		movelong [ParagPtr]:#T_RulerHdl,RulerHdl
		tool _HLock,in=(RulerHdl:l)
		movelong RulerHdl,T_CurRulHdl
		movelong [RulerHdl],RulerPtr
		movelong RulerPtr,T_CurRulPtr
		moveword [RulerPtr]:#T_RulBits,T_CurRulBits
		moveword [RulerPtr]:#T_Indent,T_CurIndent

		pld
		rtl

		ENDP



;-----------------------------------------------------------------------------
;
; T_UnlockRuler ()
;

T_UnlockRuler	PROC		EXPORT
			;Using T_Data


		tool _HUnlock,in=(T_CurRulHdl:l)

		rtl
		ENDP




;------------------------------------------------------------------------------
;
; T_GetParSize (ParagNo:a) : ParSize:a
;
; Returns the size of the paragraph in bytes.
;
; All ParOffsets must be correct for this routine to work.


T_GetParSize	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu
			;Using D_GlobalData

ParagNo	equ  20
ParagPtr	equ  22
TempHdl	equ  26
TempPtr	equ  30
ParOffset	equ  34
LastPar	equ  36
TextBlock	equ  38

		phd
		pha
		lda >D_MainZPage
		tcd

		pullword ParagNo
		rcall T_GetParPtr,in=(a:a),out=(ParagPtr:ax)
		moveword [ParagPtr]:#T_ParOffset,ParOffset
		movelong [ParagPtr]:#T_TextBlock,TextBlock

		movelong T_CurParHdl,TempHdl
		movelong [TempHdl],TempPtr
		moveword [TempPtr],a
		dec a
		sta LastPar

		cmpw ParagNo,LastPar
		bge X_EndBlock

		addwl #T_ParInfoSize,ParagPtr
		cmpl TextBlock,[ParagPtr]:#T_TextBlock
		bne X_EndBlock

		moveword [ParagPtr]:#T_ParOffset,a
		bra SubIt

X_EndBlock
		movelong [TextBlock],TempPtr
		moveword [TempPtr]:#T_TextSize,a

SubIt	subword a,ParOffset,a

		pld
		rtl

		ENDP




;------------------------------------------------------------------------------
;
; T_LockLines2 (ParagNo:a) : LinesHdl:ax
;

T_LockLines2	PROC		EXPORT
			;Using T_TextEqu

		INPUT  ParagNo:w
		OUTPUT LinesHdl:l
		LOCAL  ParagPtr:l

		BEGIN

		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)
		movelong [ParagPtr]:#T_LinesHdl,LinesHdl
		cpzl LinesHdl
		beq _Cut
		cpzl [LinesHdl]
		beq Purged

		tool _HLock,in=(LinesHdl:l)
		bra Exit


Purged
		tool _DisposeHandle,in=(LinesHdl:l)


_Cut
		in [ParagPtr]:#T_ObjHdl:l,ParagNo:w,[ParagPtr]:#T_ParStart:w
		out a:l,a:w
		xcall T_CutParag

		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)
		movelong [ParagPtr]:#T_LinesHdl,LinesHdl

Exit	RETURN
		ENDP




;------------------------------------------------------------------------------
;
; T_LockLines (ParagNo:a) : LinesHdl:ax
;
; Returns with the LinesHdl X_Locked.

T_LockLines	PROC		EXPORT

		call T_LockLines2,in=(a:w),out=(ax:l)
		rtl

		ENDP





;------------------------------------------------------------------------------
;
; T_GetLinePtr2 (ParagNo:w,LineNo:w) : LinePtr:l
;

T_GetLinePtr2	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu

		INPUT  ParagNo:w,LineNo:w
		OUTPUT LinePtr:l
		LOCAL  LinesHdl:l

		BEGIN

		call T_LockLines2,in=(ParagNo:w),out=(LinesHdl:l)
		tool _HUnlock,in=(LinesHdl:l)
		movelong [LinesHdl],LinePtr

		rcall T_MulLine,in=(LineNo:a),out=(a:a)
		addwl a,LinePtr

		RETURN
		ENDP




;------------------------------------------------------------------------------
;
; T_GetLinePtr (ParagNo:a,LineNo:x) : LinePtr:ax
;

T_GetLinePtr	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu

		call T_GetLinePtr2,in=(a:w,x:w),out=(ax:l)
		rtl

		ENDP





;-----------------------------------------------------------------------------
;
; T_EatJunk (TextPtr:ax; Offset:y) : NewOffset:y
;
; Moves Offset past any font changes, such that [TextPtr]:y is a normal
; character.

T_EatJunk	PROC		EXPORT
			;Using T_TextEqu
			;Using D_GlobalData

TextPtr	equ  0

		phd
		pha
		lda >D_MainZPage
		tcd
		pla

		movelong ax,TextPtr

Loop	lda [TextPtr],y
		and #$ff
		cmp #T_ColorChange+1
		bge Exit

		iny
		iny
		cmp #T_FontChange
		bne Loop
		iny
		bra Loop

Exit	pld
		rtl

		ENDP





;------------------------------------------------------------------------------
;
; T_PrevChar (ParagNo:a,Offset:x) : NewOffset:a
;
; Offset must be an offset within the paragraph.
; The NewOffset returned points to the previous character
; or is 0 if at the beginning of a paragraph.
;

T_PrevChar	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu
			;Using D_GlobalData

Offset	equ  20
TextPtr	equ  22
NewOffset	equ  26

		phd
		pha
		lda >D_MainZPage
		tcd

		stx Offset
		pla

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

		stz NewOffset
		ldy #T_ParHeader

CharLoop	cpy Offset
		bge Done
		lda [TextPtr],y
		and #$ff
		cmp #T_ColorChange+1
		blt Special

		sty NewOffset
		iny
		bra CharLoop

Special
		iny
		asl a
		tax
		jmp (JumpTable,x)

SkipTwo	iny
SkipOne	iny
		bra CharLoop


Done	lda NewOffset
Exit	pld
		rtl

JumpTable
	DC.W	CharLoop
	DC.W	SkipTwo
	DC.W	SkipOne
	DC.W	SkipOne
	DC.W	SkipOne

		ENDP





;------------------------------------------------------------------------------
;
; T_NextChar (ParagNo:a,Offset:x) : NewOffset:a
;
; Offset must be an offset within the paragraph.
; NewOffset is set to 0 if the next character is not in the paragraph.


T_NextChar	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu
			;Using D_GlobalData

ParagNo	equ  20
Offset	equ  22
TextPtr	equ  24
NewOffset	equ  28
HitFirst	equ  30

		phd
		pha
		lda >D_MainZPage
		clc
		adc #64
		tcd

		stx Offset
		pla
		sta ParagNo

		jsl T_GetTextPtr
		movelong ax,TextPtr

		ldy Offset
		jsl T_EatJunk

		moveword [TextPtr]:y,a
		and #$ff
		cmp #CR
		beq IsCr

		iny
		movelong TextPtr,ax
		jsl T_EatJunk
		tya


Exit	pld
		rtl

IsCR	lda #0
		bra Exit

		ENDP




;------------------------------------------------------------------------------
;
; T_JunkLeft (ParagNo:a,Offset:x) : NewOffset:a
;

T_JunkLeft	PROC		EXPORT
			;Using T_TextEqu

		jsl T_PrevChar
		cmp #0
		beq AtStart
		inc a
		rtl

AtStart	lda #T_ParHeader
		rtl

		ENDP




;------------------------------------------------------------------------------
;
; T_JunkRight (ParagNo:a,Offset:x) : NewOffset:a
;

T_JunkRight	PROC		EXPORT

		phx
		jsl T_GetTextPtr

		ply
		jsl T_EatJunk
		tya
		rtl

		ENDP





;------------------------------------------------------------------------------
;
; T_GetObjBound (ObjPtr:l,Start:w) : Par:w,Offset:w
;
; Returns the offset to the start or end of the Q_Text in a Q_Text object.
; If the Q_Text object is empty, the last par and offset are returned.

T_GetObjBound	PROC		EXPORT
			;Using P_ObjData
			;Using T_Data
			;Using T_TextEqu

		INPUT  ObjPtr:l,Start:w
		OUTPUT Par:w,Offset:w
		LOCAL  ParagHdl:l,ParagPtr:l,LastPar:w
		LOCAL  LinePtr:l,Q_Line:w,LineCount:w

		BEGIN

		movelong T_CurParHdl,ParagHdl
		movelong [ParagHdl],ParagPtr
		moveword [ParagPtr],a
		dec a
		sta LastPar


		lda Start
		beq DoEnd

		moveword [ObjPtr]:#P_StartParag,Par
		jmi DoLastPar

		moveword [ObjPtr]:#P_StartLine,Q_Line
		rcall T_GetLinePtr,in=(Par:a,Q_Line:x),out=(LinePtr:ax)
		moveword [LinePtr],Offset
		brl Exit


DoEnd
		moveword [ObjPtr]:#P_EndParag,Par
		bmi DoLastPar

		moveword [ObjPtr]:#P_EndLine,a
		bne NotFirst

		lda Par
		beq Zero
		dec Par
		rcall T_GetParPtr,in=(Par:a),out=(ParagPtr:ax)
		moveword [ParagPtr]:#T_LineCount,a
NotFirst	dec a
Zero	sta Q_Line

		rcall T_GetParPtr,in=(Par:a),out=(ParagPtr:ax)
		subword [ParagPtr]:#T_LineCount,#1,LineCount

		rcall T_GetLinePtr,in=(Par:a,Q_Line:x),out=(LinePtr:ax)
		addword [LinePtr],[LinePtr]:#T_Length,Offset
		cmpw Q_Line,LineCount
		blt Exit

		cmpw Par,LastPar
		bge Exit

		inc Par
		moveword #7,Offset
		bra Exit


DoLastPar
		moveword LastPar,Par
		rcall T_GetParPtr,in=(a:a),out=(ParagPtr:ax)
		moveword [ParagPtr]:#T_LineCount,a
		dec a
		tax
		rcall T_GetLinePtr,in=(Par:a,x:x),out=(LinePtr:ax)
		addword [LinePtr],[LinePtr]:#T_Length,Offset

Exit
		RETURN
		ENDP





;------------------------------------------------------------------------------
;
; T_NewParHdl () : ParagHdl:l
;
; Returns any memory errors.

T_NewParHdl	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData
			;Using T_Data
			;Using T_TextEqu

		OUTPUT ParagHdl:l
		ERROR Err

		LOCAL RulerHdl:l,TextHdl:l,TextPtr:l,ParagPtr:l

		BEGIN


; Make RulerHdl
		call T_NewRuler,out=(RulerHdl:l),err=(Err)
		jcs Exit


; Make TextBlock
		call D_NeedHand,in=(#T_ParHeader+5:l),out=(TextHdl:l),err=(Err)
		jcs DisposeRuler

		movelong [TextHdl],TextPtr
		lda #T_ParHeader+5
		moveword a,[TextPtr]
		moveword a,[TextPtr]:#2
		moveword P_DefFont,[TextPtr]:#4
		shortm
		moveword P_DefStyle,[TextPtr]:#6
		moveword P_DefSize,[TextPtr]:#7
		moveword #0,[TextPtr]:#8
		moveword #CR,[TextPtr]:#11
		longm


; Init ParagHdl
		call D_NeedHand,in=(#T_ParInfoSize+2:l),out=(ParagHdl:l),err=(Err)
		jcs DisposeText


		movelong [ParagHdl],ParagPtr
		moveword #1,[ParagPtr]
		movelong TextHdl,[ParagPtr]:#T_TextBlock
		moveword #4,[ParagPtr]:#T_ParOffset
		movelong RulerHdl,[ParagPtr]:#T_RulerHdl
		lda #0
		moveword a,[ParagPtr]:#T_LinesHdl
		moveword a,[ParagPtr]:#T_LinesHdl+2

Exit	RETURN

DisposeText	tool _DisposeHandle,in=(TextHdl:l)
DisposeRuler	tool _DisposeHandle,in=(RulerHdl:l)
		bra Exit

		ENDP





;------------------------------------------------------------------------------
;
; T_OffsetPCount (ObjHdl:l,Change:w)
;
; Offsets the starting paragraph for all the objects in
; the thread after ObjHdl by adding Change to them.

T_OffsetPCount	PROC		EXPORT
			;Using P_ObjData

		INPUT ObjHdl:l,Change:w
		LOCAL ObjPtr:l


		BEGIN

		movelong [ObjHdl],ObjPtr
Loop	movelong [ObjPtr]:#P_NThread,ObjHdl
		cpzl ObjHdl
		beq Exit

		movelong [ObjHdl],ObjPtr
		ldy #P_StartParag
		addword Change,[ObjPtr]:y,[ObjPtr]:y
		movelong [ObjPtr]:#P_NThread,ObjHdl
		bra Loop


Exit	RETURN
		ENDP





;------------------------------------------------------------------------------
;
; T_OffsetPars (ParagNo:w,Change:w)
;
; Offsets the paragraph offsets for the rest of the paragraphs in
; the same Q_Text block as ParagNo.

T_OffsetPars	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu

		INPUT ParagNo:w,Change:w
		LOCAL ParagPtr:l,TextBlock:l,ParCount:w

		BEGIN

		rcall T_GetParPtr,in=(#0:a),out=(ParagPtr:ax)
		moveword [ParagPtr],ParCount

		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)
		movelong [ParagPtr]:#T_TextBlock,TextBlock


ParLoop	inc ParagNo
		cmpw ParagNo,ParCount
		bge Exit


		addwl #T_ParInfoSize,ParagPtr
		cmpl TextBlock,[ParagPtr]:#T_TextBlock
		bne Exit

		ldy #T_ParOffset
		moveword [ParagPtr]:y,a
		addword a,Change,[ParagPtr]:y
		bra ParLoop


Exit	RETURN
		ENDP




;------------------------------------------------------------------------------
;
; T_NewPars (ParagNo:w,Count:w)
;
; This routine makes space for the ParagInfo records in the array.
; The paragraphs themselves are uninitialized and inserted before
; ParagNo.  This operation occurs on the current thread.

T_NewPars	PROC		EXPORT
			;Using T_Data

		INPUT ParagNo:w,Change:w
		LOCAL ParagHdl:l,ParagPtr:l,OldCount:w,NewCount:w
		ERROR Err

		BEGIN

		tool _HUnlock,in=(T_CurParHdl:l)

		movelong T_CurParHdl,ParagHdl
		movelong [ParagHdl],ParagPtr
		moveword [ParagPtr],OldCount
		addword a,Change,NewCount
		jsl T_MulParag
		addword a,#2,a		  ;Two extra bytes for count


		call D_GrowHandle,in=(#0:w,a:w,ParagHdl:l),err=(Err)
		bcs Exit


		movelong [ParagHdl],ParagPtr
		moveword NewCount,[ParagPtr]
		addwl #2,ParagPtr


		lda ParagNo
		jsl T_MulParag
		addlong a,ParagPtr,s		 ;Src
		addword ParagNo,Change,a
		jsl T_MulParag
		addlong a,ParagPtr,s		 ;Dest
		subword OldCount,ParagNo,a
		jsl T_MulParag
		pushword #0
		pushword a				   ;Amount
		_BlockMove


Exit	RETURN
		ENDP





;------------------------------------------------------------------------------
;
; T_DeletePars (ParagNo:w,Change:w)
;
; This routine deletes paragraphs starting at ParagNo.  Q_Text
; must be disposed before the LinesHdl and RulerHdl fields.

T_DeletePars	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu

		INPUT ParagNo:w,Change:w

		LOCAL ParagHdl:l,ParagPtr:l,RulerHdl:l,LinesHdl:l
		LOCAL TextBlock:l,FirstBlock:l,LastBlock:l
		LOCAL ParagCount:w,CurParag:w,NewCount:w
		LOCAL StopParag:w,SrcParag:w,ParSize:w

		BEGIN

		movelong T_CurParHdl,ParagHdl

		lda Change
		jeq Exit

		rcall T_GetParPtr,in=(#0:a),out=(ParagPtr:ax)
		moveword [ParagPtr],ParagCount

		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)
		movelong [ParagPtr]:#T_TextBlock,FirstBlock

		addword ParagNo,Change,StopParag
		dec a
		rcall T_GetParPtr,in=(a:a),out=(ParagPtr:ax)
		movelong [ParagPtr]:#T_TextBlock,LastBlock


		moveword ParagNo,CurParag

ParLoop

		rcall T_GetParPtr,in=(CurParag:a),out=(ParagPtr:ax)

		movelong [ParagPtr]:#T_TextBlock,TextBlock
		cmpl TextBlock,FirstBlock
		beq DeleteChars
		cmpl TextBlock,LastBlock
		beq DeleteChars

		cmpw [ParagPtr]:#T_ParOffset,#4
		bne AuxStuff
		tool _DisposeHandle,in=(TextBlock:l)
		bra AuxStuff

DeleteChars
		rcall T_GetParSize,in=(CurParag:a),out=(ParSize:a)
		call T_LessRoom,in=(CurParag:w,#0:w,ParSize:w)


AuxStuff
		movelong [ParagPtr]:#T_LinesHdl,LinesHdl
		cpzl LinesHdl
		beq NoLines
		tool _DisposeHandle,in=(LinesHdl:l)
NoLines
		movelong [ParagPtr]:#T_RulerHdl,RulerHdl
		rcall T_UnUseRuler,in=(RulerHdl:ax)

		inc CurParag
		cmpw CurParag,StopParag
		jlt ParLoop





; Fix up paragraph array

FixIt
		rcall T_GetParPtr,in=(#0:a),out=(ParagPtr:ax)
		subword ParagCount,Change,NewCount
		moveword a,[ParagPtr]

		addword ParagNo,Change,SrcParag
		rcall T_GetParPtr,in=(a:a),out=(ParagPtr:ax)
		addlong #2,ParagPtr,s		;Src

		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)
		addlong #2,ParagPtr,s		;Dest

		subword ParagCount,SrcParag,a
		jsl T_MulParag
		pushword #0
		pushword a				   ;Amount
		_BlockMove


		tool _HUnlock,in=(ParagHdl:l)

		lda NewCount
		jsl T_MulParag
		pushword #0
		addword a,#2,s			   ;Two extra bytes for count
		pushlong ParagHdl
		jsl D_GrowHandle



Exit	RETURN
		ENDP




;-------------------------------------------------------------------------------
;
; T_CopyParEnd (ParagNo:w,Offset:w) : Hdl:l
;
; Hdl is a valid textblock with a valid paragraph in it.

T_CopyParEnd	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu

		INPUT  ParagNo:w,Offset:w
		OUTPUT Hdl:l
		ERROR  Err
		LOCAL  TextPtr:l,Ptr:l,HdlSize:w,TextSize:w

		BEGIN

		rcall T_GetParSize,in=(ParagNo:a),out=(a:a)
		subword a,Offset,a
		sta TextSize
		addword a,#T_ParHeader+4,HdlSize

		call D_NeedHand,in=(#0:w,HdlSize:w),out=(Hdl:l),err=(Err)
		bcs Exit


		rcall T_GetTextPtr,in=(ParagNo:a),out=(TextPtr:ax)
		call T_TrackFont,in=(TextPtr:l,Offset:w)

		movelong [Hdl],Ptr
		moveword HdlSize,[Ptr]
		moveword HdlSize,[Ptr]:#2
		movelong T_CurFont,[Ptr]:#4
		moveword T_CurColor,[Ptr]:#4+T_ParColor

		addwl Offset,TextPtr
		addwl #4+T_ParHeader,Ptr
		tool _BlockMove,in=(TextPtr:l,Ptr:l,#0:w,TextSize:w)

Exit	RETURN
		ENDP





;------------------------------------------------------------------------------
;
; T_PastePar (ParagNo:w,Offset:w,Hdl:l) : CharCount:w
;
; Paste the Q_Text in Hdl at the Offset of ParagNo.
; Hdl must contain a proper textblock with a proper paragraph.
; Disposes the Hdl.
;

T_PastePar	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu

		INPUT  ParagNo:w,Offset:w,Hdl:l
		OUTPUT CharCount:w
		ERROR  Err

		LOCAL TextPtr:l,Ptr:l,TextSize:w,Room:w
		LOCAL OrigFont:l,OrigColor:w


		BEGIN

		stz Err

		rcall T_GetTextPtr,in=(ParagNo:a),out=(TextPtr:ax)
		call T_TrackFont,in=(TextPtr:l,Offset:w)
		movelong T_CurFont,OrigFont
		moveword T_CurColor,OrigColor


		movelong [Hdl],Ptr
		subword [Ptr]:#T_TextSize,#T_ParHeader+5,TextSize  ;No CR either

		addwl #4,Ptr
		moveword [Ptr],T_NewFont
		shortm
		moveword [Ptr]:#T_ParStyle,T_NewAddStyle
		moveword [Ptr]:#T_ParSize,T_NewSize
		moveword [Ptr]:#T_ParColor,T_NewColor
		longm

		call T_MakeRoom,in=(ParagNo:w,Offset:w,TextSize:w)

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

		movelong [Hdl],Ptr
		addwl #T_ParHeader+4,Ptr
		tool _BlockMove,in=(Ptr:l,TextPtr:l,#0:w,TextSize:w)


		moveword #$ffff,T_FontFlags

		call T_InsertFont,in=(ParagNo:w,Offset:w,#1:w),out=(Room:w)
		addword a,Offset,Offset


		moveword OrigFont,T_NewFont
		shortm
		moveword OrigFont+2,T_NewAddStyle
		moveword OrigFont+3,T_NewSize
		moveword OrigColor,T_NewColor
		longm

		addword Offset,TextSize,Offset
		call T_InsertFont,in=(ParagNo:w,Offset:w,#1:w),out=(a:w)
		addword a,TextSize,a
		addword a,Room,CharCount

		stz T_FontFlags
		tool _DisposeHandle,in=(Hdl:l)

		RETURN
		ENDP




;------------------------------------------------------------------------------
;
; T_GetObject (ParagNo:w,LineNo:w) : ObjHdl:l
;

T_GetObject	PROC		EXPORT
			;Using P_ObjData
			;Using T_TextEqu

		INPUT ParagNo:w,LineNo:w
		OUTPUT ObjHdl:l

		LOCAL ParagPtr:l,ObjPtr:l,NextObj:l

		BEGIN

		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)
		movelong [ParagPtr]:#T_ObjHdl,ObjHdl

While
		cpzl ObjHdl
		beq Exit

		movelong [ObjHdl],ObjPtr
		cmpw ParagNo,[ObjPtr]:#P_EndParag
		blt Exit
		bne Cont

		cmpw LineNo,[ObjPtr]:#P_EndLine
		blt Exit

Cont
		movelong [ObjPtr]:#P_NThread,ObjHdl
		bra While

Exit	RETURN
		ENDP





;-------------------------------------------------------------------------------
;
; T_TopLine (ParagNo:w,LineNo:w) : ObjHdl:l,VertPos:w
;

T_TopLine	PROC		EXPORT
			;Using P_ObjData
			;Using T_Data
			;Using T_TextEqu

		INPUT  ParagNo:w,LineNo:w
		OUTPUT ObjHdl:l,VertPos:w
		LOCAL  ObjPtr:l,ParagPtr:l,CurLine:w

		BEGIN

		call T_GetObject,in=(ParagNo:w,LineNo:w),out=(ObjHdl:l)
		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)

		movelong [ObjHdl],ObjPtr
		cmpw [ObjPtr]:#P_StartParag,ParagNo
		beq First
		moveword [ParagPtr]:#T_ParStart,VertPos
		stz CurLine
		bra LineLoop

First
		moveword [ObjPtr]:#P_StartLine,CurLine
		stz VertPos


LineLoop	cmpw CurLine,LineNo
		bge Exit

		call T_LineHeight,in=(ParagNo:w,CurLine:w),out=(a:w)
		addword a,VertPos,VertPos
		inc CurLine
		bra LineLoop

Exit
		RETURN
		ENDP





;------------------------------------------------------------------------------
;
; T_LineHeight (ParagNo:w,LineNo:w) : Height:w
;

T_LineHeight	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu

		INPUT  ParagNo:w,LineNo:w
		OUTPUT Height:w
		LOCAL  LinePtr:l,Ascent:w,Descent:w

		BEGIN

		rcall T_GetLinePtr,in=(ParagNo:a,LineNo:x),out=(LinePtr:ax)
		moveword [LinePtr]:#T_Ascent,a
		and #$ff
		sta Ascent
		moveword [LinePtr]:#T_Descent,a
		and #$ff
		sta Descent

		rcall T_GetRulBits,in=(ParagNo:a),out=(a:a)
		rcall T_GetSpacing,in=(a:a,Ascent:x,Descent:y)
		addword a,Ascent,a
		addword a,Descent,Height

		RETURN
		ENDP



;-------------------------------------------------------------------------------
;
;T_InvertObj   (ObjHdl:l,StartPar:w,StartLine:w,StartPixs:w
;			  EndPar:w,EndLine:w,EndPixs:w)

T_InvertObj	PROC		EXPORT
			;Using P_ObjData
			;Using P_Data
			;Using T_Data
			;Using T_TextEqu

		INPUT ObjHdl:l
		INPUT StartPar:w,StartLine:w,StartPixs:w
		INPUT EndPar:w,EndLine:w,EndPixs:w

		LOCAL ObjPtr:l,ObjRect:r,InvRect:r
		LOCAL StartTop:w,StartHeight:w,EndTop:w,EndHeight:w

		BEGIN

		movelong [ObjHdl],ObjPtr
		cmpw [ObjPtr]:#P_PageNo,P_Page
		jne Exit

		moverect [ObjPtr]:#P_TRect,ObjRect

		pushlong !ObjRect
		subword P_ContentRect+2,P_H,s
		subword P_ContentRect,P_V,s
		_OffsetRect

		call T_TopLine,in=(StartPar:w,StartLine:w),out=(a:l,StartTop:w)
		call T_LineHeight,in=(StartPar:w,StartLine:w),out=(StartHeight:w)

		cmpw StartLine,EndLine
		bne MultLines
		cmpw StartPar,EndPar
		bne MultLines

		addword ObjRect,StartTop,InvRect
		addword a,StartHeight,InvRect+4
		addword ObjRect+2,StartPixs,InvRect+2
		addword ObjRect+2,EndPixs,InvRect+6
		tool _InvertRect,in=(!InvRect:l)
		brl Exit



MultLines

		call T_TopLine,in=(EndPar:w,EndLine:w),out=(a:l,EndTop:w)
		call T_LineHeight,in=(EndPar:w,EndLine:w),out=(EndHeight:w)


		addword ObjRect,StartTop,InvRect
		addword a,StartHeight,InvRect+4
		addword ObjRect+2,StartPixs,InvRect+2
		moveword ObjRect+6,InvRect+6
		tool _InvertRect,in=(!InvRect:l)


		moveword InvRect+4,InvRect
		addword ObjRect,EndTop,InvRect+4
		cmpw InvRect,InvRect+4
		beq NoMiddle

		moveword ObjRect+2,InvRect+2
		moveword ObjRect+6,InvRect+6
		tool _InvertRect,in=(!InvRect:l)


NoMiddle
		moveword InvRect+4,InvRect
		addword a,EndHeight,InvRect+4
		moveword ObjRect+2,InvRect+2
		addword a,EndPixs,InvRect+6
		tool _InvertRect,in=(!InvRect:l)

Exit
		RETURN
		ENDP




;-------------------------------------------------------------------------------
;
; T_InvertArea (StartObj:l,StartPar:w,StartLine:w,StartPixs:w,
;			   EndObj:l,EndPar:w,EndLine:w,EndPixs:w);
;

T_InvertArea	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData
			;Using T_Data
			;Using T_TextEqu

		INPUT StartObj:l,StartPar:w,StartLine:w,StartPixs:w
		INPUT EndObj:l,EndPar:w,EndLine:w,EndPixs:w

		LOCAL CurObj:l,CurPtr:l,ParagPtr:l
		LOCAL Par1:w,Line1:w,Pixs1:w,Par2:w,Line2:w,Pixs2:w


		BEGIN


		cmpw StartPar,EndPar
		blt NoSwap
		bne Swap
		cmpw StartLine,EndLine
		blt NoSwap
		bne Swap
		cmpw StartPixs,EndPixs
		blt NoSwap
		jeq Exit

Swap
		pushlong StartObj
		movelong EndObj,StartObj
		pulllong EndObj
		ldx StartPar
		moveword EndPar,StartPar
		stx EndPar
		ldx StartLine
		moveword EndLine,StartLine
		stx EndLine
		ldx StartPixs
		moveword EndPixs,StartPixs
		stx EndPixs
NoSwap




		movelong StartObj,CurObj

ObjLoop
		cpzl CurObj
		jeq Exit


		movelong [CurObj],CurPtr
		cmpl CurObj,StartObj
		beq FirstObj

		moveword [CurPtr]:#P_StartParag,Par1
		moveword [CurPtr]:#P_StartLine,Line1
		stz Pixs1
		bra SetEnd

FirstObj
		moveword StartPar,Par1
		moveword StartLine,Line1
		moveword StartPixs,Pixs1


SetEnd
		cmpl CurObj,EndObj
		bne UseEnd

		call T_OffThread,in=(EndPar:w,EndLine:w),out=(a:w)
		bne UseEnd

		moveword EndPar,Par2
		moveword EndLine,Line2
		moveword EndPixs,Pixs2
		bra DoCall


UseEnd
		moveword [CurPtr]:#P_EndParag,Par2
		moveword [CurPtr]:#P_EndLine,Line2
		subword [CurPtr]:#P_TRect+6,[CurPtr]:#P_TRect+2,Pixs2

		lda Line2
		beq PrevPar
		dec Line2
		bra DoCall
PrevPar	lda Par2
		beq DoCall
		dec Par2
		rcall T_GetParPtr,in=(Par2:a),out=(ParagPtr:ax)
		subword [ParagPtr]:#T_LineCount,#1,Line2


DoCall
		in CurObj:l,Par1:w,Line1:w,Pixs1:w
		in Par2:w,Line2:w,Pixs2:w
		xcall T_InvertObj


		cmpl CurObj,EndObj
		beq Exit
		movelong [CurObj],CurPtr
		movelong [CurPtr]:#P_NThread,CurObj
		brl ObjLoop


Exit	RETURN
		ENDP





;------------------------------------------------------------------------------;
; T_InvSelect ()
;
; Inverts the area described by the active globals.

T_InvSelect	PROC		EXPORT
			;Using T_Data

		lda T_TextSelect
		beq @NoSelect

		in T_DotObj:l,T_DotParag:w,T_DotOffset:w,T_DotLine:w
		out T_DotPixs:w
		xcall T_Offset2Pix

		in T_MarkObj:l,T_MarkParag:w,T_MarkOffset:w,T_MarkLine:w
		out T_MarkPixs:w
		xcall T_Offset2Pix

		in T_DotObj:l,T_DotParag:w,T_DotLine:w,T_DotPixs:w
		in T_MarkObj:l,T_MarkParag:w,T_MarkLine:w,T_MarkPixs:w
		xcall T_InvertArea
		bra Exit

@NoSelect
		jsl T_EraseCaret
Exit	rtl
		ENDP




;-----------------------------------------------------------------------------
;
; T_OffThread (ParagNo:w,Q_Line:w) : Off:w
;
; Returns true if the position described by the inputs is not in an object.


T_OffThread	PROC		EXPORT
			;Using P_ObjData
			;Using T_TextEqu
			;Using T_Data

		INPUT  ParagNo:w,Q_Line:w
		OUTPUT Off:w
		LOCAL  ParagPtr:l,ObjHdl:l,ObjPtr:l
		LOCAL  EndParag:w,EndLine:w

		BEGIN

		stz Off

		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)
		movelong [ParagPtr]:#T_ObjHdl,ObjHdl

ObjLoop
		movelong [ObjHdl],ObjPtr
		moveword [ObjPtr]:#P_EndParag,EndParag
		bmi Exit
		moveword [ObjPtr]:#P_EndLine,EndLine

		cmpw EndParag,ParagNo
		blt TryNext
		bne Exit
		cmpw Q_Line,EndLine
		blt Exit

TryNext
		movelong [ObjPtr]:#P_NThread,ObjHdl
		cpzl ObjHdl
		bne ObjLoop
		inc Off

Exit	RETURN
		ENDP




;------------------------------------------------------------------------------
;
; T_MovedDot ()
;
; Call this routine to D_Update the position of the D_Cursor.

T_MovedDot	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData
			;Using T_Data
			;Using T_TextEqu

		LOCAL ObjHdl:l,ObjPtr:l

		BEGIN

		in T_DotParag:w,T_DotOffset:w
		out T_DotObj:l,T_DotLine:w
		xcall T_Offset2Line

		call T_OffThread,in=(T_DotParag:w,T_DotLine:w),out=(a:w)
		beq NoDeact

		call T_Deactivate,in=(#1:w,#1:w)
		bra Exit

NoDeact
		lda T_TextSelect
		bne DoRul
		movelong T_DotObj,ObjHdl
		movelong [ObjHdl],ObjPtr
		cmpw [ObjPtr]:#P_PageNo,P_Page
		beq DoRul
		call P_ChangePage,in=(a:w,#1:w)

DoRul
		call T_DrawRuler

Exit
		RETURN
		ENDP




;-------------------------------------------------------------------------------
;
; T_PadThread (ObjHdl:l,VertPos:w)
;


T_PadThread	PROC		EXPORT
			;Using P_Data
			;Using P_ObjData


		INPUT ObjHdl:l,VertPos:w
		LOCAL ObjPtr:l,MaxVert:w

		BEGIN

		movelong [ObjHdl],ObjPtr
		subword [ObjPtr]:#P_TRect+4,[ObjPtr]:#P_TRect,MaxVert
		cmpw VertPos,MaxVert
		bge Loop

		lda #$FFFF
		moveword a,[ObjPtr]:#P_EndParag
		moveword a,[ObjPtr]:#P_EndLine

Loop
		movelong [ObjPtr]:#P_NThread,ObjHdl
		cpzl ObjHdl
		beq EndLoop
		movelong [ObjHdl],ObjPtr
		lda #$FFFF
		moveword a,[ObjPtr]:#P_StartParag
		moveword a,[ObjPtr]:#P_StartLine
		moveword a,[ObjPtr]:#P_EndParag
		moveword a,[ObjPtr]:#P_EndLine
		bra Loop
EndLoop


		RETURN
		ENDP
		END

