; -----------------------------------------------------------
; uIecSwitchS1: switch disk images on a uIEC (GUI, event handlers)
; revision history:	1.0, initial release
;		1.1, fix to run on sd2iec
;		1.2, bug fix for uIEC detection, usability fixes
; -----------------------------------------------------------
.if	Pass1
	.include	uIecSwitchSym
	.include	uIecSwitchMac
	.include	uIecSwitch.inc
	.include	cbm.inc
.endif
; -----------------------------------------------------------
start:	lda	#2	;50% stipple
	jsr	SetPattern
	LoadB	r2L,0
	LoadB	r2H,199
	LoadW	r3,0
	LoadW	r4,319
	jsr	Rectangle	;clear screen
	jsr	findUiec
	bcs	10$
	LoadW	r0,mainMenu
	lda	#0	;cursor on item #0
	jsr	DoMenu
	jsr	titleBar
	jsr	readDir
	jsr	doGui
	rts		;to MainLoop
10$	LoadW	r0,uIecDlg	;no uIEC present, whine 'n' bail
	jsr	DoDlgBox
	lda	savDrive
	sta	curDrive	;restore original drive
	jsr	OpenDisk
	jmp	EnterDeskTop
; -----------------------------------------------------------
; draw title bar
; -----------------------------------------------------------
titleBar:	lda	#9	;horizontal stripes
	jsr	SetPattern
	LoadB	r2L,0
	LoadB	r2H,14
	lda	mainMenu+4	;width of main menu
	clc
	adc	#1
	sta	r3L
	lda	mainMenu+5
	adc	#0
	sta	r3H
	LoadW	r4,319
	jsr	Rectangle
	LoadW	r0,title
	jsr	strWidth	;returns string width in a0
	LoadB	r1H,9
	LoadW	r11,320
	SubW	mainMenu+4,r11	;320 - menu width
	SubW	a0,r11	;minus string width
	clc
	ror	r11H
	ror	r11L	;divided by two
	AddW	mainMenu+4,r11	;plus menu width (i.e. right edge)
	PushW	r11	;trashed by Rectangle
	lda	#0	;clear
	jsr	SetPattern
	LoadB	r2L,1
	LoadB	r2H,13
	MoveW	r11,r3
	lda	r3L
	clc
	adc	a0L
	sta	r4L
	lda	r3H
	adc	a0H
	sta	r4H
	jsr	Rectangle	;clear title text area
	PopW	r11
	PushW	rightMargin
	LoadW	rightMargin,318
	PushB	windowTop
	LoadB	windowTop,0
	jsr	PutString
	PopB	windowTop
	PopW	rightMargin
	rts
; -----------------------------------------------------------
doInfo:	jsr	GotoFirstMenu
	LoadW	r0,infoDlg	;geos/info menu handler
	jsr	DoDlgBox
	rts
; -----------------------------------------------------------
doQuit:	jsr	GotoFirstMenu	;file/quit menu handler
	LoadW	r0,gp
	jsr	sendCmd
	ldx	msg	;byte 0 (partition type)
	dex		;translate to GEOS type
	txa
	ldy	drvUiec
	cmp	driveType-8,y
	beq	10$
	LoadW	r0,typeDlg	;wrong image type for device
	jsr	DoDlgBox
	lda	r0L
	cmp	#YES	;confirm exit?
	beq	10$
	rts		;no, back to MainLoop
10$	lda	savDrive
	sta	curDrive	;restore original drive
	jsr	OpenDisk
	jmp	EnterDeskTop
; -----------------------------------------------------------
; Handler for click on "Parent" button.
; -----------------------------------------------------------
doParent:	LoadW	r0,cdParent
	jsr	sendCmd
	lda	msg
	cmp	#'2'
	bcc	30$
	cmp	#'6'
	bne	10$
	lda	msg+1
	cmp	#'2'	;62, file not found?
	bne	10$
	LoadW	errorMsg, noParent
	bra	20$
10$	LoadW	errorMsg,msg
20$	LoadW	r0,errorDlg
	jsr	DoDlgBox	;fall thru, try to re-read directory
30$	jsr	readDir
	jsr	fillList
	rts
; -----------------------------------------------------------
; Handler for click on "Open" button.
; -----------------------------------------------------------
doOpen:	lda	selName
	bpl	10$	;anything selected?
	LoadW	errorMsg,noSelect
	LoadW	r0,errorDlg
	jsr	DoDlgBox
	rts
10$	clc
	adc	topName
	sta	a8L
	lda	#0
	adc	topName+1
	sta	a8H
	jsr	a8Name
	ldy	#0
	lda	(a8),y
	iny
	cmp	#$86	;subdirectory?
	beq	20$
	jsr	isImage
	bcs	15$
	LoadW	errorMsg,noEntry
	LoadW	r0,errorDlg
	jsr	DoDlgBox
	rts
15$	LoadW	a9,cdImage+2
	bra	30$
20$	LoadW	a9,chDir+2
30$	lda	(a8),y
	cmp	#$a0	;first $a0 is end of filename
	beq	40$
	sta	(a9),y
	iny
	cpy	#17
	bne	30$
40$	lda	#0
	sta	(a9),y
	lda	a9L
	sec
	sbc	#2
	sta	r0L
	lda	a9H
	sbc	#0
	sta	r0H
	jsr	sendCmd
	lda	msg	
	cmp	#'0'
	beq	50$
	LoadW	errorMsg,msg
	LoadW	r0,errorDlg
	jsr	DoDlgBox
	rts	
50$	jsr	readDir
	jsr	fillList
	rts
; -----------------------------------------------------------
; Down button dispatch routine.
; -----------------------------------------------------------
doDown:	lda	topName	;can bottom name increment?
	clc
	adc	#MAX_LIST
	sta	a0L
	lda	topName+1
	adc	#0
	sta	a0H
	CmpW	a0L,fCount
	bcc	10$
	jsr	beep
	rts
10$	inc	topName
	bne	20$
	inc	topName+1
20$	jsr	fillList
	lda	selName	;anything selected?
	bmi	40$
	beq	30$	;first item?
	dec	selName	;no, follow item in list
	lda	selName
30$	jsr	invList
40$	rts
; -----------------------------------------------------------
; Up button dispatch routine.
; -----------------------------------------------------------
doUp:	lda	topName+1	;already at top?
	bne	10$
	lda	topName
	bne	10$
	jsr	beep
	rts
10$	lda	topName
	sec
	sbc	#1
	sta	topName
	lda	topName+1
	sbc	#0
	sta	topName+1
	jsr	fillList
	lda	selName	;anything selected?
	bmi	30$
	cmp	#MAX_LIST-1	;last item?
	beq	20$
	inc	selName	;no, follow item in list
	lda	selName
20$	jsr	invList
30$	rts
; -----------------------------------------------------------
; Page down routine (called through otherPressVector).
; -----------------------------------------------------------
pageDown:	lda	topName
	clc
	adc	#MAX_LIST
	sta	a0L
	lda	topName+1
	adc	#0
	sta	a0H
	CmpW	a0L,fCount	;can page down at all?
	bcc	10$
	jsr	beep
	rts
10$	AddVW	MAX_LIST-2,a0L
	CmpW	a0L,fCount	;can go down full page?
	bcc	20$
	lda	fCount	;no, go to bottom
	sec
	sbc	#MAX_LIST
	sta	topName
	lda	fCount+1
	sbc	#0
	sta	topName+1
	bra	30$
20$	AddVW	MAX_LIST-1,topName ;yes, top item becomes bottom
30$	jsr	fillList
	lda	selName
	bmi	40$
	jsr	invList	;restore list selection display
40$	rts
; -----------------------------------------------------------
; Page up routine (called through otherPressVector).
; -----------------------------------------------------------
pageUp:	lda	topName+1	;can page up at all?
	bne	10$
	lda	topName
	bne	10$
	jsr	beep
	rts
10$	CmpWI	topName,#MAX_LIST-1 ;can go up full page?
	bcc	20$
	lda	topName	;yes,bottom item becomes top
	sec
	sbc	#MAX_LIST-1
	sta	topName
	lda	topName+1
	sbc	#0
	sta	topName+1
	bra	30$
20$	lda	#0	;no, go to top
	sta	topName
	sta	topName+1
30$	jsr	fillList
	lda	selName
	bmi	40$
	jsr	invList	;restore list selection display
40$	rts
; -----------------------------------------------------------
; draw GUI and fill listbox
; -----------------------------------------------------------
doGui:	lda	#1	;solid (shadow box)
	jsr	SetPattern
	LoadB	r2L,MAIN_T+8
	LoadB	r2H,MAIN_B+8
	LoadW	r3,MAIN_L+8
	LoadW	r4,MAIN_R+8
	jsr	Rectangle
;	------------------------------------------------
	lda	#0	;clear
	jsr	SetPattern
	LoadB	r2L,MAIN_T+1
	LoadB	r2H,MAIN_B-1
	LoadW	r3,MAIN_L+1
	LoadW	r4,MAIN_R-1
	jsr	Rectangle
	LoadB	r2L,MAIN_T
	LoadB	r2H,MAIN_B
	LoadW	r3,MAIN_L
	LoadW	r4,MAIN_R
	lda	#$ff	;solid line
	jsr	FrameRectangle
;	------------------------------------------------
	LoadB	r2L,LIST_T	;listbox for filenames
	LoadB	r2H,LIST_B
	LoadW	r3,LIST_L
	LoadW	r4,LIST_R
	lda	#$ff	;solid line
	jsr	FrameRectangle
;	------------------------------------------------
	LoadB	r3L,LIST_T
	LoadB	r3H,LIST_B
	LoadW	r4,SCROLL_B
	lda	#$ff	;solid line
	jsr	VerticalLine	;scrollbar boundary
;	------------------------------------------------
	LoadB	r1H,107
	LoadW	r11,200
	LoadW	r0,legend
	jsr	PutString
	ldx	#0
	stx	topName
	stx	topName+1
	dex
	stx	selName
	lda	fCount+1
	bne	10$
	lda	fCount
	beq	20$
10$	jsr	fillList
20$	LoadW	r0,icons
	jsr	DoIcons
	LoadW	otherPressVector,chkMouse
	rts
; -----------------------------------------------------------
; Fill listbox from list of filenames.
;	pass:	topName, index of first filename to show
;	destroyed:	a0L, a1H, a2, a8, a9 (from call to a8Name)
; -----------------------------------------------------------
fillList:	CmpW	fNames,fEnd	;empty list?
	bne	10$
	lda	#0	;clear
	jsr	SetPattern
	LoadB	r2L,LIST_T+1
	LoadB	r2H,LIST_B-1
	LoadW	r3,LIST_L+1
	LoadW	r4,SCROLL_B-1
	jsr	Rectangle	;clear listbox
	jsr	doThumb
	rts
10$	LoadB	a1H,LIST_T+9	;first baseline
	LoadB	a0L,0	;counter
	MoveW	topName,a8
	jsr	a8Name	;text pointer to a8
	lda	#LIST_T+1
	sta	r2L
	sta	a2L	;top of list item
	lda	#LIST_T+11
	sta	r2H
	sta	a2H	;bottom of list item
20$	LoadW	r3,LIST_L+1
	LoadW	r4,SCROLL_B-1
	lda	#0	;clear
	jsr	SetPattern
	jsr	Rectangle
	CmpW	a8L,fEnd	;at end of list?
	bcs	30$
	jsr	addName
30$	inc	a0L
	lda	a0L
	cmp	#MAX_LIST
	bcc	40$
	jsr	doThumb
	rts
40$	AddVW	17,a8L	;get next filename
	lda	a2L
	clc
	adc	#10	;height of list item
	sta	a2L
	sta	r2L
	lda	a2H
	clc
	adc	#10
	sta	a2H
	sta	r2H
	AddVB	10,a1H	;baseline
	bra	20$
; -----------------------------------------------------------
; Add filename to listbox. Images in bold, directories in italics.
; -----------------------------------------------------------
addName:	ldy	#0
	lda	(a8),y	;file type
	cmp	#$86	;subdirectory?
	bne	10$
	lda	#ITALICON
	bne	30$
10$	jsr	isImage
	bcc	20$
	lda	#BOLDON
	bne	30$
20$	lda	#PLAINTEXT
30$	sta	tmpEntry
	iny
40$	lda	(a8),y	;filename
	beq	60$
	cmp	#$ff
	bne	50$
	lda	#'~'	;icky 8.3 FAT filename
50$	sta	tmpEntry,y
	iny
	cpy	#17
	bne	40$
60$	lda	tmpEntry
	cmp	#PLAINTEXT
	beq	70$
	lda	#PLAINTEXT
	sta	tmpEntry,y
	iny
70$	lda	#0
	sta	tmpEntry,y
	LoadW	r0,tmpEntry
	MoveB	a1H,r1H	;baseline
	LoadW	r11,LIST_L+2
	jsr	PutString
	rts
; -----------------------------------------------------------
; Draw thumb for scrollbar.
; -----------------------------------------------------------
doThumb:	jsr	thumbPos	;sets thumb height and position
	sta	thumbSav
	lda	#0	;clear
	jsr	SetPattern
	LoadB	r2L,LIST_T+8
	LoadB	r2H,LIST_B-8
	LoadW	r3,SCROLL_B+1
	LoadW	r4,LIST_R-1
	jsr	Rectangle	;clear scroll area
	lda	#1	;solid
	jsr	SetPattern
	lda	thumbSav	;already calculated
	sta	r2L
	clc
	adc	thumbHi
	sta	r2H
	LoadW	r3,THUMB_L
	LoadW	r4,THUMB_L+(THUMB_WD-1)
	jsr	Rectangle
	rts
; -----------------------------------------------------------
; Calculate top position of thumb for scrollbar.
; Solve for offset from THUMBTOP:
; offset / (lowest thumb pos. - THUMBTOP) = topName / max. top item
; (topName * (lowest thumb pos. - THUMBTOP)) / max. top item = offset
; -----------------------------------------------------------
thumbPos:	lda	fCount+1	;all files fit in listbox?
	bne	10$
	lda	fCount
	cmp	#MAX_LIST
	bcs	10$
	lda	#THUMBMAX
	sta	thumbHi
	lda	#THUMBTOP
	rts
10$	jsr	thumbSiz	;sets thumbHi
	lda	#LIST_B
	sec
	sbc	#8	;for arrow icon
	sbc	thumbHi	;lowest possible thumb pos.
	sbc	#THUMBTOP
	sta	a9L	;src (byte)
	lda	topName
	sta	a8L	;dest (word)
	lda	topName+1
	sta	a8H
	ldx	#a8	;dest
	ldy	#a9	;src
	jsr	BMult	;topName * (lowest thumb pos. - THUMBTOP)
	lda	fCount
	sec
	sbc	#MAX_LIST
	sta	a9L	;max. top item
	lda	fCount+1
	sbc	#0
	sta	a9H
	ldx	#a8	;dest
	ldy	#a9	;src
	jsr	Ddiv	;divide result by max. top item
	lda	#THUMBTOP
	clc
	adc	a8L	;and add to THUMBTOP
	rts
; -----------------------------------------------------------
; Calculate height of thumb for scrollbar.
; Solve for thumb height:
; thumbHi / THUMBMAX = MAX_LIST / fCount
; (MAX_LIST * THUMBMAX) / fCount = thumbHi
; -----------------------------------------------------------
thumbSiz:	lda	#THUMBMAX
	sta	a9L
	lda	#MAX_LIST
	sta	a8L
	lda	#0
	sta	a8H
	ldx	#a8	;dest
	ldy	#a9	;src
	jsr	BBMult	;MAX_LIST * THUMBMAX
	lda	fCount
	sta	a9L
	lda	fCount+1
	sta	a9H
	ldx	#a8	;dest
	ldy	#a9	;src
	jsr	Ddiv	;(MAX_LIST * THUMBMAX) / fCount
	lda	a8L
	cmp	#THUMBMIN
	bcs	10$
	lda	#THUMBMIN
	bne	30$
10$	lda	#THUMBMAX
	cmp	a8L
	bcs	20$
	lda	#THUMBMAX
	bne	30$
20$	lda	a8L
30$	sta	thumbHi
	rts
; -----------------------------------------------------------
; Check for mouse click over listbox/scroll bar.
;	destroyed: a0
; -----------------------------------------------------------
chkMouse:	lda	mouseData
	bpl	20$
10$	rts		;ignore releases
20$	CmpW	fCount,fEnd	;empty list?
	beq	10$
	LoadB	r2L,LIST_T+1
	LoadB	r2H,LIST_T+11
	LoadW	r3,LIST_L+1
	LoadW	r4,SCROLL_B-1
	ldy	#0
	php
	sei
30$	jsr	IsMseInRegion
	cmp	#$ff
	beq	50$	;hit
	iny
	cpy	#MAX_LIST
	bne	40$
	plp		;click wasn't over listbox
	bra	ckScroll
40$	AddVB	10,r2L	;height of list item
	AddVB	10,r2H
	bra	30$
;	------------------------------------------------
;	click over filename: invert and check for double-click
;	------------------------------------------------
50$	LoadB	dblClickCount,#CLICK_COUNT
	plp
	tya		;list index
	clc
	adc	topName
	sta	a0L
	lda	topName+1
	adc	#0
	sta	a0H
	CmpW	a0L,fCount	;click over empty area?
	bcs	90$	;yes, exit
	cpy	selName	;already selected?
	beq	70$	;yes, check for double-click
	tya
	ldx	selName	;anything selected?
	bmi	60$	;no
	pha		;save list index
	txa
	jsr	invList	;deselect previous
	pla
60$	sta	selName
	jsr	invList	;select new one
70$	lda	dblClickCount	;check for double-click
	beq	90$	;double-click timed out?
	lda	mouseData
	bpl	70$	;still pressed?
80$	lda	dblClickCount	;no, released
	beq	90$	;double-click timed out?
	lda	mouseData	;no, check for 2nd click
	bmi	80$	;still released?
	jmp	doOpen	;double-click, open the file
90$	rts
ckScroll:	LoadB	r2L,LIST_T+8	;click above scroll thumb?
	ldx	thumbSav
	dex
	stx	r2H
	LoadW	r3,SCROLL_B+1
	LoadW	r4,LIST_R+1
	php
	sei
	jsr	IsMseInRegion
	plp
	cmp	#$ff
	bne	10$
	jsr	pageUp
	rts
10$	lda	thumbSav	;click below scroll thumb?
	clc
	adc	thumbHi
	sta	r2L
	LoadB	r2H,LIST_B-8
	LoadW	r3,SCROLL_B+1
	LoadW	r4,LIST_R-1
	php
	sei
	jsr	IsMseInRegion
	plp
	cmp	#$ff
	bne	20$
	jsr	pageDown
20$	rts
; -----------------------------------------------------------
; Invert listbox selection.
;	pass:	.A, index of item in list to invert
; -----------------------------------------------------------
invList:	sta	a8L	;dest
	LoadB	a9L,10	;src
	ldx	#a8L
	ldy	#a9L
	jsr	BBMult
	lda	#LIST_T+1
	clc
	adc	a8L
	sta	r2L
	lda	#LIST_T+11
	clc
	adc	a8L
	sta	r2H
	LoadW	r3,LIST_L+1
	LoadW	r4,SCROLL_B-1
	jsr	InvertRectangle
	rts
; -----------------------------------------------------------
; Get pointer to filename at given index.
;	pass:	a8, index into filename list
;	return:	a8, pointer to filename
;	destroyed:	a9
; -----------------------------------------------------------
a8Name:	LoadW	a9L,17	;length of fNames entry
	ldx	#a8	;dest (word)
	ldy	#a9	;src (byte)
	jsr	BMult
	lda	a8L
	clc
	adc	#[fNames
	sta	a8L
	lda	a8H
	adc	#]fNames
	sta	a8H
	rts
