-- ============================================================================
--  AUDI RS cluster — Layered Rendering (Background -> All Bars -> Overlay Mask)
--  **COORDINATES ADJUSTED TO PREVENT BLEEDING**
-- ============================================================================

local car = ac.getCar(0)

-- 🟢 CONFIGURATION: IMAGES (Paths confirmed from previous step)
-- 1. The bottom layer (Solid dark base).
local CLUSTER_BACKGROUND_IMAGE = "cluster/CLUSTER_ALPHA.png" 

-- 2. The top layer (The cluster face with TRANSPARENT holes for bars).
local CLUSTER_OVERLAY_IMAGE    = "cluster/CLUSTER_ALPHA_42.png"        

-- 3. Size of your images
local CLUSTER_SIZE = vec2(2048, 2048) 

-- 🟢 CONFIGURATION: RPM BARS (Underlay Rectangles)
-- **ADJUSTED:** Reduced width and narrowed vertical range.
local RPM_BAR_LEFT = {
  x = 550,          -- Center X position (Fine-tune this)
  topY = 790,       -- START Y (Increased by 10)
  bottomY = 1184,   -- END Y (Decreased by 10)
  width = 350       -- Reduced width (from 180)
}

local RPM_BAR_RIGHT = {
  x = 1700,
  topY = 790,
  bottomY = 1184,
  width = 350
}

-- CONFIGURATION: OIL & BOOST BARS
-- **ADJUSTED:** Reduced size for both bars.
local BAR_OIL   = { pos = vec2(91.4, 1261),   size = vec2(650, 9),  bg = rgbm(0,0,0,0), fill = rgb(1,1,1) }
local BAR_BOOST = { pos = vec2(1531, 1260.7), size = vec2(320, 7),   bg = rgbm(0,0,0,0), fill = rgb(1,1,1) }
local OIL_EDGE   = { width = 6, color = rgbm(1, 0, 0, 0.95) }
local BOOST_EDGE = { width = 4, color = rgbm(1.0, 0., 0, 0.95) }
local OIL_MIN_C, OIL_MAX_C = 50, 130

-- Rest of the code remains the same, focused on logic and text placement.
local white = rgb(1, 1, 1)
local gearT = { [-1]="R",[0]="N",[1]="1",[2]="2",[3]="3",[4]="4",[5]="5",[6]="6",[7]="7",[8]="8",[9]="9"  }
local fuelKmsPerLitre = 9 
local SMOOTH_HZ = 10
local smoothRPMFrac, smoothOil, smoothBoost = 0, 0, 0
local movingTimeSec = 0.0

local function v(str) local x,y=str:match("([^,]+),%s*([^,]+)"); return vec2(tonumber(x), tonumber(y)) end
local function clamp(x,a,b) return (x<a) and a or (x>b) and b or x end
local function lerp(a,b,t) return a + (b - a) * t end
local function ema(prev, target, hz, dt) dt = dt or 0.016; local k = math.exp(-hz * dt); return target + (prev - target) * k end
local function rect(x,y,w,h,c,o) display.rect{ pos=vec2(x,y), size=vec2(w,h), color=c, opacity=o or 1 } end

local function getMaxRPM()
  local v =  car.rpmLimiter or car.rpmLimit or car.limiter or car.redlineRPM or car.maxRPM or car.engineMaxRPM or 8000
  if v and v < 1000 then v = 8000 end
  return v
end

local RPM_GREEN_END, RPM_YELLOW_END = 4500, 6000
local RPM_COL_GREEN   = rgbm(0.33, 1.00, 0.00, 1.0)
local RPM_COL_YELLOW  = rgbm(1.00, 0.85, 0.00, 1.0)
local RPM_COL_RED     = rgbm(1.00, 0.15, 0.10, 1.0)

local function rpmStageColor(rpm)
  if rpm <= RPM_GREEN_END  then return RPM_COL_GREEN end
  if rpm <= RPM_YELLOW_END then return RPM_COL_YELLOW end
  return RPM_COL_RED
end

local function drawRpmUnderlay(bar, fraction, color)
  fraction = clamp(fraction or 0, 0, 1)
  local fullHeight = bar.bottomY - bar.topY
  local currentHeight = fullHeight * fraction
  local centerY = bar.topY + (currentHeight * 0.5)
  
  if currentHeight > 0.5 then
    display.rect{ 
      pos = vec2(bar.x, centerY), 
      size = vec2(bar.width, currentHeight), 
      color = color 
    }
  end
end

local function drawBar(bar, fraction, edge)
  local f = clamp(fraction or 0, 0, 1)
  display.rect{ pos = bar.pos, size = bar.size, color = bar.bg, opacity=1, corner=3 }
  if f > 0 then
    display.rect{ pos = bar.pos, size = vec2(math.floor(bar.size.x * f + 0.5), bar.size.y),
                  color = bar.fill, opacity=1, corner=3 }
  end
  if edge and edge.width and edge.width>0 then
    local x = bar.pos.x + bar.size.x * f - (edge.width * 0.5)
    display.rect{ pos=vec2(math.floor(x + 0.5), bar.pos.y), size=vec2(edge.width, bar.size.y), color=edge.color }
  end
end

local DOT_TEXTURE = "cluster/g_force_dot_red.png"
local DOT_SIZE    = vec2(65.5, 65.5)
local GF_CENTER   = vec2(278, 1032)
local G_RADIUS, MAX_G, EMA_HZ_G = 73, 2.0, 7.5
local GF_SmoothedAccel = { x = 0, z = 0 }

local function gforce_update(dt)
  local gx, gz = ema(GF_SmoothedAccel.x, car.acceleration.x or 0, EMA_HZ_G, dt), ema(GF_SmoothedAccel.z, car.acceleration.z or 0, EMA_HZ_G, dt)
  GF_SmoothedAccel.x, GF_SmoothedAccel.z = gx, gz
  local ang = math.atan2(gz, gx)
  local mag = clamp(math.sqrt(gx*gx + gz*gz) / math.max(0.001, MAX_G), 0, 1)
  local pos = GF_CENTER + vec2(math.cos(ang), math.sin(ang)) * (G_RADIUS * mag)

  display.image({ image = DOT_TEXTURE, pos = vec2(pos.x - DOT_SIZE.x * 0.5, pos.y - DOT_SIZE.y * 0.5), size = DOT_SIZE })
  local col = rgbm(1, 0.2, 0.25, 1)
  display.text({ text = string.format("%.1f", math.max(gx, 0)),  pos = vec2(380, 1012), letter = vec2(30, 60), font="audi_vln_hd", width=46, alignment=1, spacing=-10, color=col })
  display.text({ text = string.format("%.1f", math.max(-gx, 0)), pos = vec2(100, 1012), letter = vec2(30, 60), font="audi_vln_hd", width=46, alignment=1, spacing=-10, color=col })
  display.text({ text = string.format("%.1f", math.max(-gz, 0)), pos = vec2(240,  895), letter = vec2(30, 60), font="audi_vln_hd", width=46, alignment=1, spacing=-10, color=col })
  display.text({ text = string.format("%.1f", math.max(gz, 0)),  pos = vec2(240, 1130), letter = vec2(30, 60), font="audi_vln_hd", width=46, alignment=1, spacing=-10, color=col })
end

local IDLE_RPM, PEAK_TORQUE_NM = 1000, 4200
local PEAK_TORQUE_RPM, PLATEAU_END_RPM, REDLINE_RPM = 4250, 4500, 7000
local SMOOTH_HZ_POWER, smoothTorqueNm, smoothPowerKW = 10, 0, 0
local PRECOMP_MAX_POWER_KW = 300

local function simulatedTorqueNm(rpm, throttle)
  rpm = clamp(rpm or 0, IDLE_RPM, REDLINE_RPM)
  local base = (rpm <= PEAK_TORQUE_RPM) and lerp(PEAK_TORQUE_NM*0.35, PEAK_TORQUE_NM, clamp((rpm-IDLE_RPM)/(PEAK_TORQUE_RPM-IDLE_RPM),0,1))
            or (rpm <= PLATEAU_END_RPM) and PEAK_TORQUE_NM
            or lerp(PEAK_TORQUE_NM, PEAK_TORQUE_NM*0.85, clamp((rpm-PLATEAU_END_RPM)/(REDLINE_RPM-PLATEAU_END_RPM),0,1))
  return math.max(0, base * (clamp(throttle or 0,0,1) ^ 1))
end

local function cluster_update(dt)
  local rpm      = car.rpm or 0
  local speedKmh = car.speedKmh
  local speed    = (speedKmh / 1.609344)
  if speedKmh > 0.5 then movingTimeSec = movingTimeSec + dt end

  -- 🟢 LAYER 1: BACKGROUND (The solid base)
  display.image{ image = CLUSTER_BACKGROUND_IMAGE, pos = vec2(0,0), size = CLUSTER_SIZE }

  -- 🟢 LAYER 2: ALL BARS (Drawn on top of background, BEFORE the mask)
  local rpmMax = getMaxRPM()
  local rpmFrac = clamp(rpm / math.max(1, rpmMax), 0, 1)
  smoothRPMFrac = ema(smoothRPMFrac, rpmFrac, 10, dt)
  local rpmColor = rpmStageColor(rpm)

  -- 2a. RPM Underlays
  drawRpmUnderlay(RPM_BAR_LEFT,  smoothRPMFrac, rpmColor)
  drawRpmUnderlay(RPM_BAR_RIGHT, smoothRPMFrac, rpmColor)

  -- 2b. Oil & Boost Bars
  local oilC     = car.oilTemperature or 0
  local oilFrac  = clamp((oilC - OIL_MIN_C) / math.max(1, (OIL_MAX_C - OIL_MIN_C)), 0, 1)
  local boostFrac= (car.turboBoost or car.boostRatio or 0)
  smoothOil      = ema(smoothOil,   oilFrac,   10, dt)
  smoothBoost    = ema(smoothBoost, boostFrac, 10, dt)

  drawBar(BAR_OIL,   smoothOil,   OIL_EDGE)
  drawBar(BAR_BOOST, smoothBoost, BOOST_EDGE)

  -- 🟢 LAYER 3: OVERLAY (The Mask)
  display.image{ image = CLUSTER_OVERLAY_IMAGE, pos = vec2(0,0), size = CLUSTER_SIZE }

  -- 🟢 LAYER 4: TEXT & UI (Always on top)
  local TIME_POS, TIME_LETTER, TIME_FONT = v("606.3, 1322"), v("40, 50"), 'b'
  display.text({ text=string.format("%02d", sim.timeHours),   pos=TIME_POS, letter=TIME_LETTER, font=TIME_FONT, color=white, alignment=1, spacing=-15 })
  display.text({ text=":",                                    pos=TIME_POS + vec2(28, -4), letter=TIME_LETTER, font=TIME_FONT, color=white, alignment=1, spacing=-10 })
  display.text({ text=string.format("%02d", sim.timeMinutes), pos=TIME_POS + vec2(46, 0), letter=TIME_LETTER, font=TIME_FONT, color=white, alignment=1, spacing=-15 })

  display.text({ text=math.floor(speed),                 pos=v("835, 1124"),     letter=v("80, 120"),font='Seat_Leon_CUP_big', color=white, alignment=0.5, width=285 })
  display.text({ text=math.floor((car.distanceDrivenTotalKm or 0)/1.6), pos=v("957, 1269"), letter=v("30, 100"), font='rs62', color=white, alignment=1, width=250 })
  display.text({ text=math.floor((car.distanceDrivenSessionKm or 0)/1.6), pos=v("595, 1269"), letter=v("30, 100"), font='rs62', color=white, alignment=1, width=250 })
  display.text({ text=math.floor(car.waterTemperature),  pos=v("40, 1277"),      letter=v("20, 35"),   font='Seat_Leon_CUP_big', color=white, alignment=1, width=250 })
  display.text({ text=gearT[car.gear],                   pos=v("940, 976"),      letter=v("70, 110"),  font='Seat_Leon_CUP_big', color=white, alignment=0.5 })
  display.text({ text=math.floor(car.fuel * fuelKmsPerLitre / 1.6), pos=v("495, 694.7"), letter=v("32, 40"), font='b', color=white, alignment=0.75, width=255, spacing=-15 })

  local gas = car.gas or 0
  local tNm = (rpm > 1050 and gas > 0.001) and simulatedTorqueNm(rpm, gas) or 0
  local pKW = tNm * rpm / 9549.0
  smoothTorqueNm = ema(smoothTorqueNm, tNm, 10, dt)
  smoothPowerKW  = ema(smoothPowerKW,  pKW, 10, dt)
  local tPct = math.floor(clamp(smoothTorqueNm / PEAK_TORQUE_NM, 0, 1) * 100 + 0.5)
  local pPct = math.floor(clamp(smoothPowerKW / PRECOMP_MAX_POWER_KW, 0, 1) * 100 + 0.5)

  display.text({ text=tostring(tPct), pos=v("1758, 1044"), letter=v("60, 160"), font='rs62', color=white, alignment=.5, width=200, spacing=-5 })
  display.text({ text=tostring(pPct), pos=v("1471, 1044"), letter=v("60, 160"), font='rs62', color=white, alignment=.5, width=200, spacing=-5 })

  if car.handbrake < 0.1 then rect(12894.2, 1306.6, 85, 85, rgb(0,0,0), 1) end 
end

function update(dt)
  cluster_update(dt)
  gforce_update(dt)
end