local class = require('lib_class')

local ControlSection = class(function(self, ...)
  self._gauges = {...}
end)

function ControlSection:reset()
  self._state = {}
  for _, gauge in ipairs(self._gauges) do
    mn.evaluateSEXP('( hud-set-custom-gauge-active ( false ) !' .. gauge .. '! )')
  end
end

function ControlSection:add(message, index)
  local state = self._state
  local gauge = self._gauges[index]
  if gauge then
    state[index] = { gauge = gauge, flashes = 4, message = message }
  else
    ba.warning('Unknown HUD control index ' .. tostring(index))
  end
end

function ControlSection:update(active)
  -- Not sequential - don't use ipairs.
  for _, entry in pairs(self._state) do
    local gauge = entry.gauge
    local flashes = entry.flashes
    if active or flashes == 0 then
      mn.evaluateSEXP('( hud-set-custom-gauge-active ( true ) !' .. gauge .. '! )')
      local handle = hu.getHUDGaugeHandle(gauge)
      handle.Text = ba.replaceTokens(entry.message:getMessage(true))
    else
      mn.evaluateSEXP('( hud-set-custom-gauge-active ( false ) !' .. gauge .. '! )')
      entry.flashes = flashes - 1
    end
  end
end

local showHudControl, reset, onFrame = (function()

  local active, flash

  local sections = {
    ControlSection(
      'Controls_Display_1',
      'Controls_Display_2',
      'Controls_Display_3',
      'Controls_Display_4',
      'Controls_Display_5',
      'Controls_Display_6'
    ),
    ControlSection( 
      'Controls_Display_1B',
      'Controls_Display_2B',
      'Controls_Display_3B',
      'Controls_Display_4B',
      'Controls_Display_5B',
      'Controls_Display_6B'
    )
  }

  local function getSection(section)
    return sections[section] or ba.error('Unknown control section ' .. tostring(section))
  end

  local function showHudControl(message, section, index)
    active = true
    getSection(section):add(message, index)
  end

  local function reset()
    active = false
    flash = 0
    for _, section in ipairs(sections) do
      section:reset()
    end
  end

  local function onFrame()
    local now = active and math.floor(mn.getMissionTime() * 2) or 0
    if now > flash then
      flash = now
      local active = (now % 2) == 0
      for _, section in ipairs(sections) do
        section:update(active)
      end
    end
  end

  return showHudControl, reset, onFrame

end)()

return { showHudControl = showHudControl, reset = reset, onFrame = onFrame }

