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

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

	IMPORT	P_BuildType
	IMPORT	P_BuildUndo
	IMPORT	P_FixMenus
	IMPORT	P_Page
	IMPORT	T_CalcFBytes
	IMPORT	T_Clear
	IMPORT	T_ClearBottom
	IMPORT	T_CopyParEnd
	IMPORT	T_CurColor
	IMPORT	T_CurFont
	IMPORT	T_CurStyleSize
	IMPORT	T_CutParag
	IMPORT	T_DeletePars
	IMPORT	T_DoControl
	IMPORT	T_DoRoom
	IMPORT	T_DotLine
	IMPORT	T_DotObj
	IMPORT	T_DotOffset
	IMPORT	T_DotParag
	IMPORT	T_DrawOneLine
	IMPORT	T_DrawParag
	IMPORT	T_DrawRuler
	IMPORT	T_EraseCaret
	IMPORT	T_FontFlags
	IMPORT	T_GetParPtr
	IMPORT	T_GetParSize
	IMPORT	T_GetTextPtr
	IMPORT	T_InsertFont
	IMPORT	T_JunkRight
	IMPORT	T_LockLines
	IMPORT	T_MakeRoom
	IMPORT	T_MovedDot
	IMPORT	T_NewAddStyle
	IMPORT	T_NewColor
	IMPORT	T_NewFont
	IMPORT	T_NewPars
	IMPORT	T_NewSize
	IMPORT	T_Offset2Line
	IMPORT	T_OffsetPCount
	IMPORT	T_PadThread
	IMPORT	T_PastePar
	IMPORT	T_PrevChar
	IMPORT	T_RecutParag
	IMPORT	T_TextSelect
	IMPORT	T_TopLine
	IMPORT	T_TrackFont
	IMPORT	T_UseRuler
	IMPORT	T_WriteFBytes
	IMPORT	T_JunkLeft
	IMPORT	T_JunkRight

;-----------------------------------------------------------------------------
;
; T_BumpParags (ParagNo:w; ObjHdl:l; ParStart:w; DoDraw:w);
;
; The starting position of ParagNo has changed.  I need to recalculate all
; the paragraphs below this one until a paragraph doesn't move and D_Update the
; ones that are currently on the screen.
;
; ObjHdl is the object that ParagNo starts in.
; ParStart is the pixel count from the top of ObjHdl to the top of ParagNo.

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

		INPUT ParagNo:w,ObjHdl:l,ParStart:w,DoDraw:w

		LOCAL ParagPtr:l,ParagCount:w
		LOCAL ObjPtr:l,MaxVert:w,ParEnd:w
		LOCAL OldObj:l,OldParStart:w,OldParHeight:w


		BEGIN

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

		movelong [ObjHdl],ObjPtr
		subword [ObjPtr]:#P_TRect+4,[ObjPtr]:#P_TRect,MaxVert


ParLoop
		lda ParagNo
		cmp ParagCount
		jge EraseBottom

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

		movelong [ParagPtr]:#T_ObjHdl,OldObj
		moveword [ParagPtr]:#T_ParStart,OldParStart
		moveword [ParagPtr]:#T_ParHeight,OldParHeight

		cmpl ObjHdl,OldObj
		bne Recut
		cmpw ParStart,OldParStart
		jeq Done


; If it used to cross object boundaries, recut it.
		addword OldParStart,OldParHeight,a
		cmp MaxVert
		bge Recut


; If it crosses object boundaries for D_New ParStart, recut it.

		addword ParStart,OldParHeight,a
		sta ParEnd
		cmp MaxVert
		bge Recut


; Set the ParStart since it could have changed and redraw paragraph

		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)
		moveword ParStart,[ParagPtr]:#T_ParStart

		lda DoDraw
		beq NextPar

		in ParagNo:w,#0:w,[ParagPtr]:#T_LineCount:w,ParStart:w
		xcall T_DrawParag
		bra NextPar



Recut
		in ObjHdl:l,ParagNo:w,ParStart:w
		out ObjHdl:l,ParEnd:w
		xcall T_RecutParag

		lda DoDraw
		beq NoDraw

		in ParagNo:w,#0:w,[ParagPtr]:#T_LineCount:w,ParStart:w
		xcall T_DrawParag
NoDraw

		movelong [ObjHdl],ObjPtr
		subword [ObjPtr]:#P_TRect+4,[ObjPtr]:#P_TRect,MaxVert


NextPar
		moveword ParEnd,ParStart
		inc ParagNo
		brl ParLoop



EraseBottom
		call T_PadThread,in=(ObjHdl:l,ParStart:w)
		lda DoDraw
		beq Done
		call T_ClearBottom,in=(ObjHdl:l,ParStart:w,P_Page:w)
Done
		jsl T_MovedDot


Exit
		RETURN
		ENDP




;----------------------------------------------------------------------------
;
; T_CmpLines (LHdl1:l,LHdl2:l,LCount1:w,LCount2:w,Bytes:w) :
;			  FirstLine:w,LastLine:w
;

T_CmpLines	PROC		EXPORT
			;Using T_TextEqu
			;Using T_Data

		INPUT  LHdl1:l,LHdl2:l
		INPUT  LCount1:w,LCount2:w
		INPUT  Bytes:w
		OUTPUT FirstLine:w,LastLine:w

		LOCAL LPtr1:l,LPtr2:l,LineNo:w
		LOCAL TotLength1:w,TotLength2:w

		BEGIN

		movelong [LHdl1],LPtr1
		movelong [LHdl2],LPtr2

		stz TotLength1
		stz TotLength2
		stz LineNo

FirstLoop
		ldy #T_Length
		addword [LPtr1]:y,TotLength1,TotLength1
		addword [LPtr2]:y,TotLength2,TotLength2
		cmpw TotLength1,TotLength2
		bne Different

		lda LineNo
		inc a
		cmp LCount1
		beq NoMore
		cmp LCount2
		beq NoMore
		sta LineNo

		addwl #T_LineInfoSize,LPtr1
		addwl #T_LineInfoSize,LPtr2
		bra FirstLoop

NoMore
		moveword LineNo,FirstLine
		lda LCount2
		dec a
		sta LastLine
		brl Exit


Different
		moveword LineNo,FirstLine
		sta LastLine
		cmpw LCount1,LCount2
		bne NoMore2
		addword TotLength2,Bytes,TotLength2
		cmpw TotLength1,TotLength2
		beq Exit


SecLoop
		lda LineNo
		inc a
		cmp LCount1
		beq NoMore2
		cmp LCount2
		beq NoMore2
		sta LineNo

		addwl #T_LineInfoSize,LPtr1
		addwl #T_LineInfoSize,LPtr2

		ldy #T_Length
		addword [LPtr1]:y,TotLength1,TotLength1
		addword [LPtr2]:y,TotLength2,TotLength2

		cmpw TotLength1,TotLength2
		bne SecLoop
Same

		moveword LineNo,LastLine
		bra Exit


NoMore2
		lda LCount2
		dec a
		sta LastLine

Exit	RETURN
		ENDP




;-------------------------------------------------------------------------------
;
; T_FixParag (ParagNo:w,LineNo:w,CharCount:w)
;

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

		INPUT ParagNo:w,LineNo:w,CharCount:w

		LOCAL ParagPtr:l,OldLinesHdl:l,LinesHdl:l
		LOCAL OldCount:w,NewCount:w,FirstLine:w,LastLine:w
		LOCAL EndVert:w,EndObjHdl:l,VertPos:w

		BEGIN


		rcall T_GetParPtr,in=(ParagNo:a),out=(ParagPtr:ax)
		moveword [ParagPtr]:#T_LineCount,OldCount
		rcall T_LockLines,in=(ParagNo:a),out=(OldLinesHdl:ax)



; Cut Paragraph

		in [ParagPtr]:#T_ObjHdl:l,ParagNo:w,[ParagPtr]:#T_ParStart:w
		out EndObjHdl:l,EndVert:w
		xcall T_CutParag

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


; Compare the lines

		in OldLinesHdl:l,LinesHdl:l,OldCount:w,NewCount:w,CharCount:w
		out FirstLine:w,LastLine:w
		xcall T_CmpLines


		tool _DisposeHandle,in=(OldLinesHdl:l)
		tool _HUnlock,in=(LinesHdl:l)


		cmpw LineNo,FirstLine
		bge Okay
		sta FirstLine
Okay


		call T_TopLine,in=(ParagNo:w,FirstLine:w),out=(a:l,VertPos:w)
		inc LastLine
		call T_DrawParag,in=(ParagNo:w,FirstLine:w,LastLine:w,VertPos:w)

		inc ParagNo
		call T_BumpParags,in=(ParagNo:w,EndObjHdl:l,EndVert:w,#1:w)

		RETURN
		ENDP





;------------------------------------------------------------------------------
;
; T_InsertCR ()
;

T_InsertCR	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu
			;Using P_Data

		LOCAL TextPtr:l,ParagPtr:l,ParOffset:w
		LOCAL EndObjHdl:l,MidVert:w,EndVert:w,RulerHdl:l
		LOCAL VertLPos:w,LastLine:w,BogusHdl:l

		BEGIN

		call P_BuildType
		jsl T_Clear

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

		call T_MakeRoom,in=(T_DotParag:w,T_DotOffset:w,#T_ParHeader+1:w)

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

		addwl T_DotOffset,TextPtr
		moveword #CR,[TextPtr]
		moveword T_CurFont,[TextPtr]:#T_ParFont+1
		moveword T_CurStyleSize,[TextPtr]:#T_ParStyle+1
		shortm
		moveword T_CurColor,[TextPtr]:#T_ParColor+1
		longm



; Make D_New paragraph

		call T_NewPars,in=(T_DotParag:w,#1:w)
		call T_OffsetPCount,in=(T_DotObj:l,#1:w)


; 1st paragraph -- Recut it and then draw the last Q_Line.

		rcall T_GetParPtr,in=(T_DotParag:a),out=(ParagPtr:ax)
		moveword [ParagPtr]:#T_ParOffset,ParOffset

		in [ParagPtr]:#T_ObjHdl:l,T_DotParag:w,[ParagPtr]:#T_ParStart:w
		out EndObjHdl:l,MidVert:w
		xcall T_RecutParag

		rcall T_GetParPtr,in=(T_DotParag:a),out=(ParagPtr:ax)
		moveword [ParagPtr]:#T_LineCount,a
		dec a
		sta LastLine

		call T_TopLine,in=(T_DotParag:w,LastLine:w),out=(a:l,VertLPos:w)

		in T_DotParag:w,LastLine:w,T_DotObj:l,VertLPos:w
		xcall T_DrawOneLine



; 2nd paragraph --
;			 Set ParOffset,ParStart and use the ruler.

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

		addword ParOffset,T_DotOffset,a
		inc a
		moveword a,[ParagPtr]:#T_ParOffset
		movelong EndObjHdl,[ParagPtr]:#T_ObjHdl
		moveword MidVert,[ParagPtr]:#T_ParStart
		movelong #0,[ParagPtr]:#T_LinesHdl
		movelong [ParagPtr]:#T_RulerHdl,RulerHdl
		rcall T_UseRuler,in=(RulerHdl:ax)

		in EndObjHdl:l,T_DotParag:w,MidVert:w
		out EndObjHdl:l,EndVert:w
		xcall T_RecutParag

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

		in T_DotParag:w,#0:w,[ParagPtr]:#T_LineCount:w,MidVert:w
		xcall T_DrawParag

		moveword #T_ParHeader,T_DotOffset

; Bump stuff.

		lda T_DotParag
		inc a
		call T_BumpParags,in=(a:w,EndObjHdl:l,EndVert:w,#1:w)

Exit
		RETURN
		ENDP




;------------------------------------------------------------------------------
;
; T_DeleteCR ()
;

T_DeleteCR	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu
			;Using P_Data

		LOCAL Hdl:l,NewOffset:w,CharCount:w
		LOCAL ParagPtr:l,LastLine:w

		BEGIN


		lda T_DotParag
		beq Exit

		call P_BuildUndo,in=(#P_NoUndo:w)
		call T_CopyParEnd,in=(T_DotParag:w,#T_ParHeader:w),out=(Hdl:l)
		bcs Exit

		lda T_DotParag
		dec a
		rcall T_GetParSize,in=(a:a),out=(a:a)
		dec a
		sta NewOffset


		call T_DeletePars,in=(T_DotParag:w,#1:w)
		dec T_DotParag


		in T_DotParag:w,NewOffset:w,Hdl:l
		out CharCount:w
		xcall T_PastePar

		moveword NewOffset,T_DotOffset
		rcall T_GetParPtr,in=(T_DotParag:a),out=(ParagPtr:ax)
		subword [ParagPtr]:#T_LineCount,#1,LastLine
		call T_FixParag,in=(T_DotParag:w,LastLine:w,CharCount:w)
		call T_DrawRuler

		jsl P_FixMenus

Exit	RETURN
		ENDP





;-----------------------------------------------------------------------------
;
; T_DeleteChar ()
;
; Deletes the character to the left of T_DotOffset.

T_DeleteChar	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu
			;Using P_Data

		LOCAL LOffset:w,ROffset:w,TextPtr:l
		LOCAL LeftFont:l,LeftColor:w,RightFont:l,RightColor:w
		LOCAL Room:w

		BEGIN

		rcall T_PrevChar,in=(T_DotParag:a,T_DotOffset:x),out=(LOffset:a)

		cmp #0
		bne DoChar
		jsl T_DeleteCR
		brl Exit
DoChar

		call P_BuildUndo,in=(#P_NoUndo:w)
		rcall T_JunkRight,in=(T_DotParag:a,T_DotOffset:x),out=(ROffset:a)
		rcall T_GetTextPtr,in=(T_DotParag:a),out=(TextPtr:ax)

		call T_TrackFont,in=(TextPtr:l,LOffset:w)
		movelong T_CurFont,LeftFont
		moveword T_CurColor,LeftColor

		call T_TrackFont,in=(TextPtr:l,ROffset:w)
		movelong T_CurFont,RightFont
		moveword T_CurColor,RightColor

		in LeftFont:l,LeftColor:w,RightFont:l,RightColor:w
		out a:w
		xcall T_CalcFBytes


;Room = Bytes-(RightOffset-LeftOffset)

		addword a,LOffset,a
		subword a,ROffset,Room
		call T_DoRoom,in=(T_DotParag:w,LOffset:w,Room:w)

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

		in TextPtr:l,LeftFont:l,LeftColor:w,RightFont:l,RightColor:w
		xcall T_WriteFBytes


		moveword LOffset,T_DotOffset


; This is a hack to prevent bug #1626, so that if you are at the beginning of
; a Q_Line, the previous Q_Line will get updated correctly.

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

		call T_FixParag,in=(T_DotParag:w,T_DotLine:w,Room:w)
		jsl P_FixMenus

Exit	RETURN
		ENDP





;-------------------------------------------------------------------------------
;
; T_InsertChars (ObjHdl:l,LineNo:w,ParagNo:w,Offset:w,CharsPtr:l,Bytes:w)
;

T_InsertChars	PROC		EXPORT
			;Using P_Data
			;Using T_Data
			;Using T_TextEqu

		INPUT ObjHdl:l,LineNo:w
		INPUT ParagNo:w,Offset:w
		INPUT CharsPtr:l,Bytes:w

		LOCAL TextPtr:l,ObjPtr:l,CharsWidth:l,LineWidth:w
		LOCAL LinePtr:l,VertPos:w,EndOffset:w,EndFont:l,EndColor:w

		BEGIN

		jsl P_BuildType
		jsl T_Clear


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


		pushlong CharsPtr
		lda Offset
		addlong a,TextPtr,s
		pushword #0
		pushword Bytes
		_BlockMove


		lda T_FontFlags
		beq NoChange

		addword Offset,Bytes,EndOffset
		rcall T_JunkRight,in=(ParagNo:a,EndOffset:x),out=(EndOffset:a)
		call T_TrackFont,in=(TextPtr:l,EndOffset:w)
		movelong T_CurFont,EndFont
		moveword T_CurColor,EndColor

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

		moveword EndFont,T_NewFont
		shortm
		moveword EndFont+2,T_NewAddStyle
		moveword EndFont+3,T_NewSize
		longm
		moveword EndColor,T_NewColor

		call T_InsertFont,in=(ParagNo:w,Offset:w,#1:w),out=(a:w)
		stz T_FontFlags
		bra FixIt

NoChange
		addword Offset,Bytes,Offset

FixIt
		moveword Offset,T_DotOffset


		call T_FixParag,in=(ParagNo:w,LineNo:w,Bytes:w)


Exit
		RETURN
		ENDP






;------------------------------------------------------------------------------;
;
; T_Key (EvtPtr:l)
;


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


		INPUT EvtPtr:l
		LOCAL ParagPtr:l,LinesHdl:l,LinePtr:l
		LOCAL Char:w,CharCount:w,CharBuf:r
		LOCAL MoreEvtRec:r,EvtRec:r,Src:l
		LOCAL CharsWidth:w,LineWidth:w,TextPtr:l,SpaceCount:w

		BEGIN

		moverect [EvtPtr],EvtRec
		moverect [EvtPtr]:#8,EvtRec+8

		lda EvtRec+2
		and #$ff
		sta Char

		cmp #SPACE
		beq SkipApple

		lda EvtRec+14
		and #AppleKey
		jne Exit
SkipApple

		_ObscureCursor
		jsl T_EraseCaret


;              lda Char
;              cmp #$24
;              jeq SpecChar1
;              cmp #$21
;              jeq SpecChar2
;              cmp #$23
;              jeq SpecChar3

              lda Char

		cmp #$7F
		jeq Delete
		cmp #SPACE
		bge InsertChars
		cmp #TAB
		beq InsertChars
		cmp #CR
		bne DoControl

		jsl T_InsertCR
		bra ToExit


DoControl
		call T_DoControl,in=(Char:w,EvtRec+14:w)
ToExit	brl Exit



InsertChars
		stz CharCount
		stz SpaceCount

SuckChars
		cmpw Char,#SPACE
		bne DidSpace

		lda EvtRec+14
		and #appleKey
		bne Sticky
		lda EvtRec+14
		and #optionKey
		beq DidSpace
Sticky	moveword #$CA,Char
DidSpace

		lda Char
		ldx CharCount
		sta CharBuf,x
		inx
		stx CharCount
		cpx #8
		beq NoMore
		cmp #CR
		beq NoMore

		tool _OSEventAvail,in=(#%101110:w,!EvtRec:l),out=(a:w)
		beq NoMore

		lda EvtRec
		cmp #3					; key event
		beq KeyEvent
		cmp #5					; auto-key event
		bne NoMore
KeyEvent

		lda EvtRec+2
		and #$ff
		cmp #$7F
		beq NoMore
		cmp #SPACE
		blt NoMore

		tool _GetOSEvent,in=(#%101000:w,!EvtRec:l),out=(a:w)

		lda EvtRec+2
		and #$ff
		sta Char
		brl SuckChars
NoMore


		in T_DotObj:l,T_DotLine:w,T_DotParag:w,T_DotOffset:w
		in !CharBuf:l,CharCount:w
		xcall T_InsertChars
		bra Exit



; Delete the previous chararcter

Delete
		lda T_TextSelect
		beq NoClear
		call P_BuildUndo,in=(#P_ClearTextUndo:w)
		jsl T_Clear
		bra Exit
NoClear
		jsl T_DeleteChar


Exit
		RETURN


;specChar1	 anop
;			 pushlong T_CurParHdl
;			 jsl T_DebugThread
;			 bra Exit
;
;specChar2	 anop
;			 lda T_BrkFlag
;			 beq Set
;			 stz T_BrkFlag
;			 bra Exit
;set		   inc T_BrkFlag
;			 bra Exit
;
;specChar3	 anop
;
;			 pushlong T_DotObj
;			 jsl T_DebugTextObj
;			 brl Exit
;
		ENDP
		END

