---@diagnostic disable: undefined-field
require "Vehicles/ISUI/ISVehicleDashboard"
require "Vehicles/Vehicles"

NepHB = {}

NepHB.options = {
	activationKey   = nil, -- NepHB.options.activationKey:getValue()
    glowMode = nil,        -- NepHB.options.glowMode:getValue() 1,2,3,4 == matching combo box entry
    fixHeadlights = nil,   -- NepHB.options.fixHeadlights:getValue()
    debugMode = nil,       -- NepHB.options.debugMode:getValue()
    dashboardLightColor = {r=0.2, g=0.3, b=1, a=alpha},
    extraPowerDraw = -0.0001, -- vanilla headlinghts are -0.000025 per minute when the engine is off, this will make the light use 5 * more power.
    --rear > 0 avoids flickering, or <-0.75 if you want the car lit up
    -- dot 0= 180° glow, dot -1=360° glow

    glowPower = { -- {rear, front, rear offset, forwardOffset,}
        [1] = {-1.0, -1.0, 2.0, 9.0},
        --[2] = {-0.75, -1.0, 2.0, 9.0},-- only differnce to max is dark spot behind
        [2] = {0.8, -1.0, 2.0, 8.5},  
        [3] = {0.96, 0.9, 2.0, 6.0},
    },
}


local function debugSay(message) 
    if NepHB.options.debugMode:getValue() then 
        print("NepHB: "..message)
    end
end

NepHB.initOptions = function()
	local options = PZAPI.ModOptions:create("NepHB", "High Beams")
    -- options:addTitle("High Beams")
    -- options:addDescription("Note: game must be restarted for options to take effect")
    NepHB.options.activationKey = options:addKeyBind("activationKey", getText("UI_options_NepHB_activationKey"), Keyboard.KEY_PERIOD, getText("UI_options_NepHB_activationKey_tooltip"))

    NepHB.options.glowMode = options:addComboBox("mode", getText("UI_options_NepHB_glowMode"), getText("UI_options_NepHB_glowMode_tooltip"))
    NepHB.options.glowMode:addItem(getText("UI_options_NepHB_glowMode_1"), false)
    NepHB.options.glowMode:addItem(getText("UI_options_NepHB_glowMode_2"), true)
    NepHB.options.glowMode:addItem(getText("UI_options_NepHB_glowMode_3"), true)
    

    NepHB.options.fixHeadlights = options:addTickBox("1", getText("UI_options_NepHB_fixHeadlights"), false, getText("UI_options_NepHB_fixHeadlights_tooltip"))

	NepHB.options.debugMode = options:addTickBox("1", getText("UI_options_NepHB_DebugMode"), true, getText("UI_options_NepHB_DebugMode_tooltip"))
    debugSay("initOptions: options initilised")
end

NepHB.initOptions()



NepHB.onKeyPress = function (_keyPressed)
    if _keyPressed == NepHB.options.activationKey:getValue() then
        local v=getPlayer():getVehicle()
        if v then 
            NepHB.toggleHighBeam(v)
        end
    end
end

Events.OnKeyPressed.Add(NepHB.onKeyPress)


-- toggles highBeamsOn and calls setHeadlights
NepHB.toggleHighBeam = function(vehicle)
    if vehicle == nil then
        debugSay("toggleHighBeam: Why did you give me a nil vehicle?")
        return
    end
    debugSay("toggleHighBeam: toggling highbeam")
    local vModData = vehicle:getModData()
    if not vModData.NepHB then vModData.NepHB = {} end
    local md=vModData.NepHB
    if md.highBeamsOn == nil then md.highBeamsOn = false end
    md.highBeamsOn = not md.highBeamsOn
    NepHB.setHeadlights(vehicle)
    --debugSay("toggleHighBeam: value:" ..(md.highBeamsOn).toString())
end


-- sets the headlights to normal mode or high beem mode based on vehicle -> ModData -> highBeamsOn
NepHB.setHeadlights = function(vehicle)
    if vehicle == nil then
        debugSay("setHeadlights: Why did you give me a nil vehicle?")
        return
    end
    local vModData = vehicle:getModData()
    if not vModData.NepHB then vModData.NepHB = {} end
    local md=vModData.NepHB
    if md.highBeamsOn == true then
        NepHB.activateHighBeam(vehicle)
    else
        md.highBeamsOn = false -- because might have been nil
        NepHB.deactivateHighBeam(vehicle) 
    end
end

-- update the headlight config in modDate, mainly which headlight should be in front.
NepHB.updateHeadlightCondition = function(vehicle)
    if vehicle == nil then
        debugSay("updateHeadlightCondition: vehicle is nil")
        return
    end
    
    local vModData = vehicle:getModData()
    if not vModData.NepHB then vModData.NepHB = {} end
    local md=vModData.NepHB
    local leftHL  = vehicle:getPartById("HeadlightLeft")
    local rightHL = vehicle:getPartById("HeadlightRight")
    if NepHB.options.fixHeadlights:getValue() then
        if leftHL  then leftHL:setCondition(100) end
        if rightHL then rightHL:setCondition(100) end
    end
    if leftHL  == nil and rightHL == nil then
        debugSay("no headlights found!")
        md.highBeamsOn = false
        md.highBeamsMode = "NONE"
        return
    elseif leftHL  == nil then
        md.leftCond  = nil
        md.rightCond = rightHL:getCondition()
        md.highBeamsMode = "RIGHTONLY"
        md.rearLight="HeadlightRight"
        md.frontLight="HeadlightLeft"
    elseif rightHL == nil then
        md.leftCond  = leftHL:getCondition() 
        md.rightCond = nil
        md.highBeamsMode = "LEFTONLY"
        md.rearLight="HeadlightLeft"
        md.frontLight="HeadlightRight"
    else  -- put the weaker headlight up front
        md.leftCond  = leftHL:getCondition() 
        md.rightCond = rightHL:getCondition()
        if md.leftCond > md.rightCond then
            md.highBeamsMode = "RIGHTFRONT"
            md.rearLight="HeadlightLeft"
            md.frontLight="HeadlightRight"
        else
            md.highBeamsMode = "LEFTFRONT"
            md.rearLight="HeadlightRight"
            md.frontLight="HeadlightLeft"
        end
    end
    debugSay("updateHeadlightCondition: mode: "..md.highBeamsMode)
end


--NepHB.activateHighBeamDEBUG(-0.75, -1.0, 2.0, 10.0)
NepHB.activateHighBeamDEBUG = function(rearDot, frontDot, rearOffset, forwardOffset)
    local vehicle=getPlayer():getVehicle()
    debugSay("activateHighBeam: Start")
    if vehicle == nil then
        debugSay("activateHighBeam: vehicle is nil")
        return
    end
    local vModData = vehicle:getModData()
    if not vModData.NepHB then vModData.NepHB = {} end
    local md=vModData.NepHB
    md.highBeamsOn = true
    NepHB.updateHeadlightCondition(vehicle)
    -- TO DO: dot size to come from NepHB.options.glowSize
    --local rearDot = 0.5
    --local frontDot = -1
    local glowMode="DEBUG"
    debugSay("activateHighBeam: glowMode: "..glowMode.." rearDot: "..rearDot.." frontDot: "..frontDot)
    vehicle:getPartById(md.rearLight):createSpotLight(0.0, rearOffset, 24, 0.75, rearDot, 200)
    vehicle:getPartById(md.frontLight):createSpotLight(0.0, forwardOffset, 24, 0.75, frontDot, 200)    

end



NepHB.activateHighBeam = function(vehicle)
    debugSay("activateHighBeam: Start")
    if vehicle == nil then
        debugSay("activateHighBeam: vehicle is nil")
        return
    end
    local vModData = vehicle:getModData()
    if not vModData.NepHB then vModData.NepHB = {} end
    local md=vModData.NepHB

    NepHB.updateHeadlightCondition(vehicle)
    -- TO DO: dot size to come from NepHB.options.glowSize
    --local rearDot = 0.5
    --local frontDot = -1
    local glowMode=NepHB.options.glowMode:getValue()
    local rearDot=NepHB.options.glowPower[glowMode][1]
    local frontDot=NepHB.options.glowPower[glowMode][2]
    local rearOffset=NepHB.options.glowPower[glowMode][3]
    local forwardOffset=NepHB.options.glowPower[glowMode][4]
    debugSay("activateHighBeam: glowMode: "..glowMode.." rearDot: "..rearDot.." frontDot: "..frontDot)
    vehicle:getPartById(md.rearLight):createSpotLight(0.0, rearOffset, 24, 0.75, rearDot, 200)
    vehicle:getPartById(md.frontLight):createSpotLight(0.0, forwardOffset, 24, 0.75, frontDot, 200)    

end

NepHB.deactivateHighBeam = function(vehicle)
    debugSay("deactivateHighBeam: Start")
    if vehicle == nil then
        debugSay("deactivateHighBeam: vehicle is nil")
        return
    end    
    -- local vModData = vehicle:getModData()
    -- if not vModData.NepHB then vModData.NepHB = {} end
    -- local md=vModData.NepHB
    NepHB.updateHeadlightCondition(vehicle)
    -- default settings
    local hlLeft=vehicle:getPartById("HeadlightLeft")
    local hlRight=vehicle:getPartById("HeadlightRight")
    if hlLeft then hlLeft:createSpotLight(-0.5, 2.0, 8.0+ZombRand(16.0), 0.75, 0.96, ZombRand(200)) end
    if hlRight then hlRight:createSpotLight(-0.5, 2.0, 8.0+ZombRand(16.0), 0.75, 0.96, ZombRand(200)) end
end





NepHB.OnEnterVehicle = function(player) -- did we load a game where player was already in a vehicle?
    local v=player:getVehicle()
    if v then
        NepHB.setHeadlights(v)
    end
end

NepHB.OnCreatePlayer = function(playerNum, player) -- did we load a game where player was already in a vehicle?
    local v=player:getVehicle()
    if v then
        NepHB.setHeadlights(v)
    end
end

NepHB.OnGameBootCheatGlasses = function() -- to allow for 180° vision at night for debugging/screenshot by equiping 3D glasses
    ScriptManager.instance:getItem("Glasses_3dGlasses"):DoParam("VisionModifier = 10")
end


Events.OnEnterVehicle.Add(NepHB.OnEnterVehicle)
Events.OnCreatePlayer.Add(NepHB.OnCreatePlayer)
Events.OnGameBoot.Add(NepHB.OnGameBootCheatGlasses)

NepHB.adjustForDamage = function()
    --check if need to reconfigure based on headlight damage
    -- TO DO:
    -- make a postfix on ISVehicleDashboard.damageFlick(character) that does this
    -- that way we're making use of existing checks to see if the car has been damaged w/ 10 tick timout, 


end



NepHB.setHeadlightsOnSpawn = function(vehicle)
    NepHB.setHeadlights(vehicle)
end

Events.OnSpawnVehicleEnd.Add(NepHB.setHeadlightsOnSpawn)




--  Set headlight icon color on dashboard
local NepHBoriginal_dahboardPrerender = ISVehicleDashboard.prerender
function ISVehicleDashboard:prerender()
	
	NepHBoriginal_dahboardPrerender(self)

	if not self.vehicle or not ISUIHandler.allUIVisible then return end  -- don't run if not in a vehicle or UI is off... otherwise throws an error when getting out of a vehicle when it excutes one final time.
	local alpha = self:getAlphaFlick(0.65); -- flickering from crashes etc
	local hlOn = self.vehicle:getHeadlightsOn()
    local vModData = self.vehicle:getModData()
    if not vModData.NepHB then vModData.NepHB = {} end
    local md=vModData.NepHB

    if hlOn and md.highBeamsOn then
        --self.lightsTex.backgroundColor = NepHB.options.dashboardLightColor 
        self.lightsTex.backgroundColor = {r=0.2, g=.3, b=1, a=alpha}
    end
end


-- recheck headlight status on damage

local NepHBoriginal_ISVehicleDashboarddamageFlick = ISVehicleDashboard.damageFlick
function ISVehicleDashboard.damageFlick(character)
    NepHBoriginal_ISVehicleDashboarddamageFlick(character)
    debugSay("ISVehicleDashboard.damageFlick")
	local v = nil;
    if instanceof(character, 'IsoPlayer') and character:isLocalPlayer() then
		v = character:getVehicle()
	end
    if v == nil then return end
    NepHB.updateHeadlightCondition(v)
end


--[[
function ISVehicleMenu.onToggleHeadlights(playerObj)
	local vehicle = playerObj:getVehicle()
	if not vehicle then return end
	sendClientCommand(playerObj, 'vehicle', 'setHeadlightsOn', { on = not vehicle:getHeadlightsOn() })
end
]]





--[[
--more power draw
--enabling this breaks my ISVehicleDashboard:prerender() code so it's doing something naughty
local NepHBoriginal_Vehicles_Update_Headlight=Vehicles.Update.Headlight
function Vehicles.Update.Headlight(vehicle, part, elapsedMinutes)
    NepHBoriginal_Vehicles_Update_Headlight(vehicle, part, elapsedMinutes)
    local light = part:getLight()
	if not light then return end
	local active = vehicle:getHeadlightsOn()
    if active and not vehicle:isEngineRunning() then
		VehicleUtils.chargeBattery(vehicle, NepHB.options.extraPowerDraw * elapsedMinutes)
	end        
end
]]
