-- factoryos.programs.navpad — touch navigation pad.
-- Draws a d-pad on whatever terminal it gets (small monitor, pocket
-- computer screen, or a regular computer). Touch zones and arrow keys
-- both emit ui.nav events to whichever node hosts "core.ui".

local sched  = require("factoryos.core.sched")
local config = require("factoryos.core.config")
local Node   = require("factoryos.net.node")

local cfg = config.loadOr("/factoryos/node.cfg", {})
local node = Node.new(cfg)
assert(node:open(), "navpad: no modem")

local t = peripheral.find("monitor") or term
if t.setTextScale then pcall(t.setTextScale, 0.5) end
local w, h = t.getSize()

local last, lastOk = "", nil

local function draw()
  t.setBackgroundColor(colors.black)
  t.setTextColor(colors.white)
  t.clear()
  if w >= 9 and h >= 6 then
    local cx = math.floor(w / 2)
    t.setCursorPos(cx, 1); t.write("^")
    t.setCursorPos(1, 2); t.write("<"); t.setCursorPos(w, 2); t.write(">")
    t.setCursorPos(cx, 3); t.write("v")
    t.setCursorPos(1, h - 1); t.write("ENTER")
    t.setCursorPos(w - 3, h - 1); t.write("BACK")
  else
    t.setCursorPos(1, 1); t.write("NAV")
    t.setCursorPos(1, 2); t.write("keys")
  end
  t.setCursorPos(1, h)
  t.write((last .. " " .. tostring(lastOk == nil and "" or lastOk)):sub(1, w))
end

local function send(key)
  node:spawn(function()
    last = key; draw()
    local ok = node:call("core.ui", "nav", { key = key },
      { timeout = 1.5, chan = node.chan.ui, auth = cfg.token,
        to = cfg.master })
    lastOk = ok
    draw()
  end, "nav.send")
end

local function zone(x, y)
  if y >= h - 1 then
    return x <= w / 2 and "NAV_ENTER" or "NAV_BACK"
  end
  local third = math.max(1, math.floor(w / 3))
  if y <= math.max(1, math.floor(h / 3)) then
    return (x > third and x <= w - third) and "NAV_UP" or nil
  elseif y <= math.max(2, math.floor(2 * h / 3)) then
    if x <= third then return "NAV_LEFT" end
    if x > w - third then return "NAV_RIGHT" end
  else
    return (x > third and x <= w - third) and "NAV_DOWN" or nil
  end
end

node:on("monitor_touch", function(_, x, y)
  local k = zone(x, y)
  if k then send(k) end
end)

local KEYMAP = keys and {
  [keys.up] = "NAV_UP", [keys.down] = "NAV_DOWN",
  [keys.left] = "NAV_LEFT", [keys.right] = "NAV_RIGHT",
  [keys.enter] = "NAV_ENTER", [keys.backspace] = "NAV_BACK",
  [keys.space] = "NAV_ENTER",
} or {}
node:on("key", function(k) if KEYMAP[k] then send(KEYMAP[k]) end end)

node:on("mouse_click", function(_, x, y)
  local k = zone(x, y)
  if k then send(k) end
end)

draw()
node:run()
