-- The six-digit money keypad BankOfMom's GET and SAVE both put up
-- (engine/events/mom.asm Mom_SetUpWithdrawMenu / Mom_SetUpDepositMenu /
-- Mom_WithdrawDepositMenuJoypad).  Not a generic ScriptMenu: nothing else in
-- the game edits a number digit by digit, so this is its own screen the way
-- the naming keyboard and the move-list are theirs.
--
-- Layout, from the ASM's own coordinates:
--   `hlcoord 0, 0 / lb bc, 6, 18 / call Textbox` -- an interior 18x6 box at
--   (0,0), i.e. a 20x8 outer box.
--   (1,2) "SAVED@" / (12,2) wMomsMoney, PRINTNUM_MONEY | 3 bytes, width 6
--   (1,4) "HELD@"  / (12,4) wMoney,     PRINTNUM_MONEY | 3 bytes, width 6
--   (1,6) "DEPOSIT@" or "WITHDRAW@" / (12,6) the typed amount,
--   PRINTNUM_MONEY | PRINTNUM_LEADINGZEROS | 3, width 6
-- PRINTNUM_MONEY puts the yen sign right before the field and the six digits
-- after it, so column 12 is the yen and 13..18 are the digits -- which is
-- where Mom_WithdrawDepositMenuJoypad's blinking cursor (`hlcoord 13, 6` plus
-- wMomBankDigitCursorPosition) lands.
--
-- Mom_WithdrawDepositMenuJoypad's own joypad loop: UP/DOWN add or subtract
-- the place value under the cursor (through GiveMoney/TakeMoney, so a digit
-- clamps at 999999 or 0 rather than wrapping), LEFT/RIGHT move the cursor,
-- A accepts, B cancels.  wMomBankDigitCursorPosition starts at 5 -- the ones
-- digit, rightmost -- which is `.DigitQuantities`' own indexing: position 0
-- is the hundred-thousands digit, position 5 is the ones digit.  Only the
-- table's first six entries are ever read (`.getdigitquantity` always starts
-- at `.DigitQuantities` and offsets by the cursor position alone); the two
-- further groups of six the ASM lays down after it are unreachable from this
-- routine and are not carried here.

local Chrome = require("src.ui.gen2.Chrome")
local Sound = require("src.core.Sound")

local BankOfMom = {}
BankOfMom.__index = BankOfMom
BankOfMom.isOpaque = false

local BOX_X, BOX_Y, BOX_W, BOX_H = 0, 0, 20, 8
local SAVED_LABEL_X, SAVED_Y = 1, 2
local HELD_LABEL_X, HELD_Y = 1, 4
local KIND_LABEL_X, KIND_Y = 1, 6
local MONEY_X = 12
local DIGIT_X = 13 -- first digit column; DIGIT_X + position is the cursor

local MAX_MONEY = 999999

-- `.DigitQuantities`' first (and only reachable) six entries, 10^5..10^0.
local PLACE_VALUES = { 100000, 10000, 1000, 100, 10, 1 }

-- No line marker in any of these four (Mom_SavedString, Mon_WithdrawString,
-- Mom_DepositString, Mom_HeldString are one word each), so they are plain
-- literals here the way MartMenu's BUY/SELL/CANCEL labels are.
local SAVED_LABEL = "SAVED"
local HELD_LABEL = "HELD"
local DEPOSIT_LABEL = "DEPOSIT"
local WITHDRAW_LABEL = "WITHDRAW"

-- charmap.asm: ¥ is the currency glyph, same one MartMenu's moneyText uses.
local YEN = "\xc2\xa5"

-- PrintNum with PRINTNUM_MONEY, no PRINTNUM_LEADINGZEROS: the ¥ floats to
-- just before the first significant digit and the field stays 6 digits wide.
local function moneyText(amount)
  local digits = ("%06d"):format(math.max(0, math.floor(amount or 0)))
  local first = digits:find("[1-9]") or #digits
  return (" "):rep(first - 1) .. YEN .. digits:sub(first)
end

-- PrintNum with PRINTNUM_MONEY | PRINTNUM_LEADINGZEROS: all six digits shown.
local function moneyTextZeroed(amount)
  return YEN .. ("%06d"):format(math.max(0, math.floor(amount or 0)))
end

-- opts: kind ("deposit" | "withdraw"), saved (wMomsMoney), held (wMoney),
--       onDone(amount) -- nil for B
function BankOfMom.new(game, opts)
  opts = opts or {}
  local self = setmetatable({}, BankOfMom)
  self.game = game
  self.data = (game and game.data) or {}
  self.kind = opts.kind or "deposit"
  self.saved = opts.saved or 0
  self.held = opts.held or 0
  self.onDone = opts.onDone
  self.amount = 0
  self.position = 5 -- ones digit, rightmost
  self.blink = 0
  return self
end

function BankOfMom:wantsFillScale() return true end

function BankOfMom:finish(amount)
  if self.done then return end
  self.done = true
  if self.onDone then self.onDone(amount) end
end

function BankOfMom:playSfx(name)
  local sfx = self.data.audio and self.data.audio.sfx
  if sfx and sfx[Sound.resolve(self.data, name)] then
    Sound.play(self.data, name)
  end
end

function BankOfMom:update(dt)
  if self.done then return end
  self.blink = self.blink + (dt or 0)
  local input = self.game and self.game.input
  if not input then return end
  if input:wasPressed("up") then
    self.amount = math.min(self.amount + PLACE_VALUES[self.position + 1],
      MAX_MONEY)
  elseif input:wasPressed("down") then
    self.amount = math.max(self.amount - PLACE_VALUES[self.position + 1], 0)
  elseif input:wasPressed("left") then
    self.position = math.max(0, self.position - 1)
  elseif input:wasPressed("right") then
    self.position = math.min(5, self.position + 1)
  elseif input:wasPressed("a") then
    self:playSfx("Sfx_ReadText2")
    self:finish(self.amount)
  elseif input:wasPressed("b") then
    self:playSfx("Sfx_ReadText2")
    self:finish(nil)
  end
end

function BankOfMom:drawPanel()
  Chrome.box(BOX_X, BOX_Y, BOX_W, BOX_H)
  Chrome.print(SAVED_LABEL, SAVED_LABEL_X, SAVED_Y)
  Chrome.print(moneyText(self.saved), MONEY_X, SAVED_Y)
  Chrome.print(HELD_LABEL, HELD_LABEL_X, HELD_Y)
  Chrome.print(moneyText(self.held), MONEY_X, HELD_Y)
  Chrome.print(self.kind == "withdraw" and WITHDRAW_LABEL or DEPOSIT_LABEL,
    KIND_LABEL_X, KIND_Y)
  Chrome.print(moneyTextZeroed(self.amount), MONEY_X, KIND_Y)
  -- `hlcoord 13, 6 / ... / ld [hl], ' '` blanks the digit under the cursor
  -- for one beat every `hVBlankCounter and $10` window; a plain white square
  -- over that one tile every half second reads the same without a real
  -- VBlank counter to poll it against.
  if math.floor(self.blink * 2) % 2 == 1 then
    love.graphics.setColor(1, 1, 1, 1)
    love.graphics.rectangle("fill",
      (DIGIT_X + self.position) * 8, KIND_Y * 8, 8, 8)
  end
  love.graphics.setColor(1, 1, 1, 1)
end

function BankOfMom:draw()
  self:drawPanel()
end

return BankOfMom
