--══════════════════════════════════════════════════════════════════════════════
--  hybrid_flow_strip.lua   (Power + Torque) – using simulated curve (FIXED)
--══════════════════════════════════════════════════════════════════════════════

------------------------------------- USER-CONFIG -----------------------------
local TIP_STYLE   = "SOLID"   -- "SOLID" or "FADE"
local TIP_W       = 501
local DEBUG       = false

-- BAR POSITIONS
local POWER = { x = 3,  y =  42,   w = 501, h = 20 }
local TORQUE= { x = 3,  y = 104.5, w = 501, h = 21 }

-- COLORS
local POWER_BODY = rgbm(1,0,0.15,1)
local POWER_TIP  = rgbm(1,0,0.15,1)
local TORQUE_BODY= rgbm(1,0,0.15,1)
local TORQUE_TIP = rgbm(1,0,0.15,1)

-------------------------------------------------------------------------------
local BG  = rgbm(0,0,0,0)
local OUT = rgbm(0,0,0,0)

local function clamp(v,a,b)
  if v < a then return a end
  if v > b then return b end
  return 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 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 drawTwoColorBar(b, frac, bodyCol, tipCol)
  rect(b.x,b.y,b.w,b.h,BG)
  if frac>0 then
    local fillW = math.min(b.w, math.floor(b.w*frac+0.5))
    local bodyW = math.max(fillW - TIP_W, 0)
    if bodyW>0 then rect(b.x,b.y,bodyW,b.h,bodyCol) end

    if TIP_STYLE == "SOLID" then
      rect(b.x+bodyW,b.y,fillW-bodyW,b.h,tipCol)
    else
      local fadeW = math.min(fillW, TIP_W)
      local slices = 30
      local segW = fadeW / slices
      local startX = b.x + bodyW
      for i=0,slices-1 do
        local x = startX + math.floor(i*segW+0.5)
        local w = math.ceil(segW)
        if x + w > b.x + fillW then w = b.x + fillW - x end
        if w<=0 then break end
        rect(x,b.y,w,b.h,mix(bodyCol,tipCol,(i+0.5)/slices))
      end
    end
  end
  outline(b)
end

-------------------------------------------------------------------------------
-- SIM CURVE
-------------------------------------------------------------------------------

local IDLE_RPM        = 1000
local PEAK_TORQUE_NM  = 4200
local PEAK_TORQUE_RPM = 4250
local PLATEAU_END_RPM = 4500
local REDLINE_RPM     = 7000
local TORQUE_AT_REDLINE_FRACTION = 0.85
local THROTTLE_EFFECT = 1

local SMOOTH_HZ = 12

local function lerp(a,b,t) return a + (b - a) * t end

-- FIX: remove minimum torque → allow zero on lift-off
local function simulatedTorqueNm(rpm, throttle)
  rpm = clamp(rpm or 0, IDLE_RPM, REDLINE_RPM)

  local tIdle    = PEAK_TORQUE_NM * 0.35
  local tPeak    = PEAK_TORQUE_NM
  local tRedline = PEAK_TORQUE_NM * TORQUE_AT_REDLINE_FRACTION

  local base
  if rpm <= PEAK_TORQUE_RPM then
    local t = (rpm - IDLE_RPM) / math.max(1,(PEAK_TORQUE_RPM - IDLE_RPM))
    base = lerp(tIdle, tPeak, clamp(t,0,1))
  elseif rpm <= PLATEAU_END_RPM then
    base = tPeak
  else
    local t = (rpm - PLATEAU_END_RPM) / math.max(1,(REDLINE_RPM - PLATEAU_END_RPM))
    base = lerp(tPeak, tRedline, clamp(t,0,1))
  end

  local gas = clamp(throttle or 0, 0, 1)

  -- FIX: REMOVE minimum torque floor (0.15)
  -- old: base = base * lerp(0.15, 1.0, gas)
  -- new: torque becomes EXACTLY 0 when gas=0
  base = base * (gas ^ THROTTLE_EFFECT)

  return math.max(0, base)
end

local function powerKWfromNm(torqueNm, rpm)
  return (torqueNm or 0) * (rpm or 0) / 9549.0
end

local function ema(prev, target, hz, dt)
  dt = dt or 0.016
  local k = math.exp(-(hz or 8) * dt)
  return target + (prev - target) * k
end

local PRECOMP_MAX_TORQUE = PEAK_TORQUE_NM
local PRECOMP_MAX_POWER_KW = (function()
  local best = 0
  for r = IDLE_RPM, REDLINE_RPM, 50 do
    local tNm = simulatedTorqueNm(r, 1.0)
    local pKW = powerKWfromNm(tNm, r)
    if pKW > best then best = pKW end
  end
  return math.max(1, best)
end)()

local smoothTorqueNm, smoothPowerKW = 0, 0

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

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

  if DEBUG then
    drawTwoColorBar(TORQUE, 1, TORQUE_BODY, TORQUE_TIP)
    drawTwoColorBar(POWER,  1, POWER_BODY,  POWER_TIP)
    return
  end

  local rpm = car.rpm or 0
  local gas = car.gas or car.throttle or 0

  local tNm = 0
  local pKW = 0

  if rpm > (IDLE_RPM + 50) then
    tNm = simulatedTorqueNm(rpm, gas)
    pKW = powerKWfromNm(tNm, rpm)
  end

  -- FIX: smoothing still allows return to zero instantly when target=0
  smoothTorqueNm = ema(smoothTorqueNm, tNm, SMOOTH_HZ, dt)
  smoothPowerKW  = ema(smoothPowerKW,  pKW, SMOOTH_HZ, dt)

  local tqFrac = clamp(smoothTorqueNm / PRECOMP_MAX_TORQUE, 0, 1)
  local pwFrac = clamp(smoothPowerKW  / PRECOMP_MAX_POWER_KW, 0, 1)

  drawTwoColorBar(TORQUE, tqFrac, TORQUE_BODY, TORQUE_TIP)
  drawTwoColorBar(POWER,  pwFrac,  POWER_BODY,  POWER_TIP)
end
