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

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

	IMPORT	W_BoxAdTable
	IMPORT	W_BoxLocTable
	IMPORT	W_DTabPc
	IMPORT	D_DrawIcon
	IMPORT	W_LTabPc
	IMPORT	W_MargPc
	IMPORT	W_RTabPc
	IMPORT	W_TabWell
	IMPORT	W_IndentPc
	IMPORT	Q_Mask
	IMPORT	W_NothingPc
	IMPORT	W_oldnumtabs
	IMPORT	Q_Point
	IMPORT	W_TabIcons
	IMPORT	W_vr_indentm
	IMPORT	W_vr_leftm
	IMPORT	W_vr_numtabs
	IMPORT	W_vr_rightm
	IMPORT	W_vr_status
	IMPORT	W_vr_tablist

	import	W_r_changes
	import	W_RulOffset

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

	ENTRY	W_CheckWells
	ENTRY	W_DeleteTab
	ENTRY	W_InvertBitBox
	ENTRY	W_SetStatBit
	ENTRY	W_TrackTab
****************************************************************
*
*	   StyleWorks word processor RULERS private routines
*______________________________________________________________*
*
*	CONTENTS:
*	  W_OneRulClick(clickpt:l) -> changed:w
*	  W_DeleteTab(num:w)	;
*	  W_InsertTab(type:w,pos:w)
*	  W_TrackTab(type:w)	;
*	  W_SetStatBit(bit:w)
*	  W_InvertBitBox(bit:w)
*
****************************************************************

****************************************************************
*
*   W_OneRulClick(clickpt:l) -- W_Handle a single D_MouseDown event
*	in the visible ruler
*
****************************************************************
W_OneRulClick	PROC	EXPORT
	;Using W_RulerData

	input clickpt:l
	output changed:w
	local count:w,temprect:r,rectptr:l

	begin

	stz changed
	moveword W_vr_numtabs,W_oldnumtabs  ; redraw tabwells if nec.

	cmpw clickpt,#W_tabtop	 	; is the Q_Point in the numbers?
	jlt bye

	cmpw clickpt,#W_boxtop	 	; could it be in a box?
	jge boxstuff

*--------------------------------------------------------------*
*	   W_Handle click in tab area
*--------------------------------------------------------------*
	subword clickpt+2,#W_TabOffset,clickpt+2  ; adjust for clk detex'n

	subword clickpt+2,W_vr_leftm,a	; is it the left margin?
	blt notleft
	cmp #W_TabSlop
	bgt notleft

	subword clickpt+2,W_vr_indentm,a  ; COULD it be the W_Indent margin?
	blt justleft
	cmp #W_TabSlop
	bgt justleft

	cmpw clickpt,#W_tabtop+3   	; it could be.  Is it low enough?
	jgt itsindent

justleft	pushlong #W_NothingPc	  	; erase the margin markers
	addword W_vr_leftm,#W_TabOffset,s
	pushword #W_tabtop
	pushword #NotCopy
	jsl D_DrawIcon

	pushlong #W_NothingPc
	addword W_vr_indentm,#W_TabOffset,s
	pushword #W_tabtop
	pushword #NotCopy
	jsl D_DrawIcon

	pushword #W_rt_leftm
	addword  W_vr_leftm,#W_TabOffset,s
	pushword #W_tabtop
	jsl W_TrackTab

	lda W_r_changes
	ora #W_ch_left
	ora #W_ch_indent	   	; W_Indent changed, too.
	sta W_r_changes

	brl done

notleft	subword clickpt+2,W_vr_indentm,a  ; is it the W_Indent margin?
	blt notindent
	cmp #W_TabSlop
	bgt notindent

itsindent	pushlong #W_NothingPc	  	; erase the marker
	addword W_vr_indentm,#W_TabOffset,s
	pushword #W_tabtop
	pushword #NotCopy
	jsl D_DrawIcon

	pushlong #W_MargPc	 	; redraw the left margin, just in case
	addword W_vr_leftm,#W_TabOffset,s
	pushword #W_tabtop
	pushword #NotBic
	jsl D_DrawIcon

	pushword #W_rt_indentm
	addword  W_vr_indentm,#W_TabOffset,s
	pushword #W_tabtop
	jsl W_TrackTab

	lda W_r_changes
	ora #W_ch_indent
	sta W_r_changes

	brl done

notindent	subword clickpt+2,W_vr_rightm,a   ; is it the right margin?
	blt notright
	cmp #W_TabSlop
	bgt notright

	pushlong #W_NothingPc	  ; erase the marker
	addword W_vr_rightm,#W_TabOffset,s
	pushword #W_tabtop
	pushword #NotCopy
	jsl D_DrawIcon

	pushword #W_rt_rightm
	addword W_vr_rightm,#W_TabOffset,s
	pushword #W_tabtop
	jsl W_TrackTab

	lda W_r_changes
	ora #W_ch_right
	sta W_r_changes

	brl done

notright	stz count
tabloop	cmpw count,W_vr_numtabs	   ; is it a tab?
	jeq bye

	lda count
	asl a
	asl a
	tax
	lda clickpt+2
	sec
	sbc W_vr_tablist+W_ort_Location,x
	blt nexttab
	cmp #W_TabSlop
	bgt nexttab

	pushword W_vr_tablist+W_ort_Type:x	  	; for W_TrackTab...
	addword W_vr_tablist+W_ort_Location:x,#W_TabOffset,s
	pushword #W_tabtop	;

	pushword count	   	;delete the tab (and fix the screen)
	jsl W_DeleteTab

	jsl W_TrackTab	 	; ...here (This ;may* reinsert the tab)

	brl done

nexttab	inc count
	brl tabloop

*--------------------------------------------------------------*
*	   W_Handle click in box area
*--------------------------------------------------------------*
boxstuff	stz count

boxloop	lda count
	cmp #11	  	; am I through?
	jeq bye

	asl a
	asl a
	tax
	movelong W_BoxAdTable:x,rectptr   ; get the icon rectangle

	movelong [rectptr],temprect	 	; get my own copy
	movelong [rectptr]:#4,temprect+4

	pushlong !temprect	   	; W_offset by icon location
	pushlong W_BoxLocTable:x
	_OffsetRect

	spaceword
	pushlong !clickpt
	pushlong !temprect
	_PtInRect
	pla
	beq nextbox

	cmpw count,#8
	bge itsawell

	pushword count
	jsl W_SetStatBit

	brl done

itsawell	cmpw W_vr_numtabs,#W_maxTabs
	jeq done

	subword count,#9,s
	pushlong clickpt
	jsl W_TrackTab	 ; (this MAY insert a tab)
	bra done

nextbox	inc count
	brl boxloop

done	inc changed

bye	return

	ENDP

****************************************************************
*
*   W_DeleteTab(num:w) -- delete the num'th tab, and fix the screen
*
****************************************************************
W_DeleteTab	PROC	EXPORT
	;Using W_RulerData

	input num:w

	begin

	lda W_r_changes
	ora #W_ch_tabs
	sta W_r_changes

	dec W_vr_numtabs

	pushlong #W_NothingPc	  ; erase the marker
	lda num
	asl a
	asl a
	tax
	addword W_vr_tablist+W_ort_Location:x,#W_TabOffset,s
	pushword #W_tabtop
	pushword #NotCopy
	jsl D_DrawIcon

mloop	cmpw num,W_vr_numtabs
	bge endmloop

	lda num	  ; shuffle the next tab back one
	asl a
	asl a
	tax
	movelong W_vr_tablist+4:x,W_vr_tablist:x

	inc num
	bra mloop

endmloop	return

	ENDP

****************************************************************
*
*   W_InsertTab(type:w,pos:w) -- insert a tab
*
****************************************************************
W_InsertTab	PROC	EXPORT
	;Using W_RulerData

	input type:w,pos:w
	local count:w,count2:w

	begin

	lda W_r_changes
	ora #W_ch_tabs
	sta W_r_changes

	stz count
floop	cmpw count,W_vr_numtabs
	bge gotit

	lda count
	asl a
	asl a
	tax
	lda W_vr_tablist+W_ort_Location,x
	cmp pos
	bgt gotit

	inc count
	bra floop

gotit	moveword W_vr_numtabs,count2

mloop	cmpw count2,count
	ble insertit

	dec count2
	lda count2
	asl a
	asl a
	tax
	movelong W_vr_tablist:x,W_vr_tablist+4:x
	bra mloop

insertit	lda count
	asl a
	asl a
	tax
	moveword type,W_vr_tablist+W_ort_Type:x
	moveword pos,W_vr_tablist+W_ort_Location:x

	inc W_vr_numtabs

	return

	ENDP

****************************************************************
*
*   W_TrackTab - track the tab marker whose type is specified by
*	the accumulator
*
****************************************************************
W_TrackTab	PROC	EXPORT
	;Using W_RulerData

	input type:w,lastpt:l
	local iptr:l,Q_Point:l,redraw:w
	local llimit:w,rlimit:w,mlimit:w
	local dist:w,count:w

	begin

	_HideCursor

	inc redraw

	lda type	 ; Get a pointer to the icon
	inc a
	asl a
	asl a
	tax
	movelong W_TabIcons:x,iptr

*--------------------------------------------------------------*
*	 Compute limits for various tab types
*--------------------------------------------------------------*
	lda type
	cmp #W_rt_leftm	; ---- PREP FOR LEFT/W_Indent MARGIN ----
	beq left1
	cmp #W_rt_indentm
	jne notleft1

left1	subword W_vr_rightm,#W_pixPerInch*2,rlimit  ; limit to rightm - 2"

	lda W_vr_numtabs	   	; any W_Tabs?
	jeq gotlimits1	   	; if not, we have our limits

	subword W_vr_tablist+W_ort_Location,#W_TabSlop,a
	cmp rlimit	   	; if so, limit to the first tab
	bge gotlimits1
	sta rlimit

gotlimits1	cmpw type,#W_rt_indentm	; if W_Indent, start tracking!
	beq in_dent2

tabfirst	subword W_vr_indentm,W_vr_leftm,dist	; how far to W_Indent?
	bgt in_dent

	subword #-W_TabOffset,dist,llimit 	; if 'out-denting', keep
	brl adjlimits	   	; indentm positive

in_dent	subword rlimit,dist,rlimit	  	; else limit indentm as above
in_dent2	moveword #-W_TabOffset,llimit	 	; and keep leftm positive
	brl adjlimits

notleft1	cmp #W_rt_rightm	  	 ; ---- PREP FOR RIGHT MARGIN ----
	jne notright1

	addword  #8*W_pixPerInch,W_RulOffset,rlimit ; keep it below 8"

	lda W_vr_leftm	 	; which is closer, leftm or indentm?
	cmp W_vr_indentm
	bgt gotleft2
	lda W_vr_indentm

gotleft2	addword a,#W_pixPerInch*2,llimit  	; limit to that margin + 2"

	lda W_vr_numtabs	   	; any W_Tabs?
	jeq adjlimits	; if not, start trackin'

	dec a
	asl a
	asl a
	tax
	addword W_vr_tablist+W_ort_Location:x,#W_TabSlop,a

	cmp llimit	   	; if so, limit to the first tab
	jle adjlimits
	sta llimit
	brl adjlimits

notright1	subword W_vr_rightm,#W_TabSlop,rlimit	; ---- PREP FOR W_Tabs ----
	lda W_vr_leftm	 	; which is closer, leftm or indentm?
	cmp W_vr_indentm
	bgt gotleft3
	lda W_vr_indentm
gotleft3	addword a,#W_TabSlop,llimit

adjlimits	addword llimit,#W_TabOffset,llimit	; adjust limits for
	addword rlimit,#W_TabOffset,rlimit	; tab W_offset

*--------------------------------------------------------------*
*	The track loop	;
*--------------------------------------------------------------*
trloop	pushlong !Q_Point	  ; ---- GET AND MANGLE THE MOUSE LOC ----
	_GetMouse

	lda type
	bmi maybedrop	; check for decimal W_Tabs
	cmp #W_rt_leftm	; don't drop margins
	bge toohigh

maybedrop	cmpw Q_Point,#200	  	; << sigh... >>
	bgt toohigh
	cmpw Q_Point,#W_welltop	  	; is it in the tab area?
	bge toolow

toohigh	moveword #W_tabtop,Q_Point   	; constrain to the tab area
	bra goty

toolow	moveword #W_welltop,Q_Point  	; stay below the tab area

goty	lda Q_Point+2	  	; make the x coord even
	and #$fffe
	clc
	adc #W_TabOffset	   	; tweak it a bit
	sta Q_Point+2

	cmpw Q_Point+2,#10000	  	; << ... >>
	blt @ok
	moveword llimit,Q_Point+2
	bra limited

@ok	lda llimit	   	; put the Q_Point within the limits
	cmp Q_Point+2
	blt l_limited	; << ... >>
	sta Q_Point+2
	bra limited

l_limited	lda rlimit
	cmp Q_Point+2
	bgt limited
	sta Q_Point+2

limited	cmpw Q_Point,#W_welltop	  	; If I'm not in the tab
	jeq notnear	  	;	area, I don't need to
	stz count	; ---- CHECK FOR TAB COLLISION ----

tabloop	cmpw count,W_vr_numtabs
	jeq notnear

	lda count
	asl a
	asl a
	tax

	lda Q_Point+2	  	; get the distance to the left side of
	sec	  	; the other tab marker
	sbc W_vr_tablist+W_ort_Location,x
	sec	  	; << HMMM! >>
	sbc #W_TabOffset-W_TabSlop
	cmp #0	   	; << hmmm.... >>
	ble nexttab
	cmp #2*W_TabSlop
	blt nearone

nexttab	inc count	; maybe next W_Time
	bra tabloop

nearone	movelong lastpt,Q_Point	; don't move from last W_Time!

notnear	lda	  redraw	  	; ---- DRAW THE ICONS IF NECESSARY ----
	jne	  newicon

	spaceword
	pushword #0
	_StillDown	   	; is the button down?
	pla
	jeq endtrloop	; if not, stop tracking

	cmpl	 Q_Point,lastpt	; has the Q_Point changed?
	jeq	  trloop	  	; if not, keep tracking

	pushlong iptr	; erase the old one
	pushlong lastpt
	pushword #NotXor
	jsl	  D_DrawIcon

	cmpw	 type,#W_rt_leftm  	; W_Indent marker, too?
	bne	  newicon

	pushlong #W_IndentPc
	addword  lastpt+2,dist,s
	pushword lastpt
	pushword #notXor
	jsl	  D_DrawIcon

newicon	pushlong iptr	; draw the D_New one
	pushlong Q_Point
	pushword #NotXor
	jsl	  D_DrawIcon

	cmpw	 type,#W_rt_leftm  	; W_Indent marker, too?
	bne	  noindent

	pushlong #W_IndentPc
	addword  Q_Point+2,dist,s
	pushword Q_Point
	pushword #notXor
	jsl	  D_DrawIcon

noindent	movelong Q_Point,lastpt
	stz	  redraw

	brl	  trloop

*--------------------------------------------------------------*
*	Set the margin/tab and D_Update the ruler
*--------------------------------------------------------------*
endtrloop	pushlong iptr
	pushlong lastpt
	pushword #notXor
	jsl D_DrawIcon

	cmpw type,#W_rt_leftm
	bne erased2

	pushlong #W_IndentPc
	addword lastpt+2,dist,s
	pushword lastpt
	pushword #notXor
	jsl D_DrawIcon

erased2	cmpw Q_Point,#W_welltop
	beq bye

	pushlong iptr
	pushlong Q_Point
	pushword #notBic
	jsl D_DrawIcon

	cmpw type,#W_rt_leftm
	bne notleft3

	pushlong #W_IndentPc
	addword Q_Point+2,dist,s
	pushword Q_Point
	pushword #notBic
	jsl D_DrawIcon

	subword Q_Point+2,#W_TabOffset,W_vr_leftm
	addword Q_Point+2,dist,a
	subword a,#W_TabOffset,W_vr_indentm
	brl bye

notleft3	cmp #W_rt_indentm
	bne notindent3

	subword Q_Point+2,#W_TabOffset,W_vr_indentm
	brl bye

notindent3	cmp #W_rt_rightm
	bne notright3

	subword Q_Point+2,#W_TabOffset,W_vr_rightm
	brl bye

notright3	pushword type	; it must be a tab.
	subword Q_Point+2,#W_TabOffset,s
	jsl W_InsertTab

bye	jsl W_CheckWells	   	; redraw the tabwells?

goway	_ShowCursor

	return

	ENDP

****************************************************************
*
*   W_CheckWells -- redraw the tabwells if necessary
*
****************************************************************
W_CheckWells	PROC	EXPORT
	;Using W_RulerData

	lda W_vr_numtabs
	cmp W_oldnumtabs
	jeq goway

	pushlong #W_TabWell	; if W_NumTabs = W_maxTabs or W_maxTabs-1,
	pushword #W_t1	 	;  redraw the tab wells
	pushword #W_welltop
	pushword #notCopy
	jsl D_DrawIcon
	pushlong #W_TabWell
	pushword #W_t2
	pushword #W_welltop
	pushword #notCopy
	jsl D_DrawIcon
	pushlong #W_TabWell
	pushword #W_t3
	pushword #W_welltop
	pushword #notCopy
	jsl D_DrawIcon

	cmpw W_vr_numtabs,#W_maxTabs	; if W_maxTabs, then that's all!
	beq goway

	pushlong #W_LTabPc	 	; Otherwise, fill 'em, too.
	pushword #W_t1+W_THoff
	pushword #W_welltop
	pushword #NotBic
	jsl D_DrawIcon
	pushlong #W_DTabPc
	pushword #W_t2+W_THoff
	pushword #W_welltop
	pushword #NotBic
	jsl D_DrawIcon
	pushlong #W_RTabPc
	pushword #W_t3+W_THoff
	pushword #W_welltop
	pushword #NotBic
	jsl D_DrawIcon

goway	rtl

	ENDP

****************************************************************
*
*   W_SetStatBit -- set the specified status bit, reseting any
*	others in the same family, and change the appearance
*	of the ruler appropriately.
*
****************************************************************
W_SetStatBit	PROC	EXPORT
	;Using W_RulerData

	input bit:w
	local Q_Mask:w,family:w

	begin

	lda #1
	ldx bit
bitloop	beq gotit
	asl a
	dex
	bra bitloop
gotit	sta Q_Mask

	lda Q_Mask
	cmp #W_r_widow	 	; is it the widow bit?
	jne notwidow

	lda W_r_changes	; remember that I changed it...
	ora #W_r_widow
	sta W_r_changes

	pushword bit	 	; ...change it on the screen...
	jsl W_InvertBitBox

	lda W_vr_status	; ...then change it for real.
	eor #W_r_widow
	sta W_vr_status

	brl bye

notwidow	jlt notjust	  	; is it justification?
	moveword #W_r_just,family
	bra gotfam

notjust	moveword #W_r_spacing,family

gotfam	lda W_r_changes	; remember ONLY the last bit set in
	and #$ffff-family	; the family!!!
	ora Q_Mask
	sta W_r_changes

	lda W_vr_status
	and family
	cmp Q_Mask
	jeq bye	  	; if the bit's already set, do nothing

	ldx #0
jloop	lsr a
	beq gotoldj
	inx
	bra jloop

gotoldj	phx	  	; invert the old box
	jsl W_InvertBitBox

	pushword bit	 	; invert the D_New box
	jsl W_InvertBitBox

	lda W_vr_status	; set the bit
	eor #$ffff
	ora family	   	; (clear the old bit first)
	eor #$ffff
	ora Q_Mask
	sta W_vr_status

bye	return

	ENDP

****************************************************************
*
*   W_InvertBitBox -- invert the box associated with a status bit
*
****************************************************************
W_InvertBitBox	PROC	EXPORT
	;Using W_RulerData

	input bit:w
	local rectptr:r,temprect:r

	begin

	lda bit
	asl a
	asl a
	tax
	movelong W_BoxAdTable:x,rectptr   	; get the icon rectangle

	movelong [rectptr],temprect	 	; get my own copy
	movelong [rectptr]:#4,temprect+4

	pushlong !temprect	   	; W_offset by icon location
	pushlong W_BoxLocTable:x
	_OffsetRect

	inc temprect
	addword temprect+2,#2,temprect+2
	subword temprect+4,#2,temprect+4
	subword temprect+6,#4,temprect+6

	pushlong !temprect
	_InvertRect

	return

	ENDP
	END

