--══════════════════════════════════════════════════════════════════════════════
-- rpm_bar_boxes.lua — RPM bar with box-by-box fill, one/both sides,
--                     red alert (solid or blinking) + debug autoplay
--══════════════════════════════════════════════════════════════════════════════

----------------------------------------- USER SETTINGS -----------------------
local BAR = { x = 0, y = 240, w = 512, h = 30 }

local START_RPM = 5300
local END_RPM   = 6750

local FILL_MODE = "left"
local BOXES_PER_HALF = 5
local BOXES_TOTAL    = 5
local BOX_GAP_PX     = 8

local COL_EDGE1 = rgb(1.00, 0.25, 0.00)
local COL_EDGE2 = rgb(1.00, 0.25, 0.00)
local COL_MID   = rgb(1.00, 0.25, 0.00)

local SPLIT1 = 0.50
local SPLIT2 = 0.5

local RED_RPM   = 8500
-- Options now: "off" | "solid" | "blink" | "blink_hide"  ← NEW
local RED_MODE  = "blink_hide"
local RED_COLOR = rgb(1.00, 00, 0.00)
local BLINK_HZ  = 4

local DRAW_OUTLINE = true
local OUTLINE_COL  = rgb(1,1,1)

-- Debug lock (fixed RPM)
local DEBUG_MODE = false
local DEBUG_RPM  = 6400

-- Debug auto-play sweep
local DEBUG_PLAY  = false
local DEBUG_SPEED = 1000
local DEBUG_HOLD  = 1.0

----------------------------------------- HELPERS -----------------------------
local function clamp(v,a,b) return (v<a) and a or (v>b) and b or v end
local function rect(x,y,w,h,c) display.rect{pos=vec2(x,y), size=vec2(w,h), color=c} end
local function outline(b)
  if not DRAW_OUTLINE then return end
  rect(b.x,   b.y-1, b.w,1, OUTLINE_COL);  rect(b.x,   b.y+b.h, b.w,1, OUTLINE_COL)
  rect(b.x-1, b.y-1, 1,b.h+2, OUTLINE_COL); rect(b.x+b.w, b.y-1, 1,b.h+2, OUTLINE_COL)
end

local function colorAtFrac(frac)
  if frac <= SPLIT1 then return COL_EDGE1
  elseif frac <= SPLIT2 then return COL_EDGE2
  else return COL_MID end
end

local function drawBoxesSpan(x0, wSpan, boxes, gap, fromLeft, lit, height, colorByIndex)
  if boxes <= 0 or wSpan <= 0 then return end
  local totalGap = gap * (boxes - 1)
  local boxW = (wSpan - totalGap) / boxes
  if boxW <= 0 then return end

  for i = 1, boxes do
    if i <= lit then
      local x = fromLeft
        and (x0 + (i-1) * (boxW + gap))
        or  (x0 + wSpan - i * boxW - (i-1) * gap)
      rect(x, BAR.y, boxW, height, colorByIndex(i, boxes))
    end
  end
end

local function drawFullRedBoxes()
  if FILL_MODE == "both" then
    local halfW = BAR.w * 0.5
    drawBoxesSpan(BAR.x,         halfW, BOXES_PER_HALF, BOX_GAP_PX, true,  BOXES_PER_HALF, BAR.h,
      function() return RED_COLOR end)
    drawBoxesSpan(BAR.x + halfW, halfW, BOXES_PER_HALF, BOX_GAP_PX, false, BOXES_PER_HALF, BAR.h,
      function() return RED_COLOR end)
  else
    drawBoxesSpan(BAR.x, BAR.w, BOXES_TOTAL, BOX_GAP_PX,
      FILL_MODE=="left", BOXES_TOTAL, BAR.h, function() return RED_COLOR end)
  end
  outline(BAR)
end

local function drawNormal(progress)
  progress = clamp(progress, 0, 1)
  if FILL_MODE == "both" then
    local halfW   = BAR.w * 0.5
    local litHalf = math.floor(progress * BOXES_PER_HALF + 1e-6)
    drawBoxesSpan(BAR.x,         halfW, BOXES_PER_HALF, BOX_GAP_PX, true,  litHalf, BAR.h,
      function(i, n) return colorAtFrac((i-0.5)/n) end)
    drawBoxesSpan(BAR.x + halfW, halfW, BOXES_PER_HALF, BOX_GAP_PX, false, litHalf, BAR.h,
      function(i, n) return colorAtFrac((i-0.5)/n) end)
  else
    local lit = math.floor(progress * BOXES_TOTAL + 1e-6)
    drawBoxesSpan(BAR.x, BAR.w, BOXES_TOTAL, BOX_GAP_PX, FILL_MODE=="left", lit, BAR.h,
      function(i, n) return colorAtFrac((i-0.5)/n) end)
  end
  outline(BAR)
end

----------------------------------------- RUNTIME -----------------------------
local car = ac.getCar(0)

local blinkTimer = 0
local demoRpm = START_RPM
local demoState = "ramp"  -- "ramp" → "hold"

function script.update(dt)
  if not car then return end
  blinkTimer = blinkTimer + (type(dt)=="number" and dt or 0)

  -- pick rpm
  local rpm
  if DEBUG_PLAY then
    if demoState == "ramp" then
      demoRpm = demoRpm + DEBUG_SPEED * dt
      if demoRpm >= RED_RPM then
        demoRpm = RED_RPM
        demoState = "hold"
        demoHoldT = 0
      end
    elseif demoState == "hold" then
      demoHoldT = (demoHoldT or 0) + dt
      if demoHoldT >= DEBUG_HOLD then
        demoRpm = START_RPM
        demoState = "ramp"
      end
    end
    rpm = demoRpm
  else
    rpm = DEBUG_MODE and DEBUG_RPM or (car.rpm or 0)
  end

  -- Red alert?
  if rpm >= RED_RPM and RED_MODE ~= "off" then
    if RED_MODE == "solid" then
      drawFullRedBoxes(); return
    elseif RED_MODE == "blink" then
      local period = 1 / math.max(0.1, BLINK_HZ)
      local on = (blinkTimer % period) < (period * 0.5)
      if on then drawFullRedBoxes(); return end
      -- fall through to normal on "off" frames (legacy blink)
    elseif RED_MODE == "blink_hide" then  -- NEW: exclusive blink (hide other LEDs)
      local period = 1 / math.max(0.1, BLINK_HZ)
      local on = (blinkTimer % period) < (period * 0.5)
      if on then
        drawFullRedBoxes()
      else
        -- draw no LEDs; optionally keep outline so placement is visible
        outline(BAR)
      end
      return
    end
  end

  -- Normal mode drawing
  local lo = math.min(START_RPM, END_RPM)
  local hi = math.max(START_RPM, END_RPM)
  local progress = (rpm - lo) / math.max(hi - lo, 1)
  drawNormal(progress)
end
