Moduł:Build bracket/StateChecks
Wygląd
local StateChecks = {}
-- =========================
-- 1) MODULE BINDINGS
-- =========================
-- Bound at runtime
local state, config, Helpers
-- Local aliases (filled in bind; with fallbacks)
local isempty, notempty
function StateChecks.bind(_state, _config, _Helpers)
state, config, Helpers = _state, _config, _Helpers
isempty = (Helpers and Helpers.isempty) or function(v) return v == nil or v == "" end
notempty = (Helpers and Helpers.notempty) or function(v) return v ~= nil and v ~= "" end
end
-- =========================
-- 2) CONTENT CHECKS
-- =========================
-- True when the entry at (col,row) is empty for rendering purposes.
-- For 'team' → check team text; for 'text' → check text; everything else counts as blank.
function StateChecks.isBlankEntry(col, row)
local colEntries = state.entries and state.entries[col]
if not colEntries then return true end
local e = colEntries[row]
if not e then return true end
local ct = e.ctype
if ct == "team" then
return isempty(e.team)
elseif ct == "text" then
return isempty(e.text)
end
-- headers/lines/blanks or anything else are non-content here
return true
end
-- =========================
-- 3) SEED VISIBILITY
-- =========================
-- Show seeds when forced, when this team has a seed, or when any teammate in the same match has a seed.
function StateChecks.showSeeds(j, i)
local col = state.entries and state.entries[j]
if not col then return false end
local e = col[i]
if not e or e.ctype ~= "team" then return false end
if config.forceseeds or notempty(e.seed) then
return true
end
local group = e.group
local tpm = state.teamsPerMatch[j] or 2
if tpm <= 1 then return false end
-- Teams are laid out every 2 rows per match.
local step = 2
local R = config.r
local function neighborHasSeed(idx)
local n = col[idx]
return n and n.ctype == "team" and n.group == group and notempty(n.seed)
end
-- Check teammates forward/back within the match block
for k = 1, tpm - 1 do
local plus = i + step * k
local minus = i - step * k
if plus <= R and neighborHasSeed(plus) then return true end
if minus >= 1 and neighborHasSeed(minus) then return true end
end
return false
end
-- =========================
-- 4) ROUND VISIBILITY (HIDE)
-- =========================
-- Mutates state.hide[j][hidx] to false when content is found under a header (keeps legacy semantics).
function StateChecks.teamLegs(j, i)
local col = state.entries and state.entries[j]
local roundDefault = (state.rlegs and state.rlegs[j]) or 1
if not col then return roundDefault end
local e = col[i]
if not e or e.ctype ~= "team" then return roundDefault end
local legs = roundDefault
if notempty(e.legs) then
legs = tonumber(e.legs) or legs
end
-- Treat nil/'' and strings containing 'nbsp' as blank
local function isScoreBlank(v)
if isempty(v) then return true end
return type(v) == "string" and v:find("nbsp", 1, true) ~= nil
end
if config.autolegs and e.score then
local l = 1
while not isScoreBlank(e.score[l]) do
l = l + 1
end
local inferred = l - 1
if inferred > 0 then
legs = inferred
end
end
return legs
end
-- =========================
-- 6) ROUND CONTENT CHECK
-- =========================
-- Used for 'byes' detection: true when there is no content until the next header (or end).
function StateChecks.roundIsEmpty(j, i)
local col = state.entries and state.entries[j]
if not col then return true end
local row, R = i + 1, config.r
while row <= R do
local e = col[row]
if e and e.ctype == "header" then break end
if not StateChecks.isBlankEntry(j, row) then
return false
end
row = row + 1
end
return true
end
-- =========================
-- 7) DEFAULT HEADER TEXT
-- =========================
-- Default header text when none provided (keeps legacy strings).
function StateChecks.defaultHeaderText(j, headerindex)
if headerindex ~= 1 then
return "Lower round " .. tostring(j)
end
local base = config.base or 0
local orig_j = j + base
local total = config.c_total or (config.c + base)
local rem = total - orig_j
if rem == 0 then
return "Final"
elseif rem == 1 then
return "Semifinals"
elseif rem == 2 then
return "Quarterfinals"
else
return "Round " .. tostring(orig_j)
end
end
-- =========================
-- 8) PATH PRESENCE CHECK
-- =========================
-- True when the path block between j → j+1 at row i has no visible lines at all.
function StateChecks.noPaths(j, i)
local hasCross = state.hascross and state.hascross[j]
local cols = hasCross and 3 or 2
-- Path cells: any nonzero border means a path
local pcj = state.pathCell and state.pathCell[j]
local pci = pcj and pcj[i]
if pci then
for k = 1, cols do
local edges = pci[k] and pci[k][1]
if edges and (
(edges[1] and edges[1] ~= 0) or
(edges[2] and edges[2] ~= 0) or
(edges[3] and edges[3] ~= 0) or
(edges[4] and edges[4] ~= 0)
) then
return false
end
end
end
-- Cross cells: left/right flag at index 1 means a cross path
if hasCross then
local ccj = state.crossCell and state.crossCell[j]
local cci = ccj and ccj[i]
if cci then
local left, right = cci.left, cci.right
if (left and left[1] == 1) or (right and right[1] == 1) then
return false
end
end
end
return true
end
return StateChecks