local M = {}
local device = nil
local timer = 0
local timer2 = 0
local timer3 = 0
local hasBeenActive = 0
local hasBeenActive2 = 0
local hasBeenActive3 = 0
local keySaveValue = 0
local indicatorActive = false
local timer_ind = 0
local indicator_l = false
local indicator_r = false
local indicator_lr = false
local shifterSmoother = newExponentialSmoothing(10)
local cabinFilterCoef = 1
local cabinFilterChanged = false
local keySmoother = newExponentialSmoothing(10)
local keyPos = 0
local automaticShifterPos = 0
local doorFL = nil
local doorFR = nil
local doorRL = nil
local doorRR = nil
local hood = nil
local trunk = nil
local doorsOpen = 0
local doorStateChanged = 0
local doorMissing = false
local buttonPress
local keyPosCache = 1

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

function round(num, numDecimalPlaces)
  local mult = 10^(numDecimalPlaces or 0)
  return math.floor(num * mult + 0.5) / mult
end

--This File contains the Vertex's gauge cluster starting sequence, the key twisting logic and the DRL logic, logic for moving the automatic shifter as well as a bit of stuff for the "door open" gauge light
local function onInit()

	indicatorActive = false
	timer_ind = 0
	indicator_l = false
	indicator_r = false
	indicator_lr = false

	if not electrics.values["isSimpleTrafficCar"] then
		device = powertrain.getDevice("mainEngine") or powertrain.getDevice("frontMotor")
		electrics.values["startermotor"] = 0
		electrics.values["startermotor2"] = 0
		electrics.values["startermotor3"] = 0
		electrics.values["doorsOpen"] = 0
		hasBeenActive = 0
		hasBeenActive2 = 0
		hasBeenActive3 = 0
		electrics.values["key"] = 0
		keyPos = 0
		automaticShifterPos = 0
		keySaveValue = 0
		keyPosCache = 0
		
		doorFL = nil
		doorFR = nil
		doorRL = nil
		doorRR = nil
		hood = nil
		trunk = nil
		
		if v.data.sounds then
			cabinFilterCoef = v.data.sounds.cabinFilterCoef == nil and 1 or v.data.sounds.cabinFilterCoef
			--print(cabinFilterCoef)
		end
	end
end

local function onReset()

	indicatorActive = false
	timer_ind = 0
	indicator_l = false
	indicator_r = false
	indicator_lr = false

	if not electrics.values["isSimpleTrafficCar"] then
		electrics.values["startermotor"] = 0
		electrics.values["startermotor2"] = 0
		electrics.values["startermotor3"] = 0
		electrics.values["doorsOpen"] = 0
		electrics.values["domelight"] = 0
		hasBeenActive = 0
		hasBeenActive2 = 0
		hasBeenActive3 = 0
		electrics.values["key"] = 0
		doorsOpen = 0
		keyPos = 0
		keyPosCache = 1
		automaticShifterPos = 0
		keySaveValue = 0

		doorStateChanged = 0
		if cabinFilterChanged then
			obj:queueGameEngineLua(string.format("core_sounds.cabinFilterStrength = %f", cabinFilterCoef))
			cabinFilterChanged = false
		end
	end
end

local function updateGFX(dt) 
	if electrics.values["engineRunning"] == 0 then
		indicatorActive = false
		if electrics.values["signal_L"] == 1 and electrics.values["signal_R"] == 1 then
			electrics.values["drl_L"] = 1
			electrics.values["drl_R"] = 1
		elseif electrics.values["signal_L"] == 1 then
			electrics.values["drl_L"] = 1
			electrics.values["drl_R"] = 0
		elseif electrics.values["signal_R"] == 1 then
			electrics.values["drl_L"] = 0
			electrics.values["drl_R"] = 1
		else
			electrics.values["drl_L"] = 0
			electrics.values["drl_R"] = 0
		end
	elseif electrics.values["engineRunning"] == 1 and electrics.values["signal_R"] ~= 0 or electrics.values["signal_L"] ~= 0 then
		indicatorActive = true
		timer_ind = 0
		if electrics.values["signal_L"] == 1 and electrics.values["signal_R"] == 1 then
			indicator_lr = true
			indicator_r = false
			indicator_l = false
			electrics.values["drl_L"] = 1
			electrics.values["drl_R"] = 1
		elseif electrics.values["signal_L"] == 1 then
			indicator_l = true
			indicator_r = false
			indicator_lr = false
			electrics.values["drl_L"] = 1
			electrics.values["drl_R"] = 1
		elseif electrics.values["signal_R"] == 1 then
			indicator_r = true
			indicator_l = false
			indicator_lr = false
			electrics.values["drl_L"] = 1
			electrics.values["drl_R"] = 1
		end
	elseif electrics.values["engineRunning"] == 1 and electrics.values["signal_R"] == 0 and electrics.values["signal_L"] == 0 and indicatorActive == true then
		timer_ind = timer_ind + dt
		if indicator_lr == true then
			electrics.values["drl_L"] = 0
			electrics.values["drl_R"] = 0
		elseif indicator_l == true then
			electrics.values["drl_L"] = 0
			electrics.values["drl_R"] = 1
		elseif indicator_r == true then
			electrics.values["drl_L"] = 1
			electrics.values["drl_R"] = 0
		end
		if timer_ind >= 0.7 then
			indicatorActive = false
		end
	else
		electrics.values["drl_L"] = 1
		electrics.values["drl_R"] = 1
		indicator_r = false
		indicator_l = false
		indicator_lr = false
		indicatorActive = false
	end

	if not electrics.values["isSimpleTrafficCar"] then
		--Make sure this code is only excecuted when the car is not a simple traffic car to save on resources

		--Door open detection logic as well as domelight and cabin filter logic
		--set to 1 when doesnt exist

		if electrics.values["doorFLCoupler_notAttached"] then
			doorFL = electrics.values["doorFLCoupler_notAttached"]
		else
			doorMissing = true
		end
		if electrics.values["doorFRCoupler_notAttached"] then
			doorFR = electrics.values["doorFRCoupler_notAttached"]
		else
			doorMissing = true
		end
		if electrics.values["doorRLCoupler_notAttached"] then
			doorRL = electrics.values["doorRLCoupler_notAttached"]
		else
			doorMissing = true
		end
		if electrics.values["doorRRCoupler_notAttached"] then
			doorRR = electrics.values["doorRRCoupler_notAttached"]
		else
			doorMissing = true
		end
		if electrics.values["trunkCoupler_notAttached"] then
			trunk = electrics.values["trunkCoupler_notAttached"]
		else
			trunk = 1
		end
		if electrics.values["hoodLatchCoupler_notAttached"] then
			hood = electrics.values["hoodLatchCoupler_notAttached"]
		else
			hood = 1
		end

		if doorFR == 1 or doorFL == 1 or doorRR == 1 or doorRL == 1 then
			doorsOpen = 1
			if doorStateChanged ~= doorsOpen then
				doorStateChanged = doorsOpen
				if electrics.values["ignitionLevel"] > 0 and not doorMissing then electrics.values["domelight"] = 1 end --only change it when ignition is on and no door is missing (otherwise kinda annoying)
				
				if playerInfo.anyPlayerSeated then
					cabinFilterChanged = true
					obj:queueGameEngineLua(string.format("core_sounds.cabinFilterStrength = %f", 0))
				end
			end
		else
			doorsOpen = 0
			if doorStateChanged ~= doorsOpen then
				doorStateChanged = doorsOpen
				electrics.values["domelight"] = 0
				if playerInfo.anyPlayerSeated then
					cabinFilterChanged = false
					obj:queueGameEngineLua(string.format("core_sounds.cabinFilterStrength = %f", cabinFilterCoef))
				end
			end
		end
	  
		if doorsOpen == 1 or trunk == 1 or hood == 1 then
			if electrics.values["ignitionLevel"] > 0 then electrics.values["doorsOpen"] = 1 end 
		else
			electrics.values["doorsOpen"] = 0

		end

	  --Automatic shifter
		if electrics.values['gear'] == "P" then
			automaticShifterPos = 0
			electrics.values["automaticShifterPos"] = shifterSmoother:get(automaticShifterPos)
		elseif electrics.values['gear'] == "R" then
			automaticShifterPos = 0.25
			electrics.values["automaticShifterPos"] = shifterSmoother:get(automaticShifterPos)

		elseif electrics.values['gear'] == "N" then
			automaticShifterPos = 0.45
			electrics.values["automaticShifterPos"] = shifterSmoother:get(automaticShifterPos)

		else
			automaticShifterPos = 0.65
			electrics.values["automaticShifterPos"] = shifterSmoother:get(automaticShifterPos)

		end

	  if device == nil then return end -- prevent lua error when engine removed
	  --if device.starterEngagedCoef == nil then return end
	  if device.starterEngagedCoef ~= nil and device.starterEngagedCoef ~= 0 and not device.isDisabled then 
		hasBeenActive = 1
		hasBeenActive2 = 1
		hasBeenActive3 = 1

		electrics.values["startermotor"] = 1
		electrics.values["startermotor2"] = 1
		electrics.values["startermotor3"] = 1

		--else
		--electrics.values["startermotor"] = 0
	  end
	  if hasBeenActive == 1 then
		timer = timer + dt		
		if timer >= 1.5 then
			electrics.values["startermotor"] = 0
			hasBeenActive = 0
			timer = 0
		end
	  end
	  if hasBeenActive2 == 1 then
		timer2 = timer2 + dt	
		if timer2 >= 2.5 then
			electrics.values["startermotor2"] = 0
			hasBeenActive2 = 0
			timer2 = 0
		end
	  end
	  if hasBeenActive3 == 1 then	
		timer3 = timer3 + dt	
		if timer3 >= 4.5 then
			electrics.values["startermotor3"] = 0
			hasBeenActive3 = 0
			timer3 = 0
		end
	  end
	  
	 --car key twisting function 

		if device.starterEngagedCoef ~= 0 and not device.isDisabled then
			keyPos = 1
			electrics.values["key"] = keySmoother:get(keyPos)
		elseif electrics.values["engineRunning"] == 1 or electrics.values["ignitionLevel"] >= 1 then
			keyPos = 0.7
			electrics.values["key"] = keySmoother:get(keyPos)
		else
			keyPos = 0
			electrics.values["key"] = keySmoother:get(keyPos)
		end

		if round(electrics.values["key"], 2) == keyPos and keyPos ~= keyPosCache then
			buttonPress = buttonPress or sounds.createSoundscapeSound("ButtonPress")
			sounds.playSoundSkipAI(buttonPress)
			keyPosCache = keyPos
		end
	
	end
end

-- public interface
M.onInit = onInit
M.onReset = onReset
M.updateGFX = updateGFX

return M