DEF vPreviousSpreadIndex EQU SCREEN_VARS_START
def vPreviousSpreadCard equ vPreviousSpreadIndex + 1

ScreenSpreadSelect:
  dw SpreadSelectSetup
  dw SpreadSelectUpdate
  dw SpreadSelectDraw
  dw SpreadSelectTeardown
  
SpreadSelectSetup:
  ld a, [vSelectedSpreadIndex]
  ld [vPreviousSpreadIndex], a
  ld a, [vSelectedSpreadCard]
  ld [vPreviousSpreadCard], a 
  ld a, 1
  ld [vBlocked], a
  
  call UpdateCurrentSpread
  
  ld hl, .asyncTask
  call Async_Spawn_HL

  ret  
  
.asyncTask ; setup task to be executed async
  ld a, HIGH(ZEROES)
  ld de, SAFE_DMA_LOCATION
  call RunDMA
  
  ld hl, SpreadSelectTilemap
  ld de, $9800
  ld b, 18
  ld c, 20
  call CopyTilesToMapUnsafe
  
  ld hl, CardPartTiles
  ld de, $9000 - ($10)*16
  ld bc, CardPartTilesEnd - CardPartTiles
  
  call CopyRangeUnsafe
  
  call DrawSpreadTask
  ld a, 0 
  ld [vBlocked], a 
  ret 
  
SpreadSelectUpdate:
  ld hl, rMYBTNP
  bit 4, [hl]
  jp z, .doneB
  ld hl, ScreenMainMenu
  call ChangeScene
  ret
.doneB
  bit 5, [hl]
  jp z, .doneA
  ld hl, ScreenCardRead
  call ChangeScene
  ret
.doneA

  ;up and down
  ld a, [vSelectedSpreadIndex]
  
  bit 3, [hl]  ; select the down key
  jp z, .doneDown ; skip the following code if down is not pressed
  inc a ; increment when they press down
.doneDown
  bit 2, [hl] ; select up key
  jp z, .doneUp ; skip the following code if up is not pressed
  dec a ; decrement when they press up because the deck has card 0 at the top
.doneUp
  ld hl, Spreads 
  call ArrayClampLooping
  ld [vSelectedSpreadIndex], a ; save clamped index

  ; left and righgt
  ld a, [vSelectedSpreadCard]
  ld hl, rMYBTNP
  bit 1, [hl]
  jp z, .doneLeft ; skip the following code if left is not pressed
  dec a 
.doneLeft
  bit 0, [hl]
  jp z, .doneRight ; skip the following code if right is not pressed
  inc a 
.doneRight
  ld hl, vCurrentSpread
  ld c, [hl]
  inc hl
  ld b, [hl]
  ld h, b 
  ld l, c 
  ; hl has current spread, a has index 
  call ArrayClampLooping
  ld [vSelectedSpreadCard], a 
  

  ld hl, vTime
  ld a, [rDELTAT]
  ld b, a 
  ld a, [vTime]
  add a, b
  ld [vTime], a 
  ld a, [vTime+1]
  adc a, 0 
  ld [vTime+1], a ; increment time. when the 16bit time register is greater 
  ; than 4096 ($10_00) then one second has passed. so that's satisfied when
  ; vTime+1 is equal to or greater than $10
  
  ld a, [vTime+1]
  cp a, $01
  jp c, .doneTimer ; if the timer is less than $0100, skip to end
  
  ;otherwise reset the timer
  ld a, 0 
  ld [vTime], a 
  ld [vTime+1], a 
  
  ld hl, SquaresTiles
  ld a, [vFrameCountSquares]
  inc a
  call ArrayClampLooping
  ld [vFrameCountSquares], a 

.doneTimer
  ld a, [vSelectedSpreadIndex]
  ld hl, vPreviousSpreadIndex
  cp a, [hl]
  jp nz, .spreadChanged ; update the spread if the spread changed
  
  ld a, [vSelectedSpreadCard]
  ld hl, vPreviousSpreadCard
  cp a, [hl]
  jp nz, .cardChanged ; update the spread if the card changed
 
  ret
  
.spreadChanged
  ld a, [vBlocked]
  cp a, 0
  ret nz ; early return if we're blocked
  ld a, 1
  ld [vBlocked], a ; block!
  
  ld a, [vSelectedSpreadIndex]
  ld [vPreviousSpreadIndex], a
  ld a, 0
  ld [vSelectedSpreadCard], a
  ld [vPreviousSpreadCard], a 
  call UpdateCurrentSpread
  
  ; execute an async call to DrawSpreadAsync.
  ld hl, DrawSpreadTask
  call Async_Spawn_HL
  
  ret

.cardChanged
  ld a, [vBlocked]
  cp a, 0 
  ret nz ; early return if the async threadd is in use
  ld a, 1
  ld [vBlocked], a ; block!
  
  ld a, [vSelectedSpreadIndex]
  ld [vPreviousSpreadIndex], a
  ld a, [vSelectedSpreadCard]
  ld [vPreviousSpreadCard], a 
  call UpdateCurrentSpread
  
  ; execute an async call to DrawSpread.
  ld hl, DrawSpreadTaskWithoutRefreshingBackgroundFirst
  call Async_Spawn_HL
  
  ret

UpdateCurrentSpread:
  ; find the correct spread address
  ld hl, Spreads
  inc hl ; skip length of spreads
  ld a, [vSelectedSpreadIndex]
  inc a ; we're decing at the start so we inc first to prepare...
  ld d, 0
.findSpread
  dec a
  jp z, .spreadFound
  
  ld e, [hl] ; skip cards in spread
  inc hl 
  add hl, de
  
.skipCardDescription ; e has number of cards in spread
  call PassList
  call PassList ; one card description has two strings
  dec e ; this will not work if the spreadd had zero cardss. i will overflow.
  jp nz, .skipCardDescription
  
  ld e, [hl] ; skip title of spread
  inc hl
  add hl, de
  
  ld e, [hl] ; skip description
  inc hl
  add hl, de
  
  jp .findSpread
.spreadFound
  ld a, l 
  ld [vCurrentSpread], a
  ld a, h
  ld [vCurrentSpread+1], a ; save the current spread (hl) into vcurrentspread. 
  ret
  
DrawSpreadTask: ; draw the spread large in the middle of the screen, and descs
  ; clear the space to scrolling background tiles
  ld de, $9800 + 32*5 + 3
  ld hl, ONES
  ld b, 8
  ld c, 14
  call CopyTilesToMapUnsafe
DrawSpreadTaskWithoutRefreshingBackgroundFirst:
  ; step past the spread layout to get to the spread description
  ld a, [vCurrentSpread]
  ld l, a 
  ld a, [vCurrentSpread+1]
  ld h, a
  ld e, [hl] ; e holds length of spread
  call PassList ; step past spread layout
  
.PassCardPositionDescriptions
  call PassList ; step past one pdesc
  call PassList ; step past two pdesc
  dec e ; we've looked at one 
  jp nz, .PassCardPositionDescriptions

  ; now hl is pointing at the title string
  ld de, $9800 + 32 + 1
  call PrintString

  ; now hl is pointing at the  description
  ld de, $9800 + (32*2) + 1
  call PrintString
  
  call DrawSpreadCards
  
  ld a, 0 
  ld [vBlocked], a
  ret

DrawSpreadCards:
  ld hl, $9800 + 32*5 + 3
  ld a, [vSelectedSpreadCard]
  ld d, 0
  ld e, a ; e contains the selected index
  call DrawSpreadBig ; draw the large cards for the spread

.drawSpreadPositionDescription
  ld a, [vCurrentSpread]
  ld l, a 
  ld a, [vCurrentSpread+1]
  ld h, a ; hl points at beginning of card postion list
  call PassList ; hl points at first card description
  ld a, [vSelectedSpreadCard]
  ld e, a 
  cp a, 0 
  jp z, .printIt
.stepForwardCardDescription
  call PassList
  call PassList
  dec e
  jp nz, .stepForwardCardDescription
.printIt
  ld de, $9800+32*15 + 6
  call PrintString
  ld de, $9800+32*16 + 6
  call PrintString

  ret

SpreadSelectDraw:
  ld hl, SquaresTiles
  inc hl 
  ld b, 0
  ld a, [vFrameCountSquares]
  ld c, a 
  add hl, bc 
  add hl, bc
  ld c, [hl]
  inc hl
  ld b, [hl]
  ld h, b
  ld l, c
  ld de, $8000+$100*16 + 1*16
  ld bc, (SquaresTileset8 - SquaresTileset7) / 8
  call CopyRangeUnsafeBy8s

  ret
SpreadSelectTeardown:
  ret  

DrawSpreadBig:
; hl for location on screen
; current spread address in vCurrentSpread
; e for index of selected card
  ld a, [vCurrentSpread]
  ld c, a 
  ld a, [vCurrentSpread+1]
  ld b, a 
  ld a, [bc]
  cp a, 0 ; length of spread
  jp z, .doneDrawingSpread ; return early if the spread is empty
  ld d, a ; length of spread in d
  inc d
.drawCards

  dec d
  jp z, .doneWithSpread ; if we're drawing zero remaining cards, stop drawing
  inc bc ; step forward
  push hl  ; need this bc drawsmallcard changes hl
  ld a, [bc]
  call DrawBigCard
  pop hl  
  jp .drawCards
.doneWithSpread 
; stack has spread address
; d is zero
; e should have currently selected index
  ld b, h
  ld c, l ; stash hl in bc for a mo; this should be a location in vram
  
  ld a, [vCurrentSpread]
  ld l, a
  ld a, [vCurrentSpread+1]
  ld h, a 
  ;spread address in hl

  inc hl ; skip the tiles length
  
  ld d, 0
  ld a, [vSelectedSpreadCard]
  ld e, a 
  
  add hl, de
  ld a, [hl] ; load card descriptor into a 
  
  ld h, b
  ld l, c; retrieve vram address
  call DrawBigCardSelected
  
.doneDrawingSpread
  ret

DrawBigCard: ; starting from screen location hl, draw a card at 
;the location described in a
  push de
  ld d, a 
  swap a
  and a, %0000_1111
  sla a
  ld e, a 

  ld a, d
  and a, %0000_1111

  ld d, 0
  add hl, de ; step right
  
  ld e, 64
  jp z, .drawCard
.stepDown
  add hl, de ; step down
  dec a
  jp nz, .stepDown
.drawCard
  ld de, 32
  ld [hl], -16 + $1
  inc hl 
  ld [hl], -16 + $2
  add hl, de
  ld [hl], -16 + $4
  dec hl 
  ld [hl], -16 + $3
  add hl, de 
  ld [hl], -16 + $3
  inc hl 
  ld [hl], -16 + $4
  add hl, de
  ld [hl], -16 + $6
  dec hl 
  ld [hl], -16 + $5
  
  pop de
  ret 

DrawBigCardSelected: ; starting from screen location hl, draw a card at 
;the location described in a
  push de
  push af 
  swap a
  ld d, 0
  and a, %0000_1111
  sla a
  ld e, a 
  add hl, de ; step right
  
  ld e, 64
  pop af
  and a, %0000_1111
  jp z, .drawCard
.stepDown
  add hl, de ; step down
  dec a
  jp nz, .stepDown
.drawCard
  ld de, 32
  ld [hl], -16 + $7
  inc hl 
  ld [hl], -16 + $8
  add hl, de
  ld [hl], -16 + $a
  dec hl 
  ld [hl], -16 + $9
  add hl, de 
  ld [hl], -16 + $b
  inc hl 
  ld [hl], -16 + $c
  add hl, de
  ld [hl], -16 + $e
  dec hl 
  ld [hl], -16 + $d
  
  pop de
  ret 

DrawSpreadMinimap:
; hl for location on screen
; bc for current spread address
; a for index of selected card
  push af
  push bc
  
  ld a, [bc]
  ld d, 0
  ld e, a ; length of spread in de
.drawCards
  ld a, e 
  cp a, 0
  jp z, .doneWithSpread ; if we're drawing zero remaining cards, stop drawing
  dec e
  inc bc ; step forward
  
  push hl ; need this bc drawsmallcard changes hl
  push bc
  ld a, [bc]
  ld bc, $1716
  call DrawSmallCard
  pop bc
  pop hl
  
  jp .drawCards
.doneWithSpread 
  pop bc ; stack: af 
  pop af
  ld d, 0
  ld e, a ; index of selected card in spread
  inc e ; skip the length
  
  push hl ; stack: hl
  ld h, b
  ld l, c ; put bc in hl temporarily so we can add to hl 
  
  add hl, de
  
  ld a, [hl]
  pop hl ; stack: empty
  ld bc, $1918
  call DrawSmallCard
  
  ret
  
DrawSmallCard: ; starting from screen location hl, draw a card at 
;the location described in a, top and bottom sprite in b and c
  push de
  push af 
  swap a
  ld d, 0
  and a, %0000_1111
  ld e, a 
  add hl, de ; step right
  
  ld e, 32
  pop af
  and a, %0000_1111
  jp z, .drawCard
:
  dec a
  add hl, de ; step down
  cp a, 0
  jp nz, :-
.drawCard
  ld [hl], b
  add hl, de
  ld [hl], c
  
  pop de
  ret 
  
CardPartTiles:
  db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
	db $00,$ff,$7f,$ff,$7f,$ff,$60,$ff,$6f,$ff,$6d,$fa,$6a,$fd,$6d,$fa
	db $00,$ff,$fe,$ff,$fe,$ff,$06,$ff,$f6,$ff,$56,$bf,$b6,$5f,$56,$bf
	db $6a,$fd,$6d,$fa,$6a,$fd,$6d,$fa,$6a,$fd,$6d,$fa,$6a,$fd,$6d,$fa
	db $b6,$5f,$56,$bf,$b6,$5f,$56,$bf,$b6,$5f,$56,$bf,$b6,$5f,$56,$bf
	db $6a,$fd,$6d,$fa,$6a,$fd,$6f,$ff,$60,$ff,$7f,$ff,$7f,$ff,$00,$ff
	db $b6,$5f,$56,$bf,$b6,$5f,$f6,$ff,$06,$ff,$fe,$ff,$fe,$ff,$00,$ff
	db $ff,$00,$80,$7f,$80,$7f,$9f,$7f,$9f,$7f,$98,$78,$99,$79,$9a,$7a
	db $ff,$00,$01,$fe,$01,$fe,$f9,$fe,$f9,$fe,$19,$1e,$19,$1e,$d9,$de
	db $9a,$7a,$99,$79,$98,$78,$9c,$78,$99,$78,$9b,$79,$9b,$7a,$9b,$7a
	db $d9,$de,$99,$9e,$d9,$de,$f9,$de,$99,$9e,$d9,$9e,$d9,$9e,$d9,$5e
	db $98,$78,$98,$7b,$99,$7a,$9a,$7c,$9f,$7b,$99,$79,$99,$79,$98,$78
	db $59,$5e,$19,$fe,$f9,$1e,$19,$1e,$d9,$de,$d9,$de,$59,$5e,$19,$1e
	db $98,$79,$98,$79,$98,$78,$9f,$7f,$9f,$7f,$80,$7f,$80,$7f,$ff,$00
	db $19,$9e,$19,$9e,$19,$1e,$f9,$fe,$f9,$fe,$01,$fe,$01,$fe,$ff,$00
CardPartTilesEnd:
SpreadSelectTilemap:
  db $09, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $02, $08
	db $03, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $04
	db $03, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $04
	db $06, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $07
	db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $09, $02, $02, $02, $02, $02, $02, $02, $02, $08, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $03, $00, $00, $00, $00, $00, $00, $00, $00, $04, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $03, $00, $00, $00, $00, $00, $00, $00, $00, $04, $01, $01, $01, $01, $01
	db $01, $01, $01, $01, $01, $06, $05, $05, $05, $05, $05, $05, $05, $05, $07, $01, $01, $01, $01, $01
SpreadSelectTilemapEnd: