--══════════════════════════════════════════════════════════════════════════════
--  rpm_bar.lua   – single bar driven by engine RPM
--                 with per-1000 mapping + DEBUG RPM lock (no Extra buttons)
--══════════════════════════════════════════════════════════════════════════════

-------------------------------------------------------- USER SETTINGS --------
local BAR      = { x = 0, y = 122, w = 232, h = 12 }   -- bar rectangle
local BAR_BODY = rgb(1, 1, 1.00)                       -- main fill
local BAR_TIP  = rgb(1.00, 1.00, 1.00)                 -- tip colour

local TIP_STYLE = "fade"     -- "solid" | "fade"
local TIP_W     = 12

-- ── DEBUG: lock the bar to a specific RPM while calibrating marks ───────────
local DEBUG_MODE   = false     -- true = always use DEBUG_RPM below
local DEBUG_RPM    = 7000      -- rpm value to preview when debugging

-- ── Per-1k RPM mapping (edit to match your curved gauge) ────────────────────
local RPM_STEP       = 1000
-- Pixel offsets from BAR.x at 0k, 1k, 2k, … (last full 1k step).
-- Example for 0..7k across 232 px:
-- local RPM_MARKS_PX = { 0, 22, 44, 68, 98, 135, 178, 232 }
local RPM_MARKS_PX   = { 0, 12.5, 32, 55, 82, 122, 169, 200 }
local DRAW_MARKS     = true     -- show small ticks at 0k/1k/… while tuning

-------------------------------------------------------- FIXED COLOURS --------
-- Transparent background (no BG quad)
local OUT  = rgb(1,1,1)           -- outline colour
local TICK = rgb(1,1,1)           -- tick colour (for DRAW_MARKS/DEBUG)
local DBG  = rgb(1,0,0)           -- red cursor at DEBUG_RPM

-------------------------------------------------------- HELPERS --------------
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)
  rect(b.x,   b.y-1, b.w,1, OUT);  rect(b.x,   b.y+b.h, b.w,1, OUT)
  rect(b.x-1, b.y-1, 1,b.h+2, OUT); rect(b.x+b.w, b.y-1, 1,b.h+2, OUT)
end
local function clamp(v,a,b) return (v<a) and a or (v>b) and b or v end
local function mix(a,b,t)   return rgb(
  a.r+(b.r-a.r)*t, a.g+(b.g-a.g)*t, a.b+(b.b-a.b)*t) end
local function safe(o,k)    local ok,v=pcall(function()return o[k] end)
                            return ok and v or nil end

-- draw filled bar by pixel width (no background quad) -------------------------
local function drawBarPx(b, fillPx)
  if fillPx>0 then
    local fill = math.min(b.w, math.floor(fillPx+0.5))
    if TIP_STYLE=="solid" then
      local body = math.max(fill - TIP_W, 0)
      if body>0 then rect(b.x,b.y,body,b.h,BAR_BODY) end
      rect(b.x+body,b.y,fill-body,b.h,BAR_TIP)
    else  -- fade
      local fade = math.min(fill, TIP_W)
      local body = fill - fade
      if body>0 then rect(b.x,b.y,body,b.h,BAR_BODY) end
      local slice = fade / 8
      for i=0,7 do
        local sx = b.x + body + math.floor(i*slice+0.5)
        local sw = math.ceil(slice)
        if sx+sw > b.x+fill then sw = b.x+fill - sx end
        if sw<=0 then break end
        rect(sx,b.y,sw,b.h,mix(BAR_BODY,BAR_TIP,(i+0.5)/8))
      end
    end
  end
  outline(b)
end

-- build marks for current limiter -------------------------------------------
local function makeMarks(limit)
  local steps = math.floor(limit / RPM_STEP)
  local marks = {}
  if RPM_MARKS_PX and #RPM_MARKS_PX >= steps+1 then
    for i=0,steps do marks[i+1] = RPM_MARKS_PX[i+1] end
  else
    for i=0,steps do marks[i+1] = math.floor(BAR.w*(i/steps)+0.5) end
  end
  marks[1] = 0; marks[steps+1] = BAR.w
  return marks, steps
end

-- rpm → pixels via piecewise-linear interpolation ----------------------------
local function rpmToPixels(rpm, limit, marks, steps)
  rpm = clamp(rpm, 0, limit)
  local fullSpan = steps * RPM_STEP
  if rpm >= fullSpan then
    if fullSpan == limit then return BAR.w end
    local t = (rpm - fullSpan) / (limit - fullSpan)
    return marks[steps+1] + (BAR.w - marks[steps+1]) * t
  else
    local seg = math.floor(rpm / RPM_STEP)
    local t   = (rpm - seg*RPM_STEP) / RPM_STEP
    local x0  = marks[seg+1]
    local x1  = marks[seg+2]
    return x0 + (x1 - x0) * t
  end
end

-- optional ticks at each 1k mark --------------------------------------------
local function drawTicks(marks)
  if not DRAW_MARKS then return end
  for i=1,#marks do rect(BAR.x+marks[i], BAR.y-3, 1, BAR.h+6, TICK) end
end

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

local function getLimiter()
  return safe(car,'limiterRPM')
      or safe(car,'redline')
      or safe(car,'maxRpm')
      or 7000
end

function script.update(dt)
  if not car then return end

  local limit        = getLimiter()
  local marks, steps = makeMarks(limit)

  -- debug is controlled ONLY by DEBUG_MODE/DEBUG_RPM now (no Extra buttons)
  local debugActive  = DEBUG_MODE
  local rpm          = debugActive and DEBUG_RPM or (car.rpm or 0)

  local fillPx = rpmToPixels(rpm, limit, marks, steps)
  drawBarPx(BAR, fillPx)

  drawTicks(marks)
  if debugActive then
    local dbgX = BAR.x + rpmToPixels(DEBUG_RPM, limit, marks, steps)
    rect(math.floor(dbgX+0.5), BAR.y-6, 2, BAR.h+12, DBG)  -- red cursor at DEBUG_RPM
  end
end
