MoveRelearner:
	ld hl, .IntroText
	call PrintText
	call YesNoBox
	jr c, .cancel
	ld hl, .WhichMonText
	call PrintText
	call JoyWaitAorB

	ld b, $6
	farcall SelectMonFromParty
	jr c, .cancel

	ld a, [wCurPartySpecies]
	cp EGG
	jr z, .egg

	call IsAPokemon
	jr c, .no_mon

	call GetRelearnableMoves
	jr z, .no_moves

.menuloop
	ld hl, .WhichMoveText
	call PrintText
	call JoyWaitAorB
	call ChooseMoveToLearn
	jr c, .cancelMoveLearn

	ld a, [wMenuSelection]
	ld [wd265], a
	call GetMoveName
	ld de, wStringBuffer1
	call CopyName1
	ld b, 0
	predef LearnMove
	ld a, b
	and a
	push af
	call CloseSubmenu
	call SpeechTextBox
	pop af
	jr z, .reloadmenu

.cancel
	ld hl, .ComeAgainText
	call PrintText
	call JoyWaitAorB
	ret

.reloadmenu
	call .menuloop
	ret
	
.cancelMoveLearn
	call CloseSubmenu
	jr .cancel

.egg
	ld hl, .EggText
	call PrintText
	ret

.no_mon
	ld hl, .NotMonText
	call PrintText
	ret

.no_moves
	ld hl, .NoMovesToLearnText
	call PrintText
	ret

.IntroText
	text_jump MoveRelearner_IntroText
	db "@"

.WhichMonText
	text_jump MoveRelearner_WhichMonText
	db "@"

.WhichMoveText
	text_jump MoveRelearner_WhichMoveText
	db "@"

.HandedOverOneHeartScaleText
	text_jump MoveRelearner_HandedOverOneHeartScaleText
	db "@"

.ComeAgainText
	text_jump MoveRelearner_ComeAgainText
	db "@"

.EggText
	text_jump MoveRelearner_EggText
	db "@"

.NotMonText
	text_jump MoveRelearner_NotMonText
	db "@"

.NoMovesToLearnText
	text_jump MoveRelearner_NoMovesToLearnText
	db "@"

GetRelearnableMoves:
	; Get moves relearnable by CurPartyMon
	; Returns z if no moves can be relearned.
	ld hl, wd002
	xor a
	ld [hli], a
	ld [hl], $ff
	ld a, MON_SPECIES
	call GetPartyParamLocation
	ld a, [hl]
	ld [wCurPartySpecies], a

	push af
	ld a, MON_LEVEL
	call GetPartyParamLocation
	ld a, [hl]
	ld [wCurPartyLevel], a

	ld b, 0
	ld de, wd002 + 1
.loop
	push bc
	ld a, [wCurPartySpecies]
	dec a
	ld b, 0
	ld c, a
	ld hl, EvosAttacksPointers
	add hl, bc
	add hl, bc
	ld a, BANK(EvosAttacksPointers)
	call GetFarHalfword
.skip_evos
	ld a, BANK(EvosAttacks)
	call GetFarByte
	inc hl
	and a
	jr nz, .skip_evos

.loop_moves
	ld a, BANK(EvosAttacks)
	call GetFarByte
	inc hl
	and a
	jr z, .done
	ld c, a
	ld a, [wCurPartyLevel]
	cp c
	ld a, BANK(EvosAttacks)
	call GetFarByte
	inc hl
	jr c, .loop_moves

	ld c, a
	call CheckAlreadyInList
	jr c, .loop_moves
	call CheckPokemonAlreadyKnowsMove
	jr c, .loop_moves
	ld a, c
	ld [de], a
	inc de
	ld a, $ff
	ld [de], a
	pop bc
	inc b
	push bc
	jr .loop_moves
.done
	farcall GetPreEvolution
	pop bc
	jr c, .loop
	pop af
	ld [wCurPartySpecies], a
	ld a, b
	ld [wd002], a
	and a
	ret

CheckAlreadyInList:
	push hl
	ld hl, wd002 + 1
.loop
	ld a, [hli]
	cp $ff
	jr z, .nope
	cp c
	jr nz, .loop
	pop hl
	scf
	ret
.nope
	pop hl
	and a
	ret

CheckPokemonAlreadyKnowsMove:
	; Check if move c is in the selected pokemon's movepool already.
	; Returns carry if yes.
	push hl
	push bc
	ld a, MON_MOVES
	call GetPartyParamLocation
	ld b, NUM_MOVES
.loop
	ld a, [hli]
	cp c
	jr z, .yes
	dec b
	jr nz, .loop
	and a
	jr .done
.yes
	scf
.done
	pop bc
	pop hl
	ret

ChooseMoveToLearn:
; Open a full-screen scrolling menu
; Number of items stored in wd002
; List of items stored in wd002 + 1
; Print move names, PP, details, and descriptions
; Enable Up, Down, A, and B
; Up scrolls up
; Down scrolls down
; A confirms selection
; B backs out
	call FadeToMenu
	farcall BlankScreen
	call UpdateSprites
	ld hl, .MenuHeader
	call CopyMenuHeader
	xor a
	ld [wMenuCursorBuffer], a
	ld a, 1
	ld [wMenuScrollPosition], a
	call ScrollingMenu
	call SpeechTextBox
	ld a, [wMenuJoypad]
	cp B_BUTTON
	jr z, .carry
	ld a, [wMenuSelection]
	ld [wPutativeTMHMMove], a
	and a
	ret

.carry
	scf
	ret

.MenuHeader
	db $40 ; flags
	db 01, 01 ; start coords
	db 11, 19 ; end coords
	dw .menudata2
	db 1 ; default option

.menudata2
	db $30 ; pointers
	db 5, 8 ; rows, columns
	db 1 ; horizontal spacing
	dbw 0, wd002
	dba .PrintMoveName
	dba .PrintDetails
	dba .PrintMoveDesc

.PrintMoveName
	push de
	ld a, [wMenuSelection]
	ld [wd265], a
	call GetMoveName
	pop hl
	call PlaceString
	ret

.PrintDetails
	ld hl, wStringBuffer1
	ld bc, wStringBuffer2 - wStringBuffer1
	ld a, " "
	call ByteFill
	ld a, [wMenuSelection]
	cp $ff
	ret z
	push de
	dec a
	ld bc, MOVE_LENGTH
	ld hl, Moves + MOVE_TYPE
	call AddNTimes
	ld a, BANK(Moves)
	call GetFarByte
	ld [wd265], a
	; get move type
	and $3f
	; 5 characters
	ld c, a
	add a
	add a
	add c
	ld c, a
	ld b, 0
	ld hl, .Types
	add hl, bc
	ld d, h
	ld e, l

	ld hl, wStringBuffer1
	call PlaceString
	ld hl, wStringBuffer1 + 4
	ld [hl], "/"
	; get move class
	ld a, [wd265]
	and $c0
	rlca
	rlca
	ld c, a
	add a
	add a
	add c
	ld c, a
	ld b, 0
	ld hl, .Classes
	add hl, bc
	ld d, h
	ld e, l

	ld hl, wStringBuffer1 + 5
	call PlaceString
	ld hl, wStringBuffer1 + 9
	ld [hl], "/"

	ld a, [wMenuSelection]
	dec a
	ld bc, MOVE_LENGTH
	ld hl, Moves + MOVE_PP
	call AddNTimes
	ld a, BANK(Moves)
	call GetFarByte
	ld [wEngineBuffer1], a
	ld hl, wStringBuffer1 + 10
	ld de, wEngineBuffer1
	lb bc, 1, 2
	call PrintNum
	ld hl, wStringBuffer1 + 12
	ld [hl], "@"

	ld hl, SCREEN_WIDTH - 5
	pop de
	add hl, de
	push de
	ld de, wStringBuffer1
	call PlaceString
	pop de
	ret

.Types
	db "Norm@"
	db "Figh@"
	db " Fly@"
	db "Pois@"
	db "Grnd@"
	db "Rock@"
	db "Bird@"
	db " Bug@"
	db "Ghst@"
	db " Stl@"
	db " Fry@"

	db " Gas@"
	db "Wind@"
	db " Snd@"
	db " Tri@"
	db "Prsm@"
	db "Tp16@"
	db "Tp17@"
	db "Tp18@"
	db "Crse@"

	db "Fire@"
	db "Watr@"
	db "Gras@"
	db "Elec@"
	db "Psyc@"
	db " Ice@"
	db "Drgn@"
	db "Dark@"
.Classes
	db "Phys@"
	db "Spec@"
	db "Stat@"

.PrintMoveDesc
	push de
	call SpeechTextBox
	ld a, [wMenuSelection]
	cp $ff
	pop de
	ret z
	ld [wCurSpecies], a
	hlcoord 1, 14
	farcall PrintMoveDesc
	ret
