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

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

	IMPORT	D_IsAlphaNum
	IMPORT	D_IsDigit
	IMPORT	D_IsLetter
	IMPORT	P_KillUndo
	IMPORT	P_Local2PL
	IMPORT	P_TrackCursor
	IMPORT	T_ClickCount
	IMPORT	T_Dot
	IMPORT	T_DotLine
	IMPORT	T_DotObj
	IMPORT	T_DotOffset
	IMPORT	T_DotParag
	IMPORT	T_DotPixs
	IMPORT	T_DrawRuler
	IMPORT	T_EraseCaret
	IMPORT	T_GetLinePtr
	IMPORT	T_GetTextPtr
	IMPORT	T_InvSelect
	IMPORT	T_InvertArea
	IMPORT	T_JunkLeft
	IMPORT	T_JunkRight
	IMPORT	T_LastOffset
	IMPORT	T_LastParag
	IMPORT	T_Mark
	IMPORT	T_MarkLine
	IMPORT	T_MarkObj
	IMPORT	T_MarkOffset
	IMPORT	T_MarkParag
	IMPORT	T_MarkPixs
	IMPORT	T_NextChar
	IMPORT	T_Offset2Pix
	IMPORT	T_Pt2Offset
	IMPORT	T_TextSelect

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

	ENTRY	T_InWord
	ENTRY	T_SelectLine
	ENTRY	T_SelectWord
	ENTRY	T_WordBounds



;--------------------------------------------------------------------------
;
; T_SwapDotMark ()
;

T_SwapDotMark	PROC		EXPORT
			;Using T_Data

		lda T_DotParag
		ldx T_MarkParag
		sta T_MarkParag
		stx T_DotParag

		lda T_DotOffset
		ldx T_MarkOffset
		sta T_MarkOffset
		stx T_DotOffset

		lda T_DotLine
		ldx T_MarkLine
		sta T_MarkLine
		stx T_DotLine

		lda T_DotPixs
		ldx T_MarkPixs
		sta T_MarkPixs
		stx T_DotPixs

		pushlong T_DotObj
		movelong T_MarkObj,T_DotObj
		pulllong T_MarkObj

		rtl
		ENDP




;------------------------------------------------------------------------------;
;
; T_Click (ObjHdl:l; Pt:l; ModFlags:w; Click:w)
;
; ThePoint should be in local coordinates.


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

		INPUT ObjHdl:l,Pt:l,ModFlags:w,Click:w

		LOCAL ObjPtr:l
		LOCAL NewParag:w,NewLine:w,NewOffset:w,NewPixs:w,NewObj:l
		LOCAL EndPixs:w,EndPos:w,StartPixs:w,StartPos:w


		BEGIN

		jsl P_KillUndo
		jsl T_EraseCaret

		in ObjHdl:l,Pt:l
		out NewParag:w,NewOffset:w,NewLine:w,NewPixs:w
		xcall T_Pt2Offset

		movelong ObjHdl,NewObj


		lda Click
		cmp #1
		jeq SingleClick

		cmpw NewParag,T_LastParag
		bne SingleClick
		cmpw NewOffset,T_LastOffset
		bne SingleClick
		lda T_ClickCount
		beq SingleClick
		cmp #1
		beq DoubleClick


TripleClick
		inc T_ClickCount
		inc T_TextSelect
		jsl T_InvSelect

		spacelong
		spacelong
		pushword NewParag
		pushword NewLine
		jsl T_SelectLine
		bra InitSelect


DoubleClick
		inc T_ClickCount
		inc T_TextSelect
		jsl T_InvSelect
		spacelong
		spacelong
		pushword NewParag
		pushword NewOffset
		pushword NewLine
		jsl T_SelectWord
InitSelect	pullword T_MarkPixs
		pullword T_MarkOffset
		pullword T_DotPixs
		pullword T_DotOffset

		moveword NewParag,T_DotParag
		moveword a,T_MarkParag
		moveword NewLine,T_DotLine
		moveword a,T_MarkLine
		inc T_TextSelect
		jsl T_InvSelect
		brl DragLoop


SingleClick
		moveword #1,T_ClickCount
		lda ModFlags
		and #ShiftKey
		beq ShiftUp

 		lda T_TextSelect
 		beq _NoSelect
		cmpw NewParag,T_DotParag
		blt Swap
				
		cmpw NewOffset,T_DotOffset
		bge ToAdd
Swap	jsl T_SwapDotMark
ToAdd	
		brl AddSelect
_NoSelect
		movelong T_Dot,T_Mark
		movelong T_Dot+4,T_Mark+4
		movelong T_Dot+8,T_Mark+8
		brl AddSelect
ShiftUp

		jsl T_InvSelect
		moveword NewParag,T_DotParag
		sta T_MarkParag
		moveword NewOffset,T_DotOffset
		sta T_MarkOffset
		moveword NewLine,T_DotLine
		sta T_MarkLine
		moveword NewPixs,T_DotPixs
		sta T_MarkPixs
		movelong NewObj,T_DotObj
		movelong NewObj,T_MarkObj



DragLoop
		tool _StillDown,in=(#0:w),out=(a:w)
		jeq Up


		tool _GetMouse,in=(!Pt:l)
		call P_TrackCursor,in=(!Pt:l)
		rcall P_Local2PL,in=(Pt:ax),out=(Pt:ax)


		in ObjHdl:l,Pt:l
		out NewParag:w,NewOffset:w,NewLine:w,NewPixs:w
		xcall T_Pt2Offset


		lda T_ClickCount
		cmp #1
		beq AddSelect
		cmp #2
		beq ByWord

ByLine
		spacelong
		spacelong
		pushword NewParag
		pushword NewLine
		jsl T_SelectLine
		bra SetNew


ByWord
		spacelong
		spacelong
		pushword NewParag
		pushword NewOffset
		pushword NewLine
		jsl T_SelectWord
SetNew	pullword EndPixs
		pullword EndPos
		pullword StartPixs
		pullword StartPos


		cmpw StartPos,T_Dot
		blt GoingUp
		moveword EndPos,NewOffset
		moveword EndPixs,NewPixs
		bra AddSelect
GoingUp	moveword StartPos,NewOffset
		moveword StartPixs,NewPixs



AddSelect

		in T_MarkObj:l,T_MarkParag:w,T_MarkLine:w,T_MarkPixs:w
		in NewObj:l,NewParag:w,NewLine:w,NewPixs:w
		xcall T_InvertArea

		movelong NewObj,T_MarkObj
		moveword NewParag,T_MarkParag
		moveword NewOffset,T_MarkOffset
		moveword NewLine,T_MarkLine
		moveword NewPixs,T_MarkPixs

		brl DragLoop
Up

		moveword NewOffset,T_LastOffset
		moveword NewParag,T_LastParag

		stz T_TextSelect
		cmpw T_DotParag,T_MarkParag
		beq SameParag
		blt InOrder
		bra DoSwap

SameParag
		rcall T_JunkRight,in=(T_DotParag:a,T_DotOffset:x)
		sta T_DotOffset
		cmpw T_DotOffset,T_MarkOffset
		beq NoSelect2
		blt InOrder
DoSwap	jsl T_SwapDotMark
InOrder	inc T_TextSelect
		rcall T_JunkLeft,in=(T_MarkParag:a,T_MarkOffset:x)
		sta T_MarkOffset
;		Cmpw T_DotOffSet,#T_ParHeader
; 		bne  DoJunkLeft
		rcall T_JunkRight,in=(T_DotParag:a,T_DotOffset:x)
		sta T_DotOffset
 		bra DoRuler
NoSelect2
DoJunkLeft		
 		rcall T_JunkLeft,in=(T_DotParag:a,T_DotOffset:x)
 		sta T_DotOffset
DoRuler
		call T_DrawRuler

Exit	RETURN
		ENDP





;------------------------------------------------------------------------------
;
; T_SelectWord (Parag:w,Pos:w,Q_Line:w): StartPos:w,StartPixs:w,EndPos:w,EndPixs:w
;

T_SelectWord	PROC		EXPORT
			;Using T_Data

		INPUT  Parag:w,Pos:w,Q_Line:w
		OUTPUT StartPos:w,StartPixs:w,EndPos:w,EndPixs:w

		BEGIN


		in Parag:w,Pos:w,Q_Line:w
		out StartPos:w,EndPos:w
		xcall T_WordBounds

		in T_DotObj:l,Parag:w,StartPos:w,Q_Line:w
		out StartPixs:w
		xcall T_Offset2Pix

		in T_DotObj:l,Parag:w,EndPos:w,Q_Line:w
		out EndPixs:w
		xcall T_Offset2Pix

Exit	RETURN
		ENDP





;-----------------------------------------------------------------------------
;
;
; T_WordBounds (ParagNo:w,Offset:w,LineNo:w) : StartOffset:w,EndOffset:w
;
;		'Word' is explicitly defined in Apple's Human Interface
;		Guidelines, with the exception that words are
;		necessarily confined to a single Q_Line.
;

T_WordBounds	PROC		EXPORT
			;Using T_Data
			;Using T_TextEqu

		INPUT  ParagNo:w,Offset:w,LineNo:w
		OUTPUT StartOffset:w,EndOffset:w
		LOCAL  LinePtr:l,TextPtr:l,CurOffset:w,Started:w
		LOCAL  GotLetter:w,GotDigit:w

		BEGIN

		rcall T_GetLinePtr,in=(ParagNo:a,LineNo:x),out=(LinePtr:ax)
		moveword [LinePtr],StartOffset
		addword a,[LinePtr]:#T_Length,EndOffset

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


		moveword StartOffset,CurOffset
		stz Started


		ldy StartOffset
		lda [TextPtr],y
		and #$ff
		cmp #CR
		jeq GotWord



; Loop through the characters in the current Q_Line

CLoop	jsl T_InWord
		bcs NotNormal

		stz GotLetter
		stz GotDigit

		jsl D_IsLetter
		bcs NotLetter
		inc GotLetter
		bra NotDigit


NotLetter	jsl D_IsDigit
		bcs NotDigit
		inc GotDigit


NotDigit	lda Started		 ; am I in the middle of a word?
		jne GetNext

		inc Started		 ; if not, I am now!
		bra GotStart


notnormal	cmp #''''
			beq @1
			cmp #'Õ'
			bne notapostrophe
@1
		lda GotDigit
		ora GotLetter
		beq Alone

		rcall T_NextChar,in=(ParagNo:a,CurOffset:x),out=(a:y)

		lda [TextPtr],y
		and #$ff
		jsl D_IsDigit
		bcc GetNext
		jsl D_IsLetter
		bcc GetNext
		bra Alone


NotApostrophe	cmp #'.'
		bne NotPeriod

		rcall T_NextChar,in=(ParagNo:a,CurOffset:x),out=(a:y)

		lda [TextPtr],y
		and #$ff
		jsl D_IsDigit
		bcs Alone
		lda Started
		bne GetNext
		inc Started
		bra GotStart


NotPeriod	cmp #','
		bne NotComma

		lda GotDigit
		beq Alone

		rcall T_NextChar,in=(ParagNo:a,CurOffset:x),out=(a:y)

		lda [TextPtr],y
		and #$ff
		jsl D_IsDigit
		bcc GetNext


NotComma	
		cmp #$CA			; non-breaking space.
		bne alone

		lda Started
		bne GetNext
		inc Started
		bra GotStart

Alone	stz Started


GotStart	ldy CurOffset
		cpy Offset
		bge GotWord
		sty StartOffset


GetNext	ldy CurOffset
		cpy EndOffset	   ; have I reached the end of the Q_Line?
		bgt GotWord		 ; if so, stop no matter what.

		rcall T_NextChar,in=(ParagNo:a,CurOffset:x),out=(CurOffset:a)
		tay

		lda [TextPtr],y
		and #$ff
		cmp #CR			 ; repeat unless at the end of the
		jne CLoop		   ; current paragraph.


GotWord
		moveword CurOffset,EndOffset

		RETURN
		ENDP





;------------------------------------------------------------------------------
;
;	 Can the char in A be part of a word (no matter what)?	;
;

T_InWord	PROC		EXPORT

		jsl	  D_IsAlphaNum
		bcc	  yes_w
		cmp	  #'-'
		beq	  yes_w
		cmp	  #'$'
		beq	  yes_w
		cmp	  #'%'
		beq	  yes_w
		cmp   #'£'
		beq   yes_w
		cmp   #'¢'
		beq   yes_w
		cmp   #'´'
		beq   yes_w
		cmp #'Û'
		beq yes_w
		sec
		rtl

yes_w
		clc
		rtl

		ENDP




;------------------------------------------------------------------------------
;
; T_SelectLine (ParagNo:w,LineNo:w) : StartPos:w,StartPixs:w,EndPos:w,EndPixs:w
;

T_SelectLine	PROC		EXPORT
			;Using T_TextEqu
			;Using T_Data

		INPUT  ParagNo:w,LineNo:w
		OUTPUT StartPos:w,StartPixs:w,EndPos:w,EndPixs:w
		LOCAL  LinePtr:l

		BEGIN

		rcall T_GetLinePtr,in=(ParagNo:a,LineNo:x),out=(LinePtr:ax)
		moveword [LinePtr],StartPos
		addword a,[LinePtr]:#T_Length,EndPos

		in T_DotObj:l,ParagNo:w,EndPos:w,LineNo:w
		out EndPixs:w
		xcall T_Offset2Pix

		stz StartPixs

		RETURN
		ENDP
		END

