-- factoryos.ui.compositor — cuts a Canvas into per-tile row segments and
-- pushes dirty rows to `displaytile` drivers as FNP events.
--
-- Tiles: { id = { x, y, w, h } } in canvas coordinates. Each tile driver
-- hosts service "display.tile.<id>". Use a wired display LAN in production;
-- the channel default exists so a demo can run over wireless.

local channels = require("factoryos.net.channels")

local M = {}
local Compositor = {}
Compositor.__index = Compositor

function M.new(node, canvas, tiles, chan)
  return setmetatable({
    node = node, cv = canvas, tiles = tiles or {},
    chan = chan or channels.display,
  }, Compositor)
end

--- Push all dirty canvas rows to every tile they intersect. Returns stats.
function Compositor:flush()
  local sent = 0
  for _, y in ipairs(self.cv:dirtyRows()) do
    local row = self.cv:row(y)
    for id, t in pairs(self.tiles) do
      if y >= t.y and y < t.y + t.h then
        local lx, lw = t.x, t.w
        local payload = {
          rows = { {
            y = y - t.y + 1,
            txt = row.txt:sub(lx, lx + lw - 1),
            fg  = row.fg:sub(lx, lx + lw - 1),
            bg  = row.bg:sub(lx, lx + lw - 1),
          } },
        }
        self.node:emit("display.tile." .. id, "blit", payload, { chan = self.chan })
        sent = sent + 1
      end
    end
  end
  return sent
end

return M
