-- One presentation-only AdBlue gauge beside the vanilla energy gauge.
-- Gameplay and fill-level ownership stay in AdblueConsumer/AA Damage.

AAIntegratedAdBlueGauge = AAIntegratedAdBlueGauge or {}

local function clamp(value)
    value=tonumber(value)
    if value==nil then return nil end
    return math.max(0,math.min(1,value))
end

local function scaled(method,object,value)
    if type(method)~="function" then return nil end
    local ok,result=pcall(method,object,value)
    return ok and tonumber(result) or nil
end

function AAIntegratedAdBlueGauge:getLayout(speedMeter)
    if type(speedMeter)~="table" or type(speedMeter.getPosition)~="function" then return nil end
    local ok,posX,posY=pcall(speedMeter.getPosition,speedMeter)
    if not ok or tonumber(posX)==nil or tonumber(posY)==nil then return nil end
    local required={"sectionOffsetX","sectionOffsetY","fuelOffsetX","fuelOffsetY","fuelBarOffsetX","fuelBarOffsetY"}
    for _,name in ipairs(required) do if tonumber(speedMeter[name])==nil then return nil end end
    local columnStep=scaled(speedMeter.scalePixelToScreenWidth,speedMeter,30)
    local iconGap=scaled(speedMeter.scalePixelToScreenHeight,speedMeter,144)
    local percentGap=scaled(speedMeter.scalePixelToScreenHeight,speedMeter,134)
    local textSize=scaled(speedMeter.scalePixelToScreenHeight,speedMeter,9)
    if columnStep==nil or iconGap==nil or percentGap==nil or textSize==nil then return nil end
    local fuelX=posX+speedMeter.sectionOffsetX+speedMeter.fuelOffsetX+speedMeter.fuelBarOffsetX
    local fuelY=posY+speedMeter.sectionOffsetY+speedMeter.fuelOffsetY+speedMeter.fuelBarOffsetY
    return {
        x=fuelX+columnStep,
        y=fuelY,
        iconY=fuelY+iconGap,
        percentY=fuelY+percentGap,
        textSize=textSize,
        columnStep=columnStep
    }
end

local function getVanillaPanelScaleWidth(speedMeter)
    local vehicle=speedMeter.vehicle
    if type(vehicle)~="table" then return nil end
    local fuelWidth=tonumber(speedMeter.fuelBarScaleWidth)
    local repairWidth=tonumber(speedMeter.repairBarScaleWidth)
    local gearWidth=tonumber(speedMeter.gearBarScaleWidth)
    if fuelWidth==nil or repairWidth==nil or gearWidth==nil then return nil end

    local width=gearWidth
    if vehicle.spec_motorized~=nil then width=width+fuelWidth end
    if type(vehicle.getDamageAmount)=="function" and vehicle:getDamageAmount()~=nil then
        width=width+repairWidth
    end
    return width
end

local function setPanelColor(parts,r,g,b,a)
    for _,part in ipairs(parts) do part:setColor(r,g,b,a) end
end

-- Render the existing vanilla three-part speedometer panel one indicator column
-- wider. No overlay is created: speedBgScale supplies the seamless middle and
-- speedBgRight keeps the original rounded edge and green lower separator.
function AAIntegratedAdBlueGauge:drawWithExtendedPanel(speedMeter,originalDraw)
    local layout=self:getLayout(speedMeter)
    local baseWidth=getVanillaPanelScaleWidth(speedMeter)
    local left=type(speedMeter)=="table" and speedMeter.speedBg or nil
    local middle=type(speedMeter)=="table" and speedMeter.speedBgScale or nil
    local right=type(speedMeter)=="table" and speedMeter.speedBgRight or nil
    local parts={left,middle,right}
    if layout==nil or baseWidth==nil or type(originalDraw)~="function" then return false end
    if type(left)~="table" or type(middle)~="table" or type(right)~="table" then return false end
    for _,part in ipairs(parts) do
        if type(part)~="table" or type(part.setPosition)~="function"
            or type(part.setDimension)~="function" or type(part.setColor)~="function"
            or type(part.render)~="function" or tonumber(part.width)==nil then return false end
    end

    local ok,posX,posY=pcall(speedMeter.getPosition,speedMeter)
    if not ok or tonumber(posX)==nil or tonumber(posY)==nil then return false end
    local extendedWidth=baseWidth+layout.columnStep
    local rightX=posX-right.width+layout.columnStep
    middle:setDimension(extendedWidth,nil)
    middle:setPosition(rightX-middle.width,posY)
    right:setPosition(rightX,posY)
    left:setPosition(middle.x-left.width,posY)
    left:render()
    middle:render()
    right:render()

    -- Vanilla must still draw every gauge and text at its unchanged coordinates.
    -- Hide only its second background pass, then restore the overlays even if the
    -- delegated draw reports an error; the error is propagated, never swallowed.
    setPanelColor(parts,1,1,1,0)
    local drawOk,drawError=pcall(originalDraw,speedMeter)
    setPanelColor(parts,1,1,1,1)
    if not drawOk then error(drawError,0) end
    return true
end

local function setRatioColor(ratio)
    if ratio>0.5 then setTextColor(0.458,0.768,0.078,1)
    elseif ratio>0.2 then setTextColor(0.988,0.674,0.015,1)
    else setTextColor(1,0.266,0,1) end
end

function AAIntegratedAdBlueGauge:draw(speedMeter,level,capacity)
    level,capacity=tonumber(level),tonumber(capacity)
    local ratio=capacity~=nil and capacity>0 and level~=nil and clamp(level/capacity) or nil
    local layout=self:getLayout(speedMeter)
    if ratio==nil or layout==nil or type(speedMeter.bar)~="table"
        or tonumber(speedMeter.barMaxScaleWidth)==nil then return false end

    -- Reuse the exact rotated ThreePartOverlay and scale used by vanilla diesel.
    speedMeter.bar:setColor(0,0,0,1)
    speedMeter.bar:setMiddlePart(nil,speedMeter.barMaxScaleWidth,nil)
    speedMeter.bar:setPosition(layout.x,layout.y)
    speedMeter.bar:render()
    if ratio>0 then
        speedMeter.bar:setColor(0.12,0.72,0.86,1)
        speedMeter.bar:setMiddlePart(nil,speedMeter.barMaxScaleWidth*ratio,nil)
        speedMeter.bar:setPosition(layout.x,layout.y)
        speedMeter.bar:render()
    end

    local icon=speedMeter.fuelIconExtraImage
    if type(icon)=="table" and type(icon.setPosition)=="function" and type(icon.render)=="function" then
        icon:setPosition(layout.x-(tonumber(icon.width) or 0)*0.5,layout.iconY)
        icon:render()
    end
    if renderText~=nil and setTextAlignment~=nil and RenderText~=nil then
        setTextAlignment(RenderText.ALIGN_CENTER)
        if setTextBold~=nil then setTextBold(true) end
        setRatioColor(ratio)
        renderText(layout.x,layout.percentY,layout.textSize,string.format("%d%%",math.floor(ratio*100+0.5)))
        if setTextBold~=nil then setTextBold(false) end
        setTextAlignment(RenderText.ALIGN_LEFT)
        if setTextColor~=nil then setTextColor(1,1,1,1) end
    end
    return true
end
