local engds = 0
local oilt = 0
local idlt = 0
local abs=math.abs
local sin=math.sin

local chain=0

local coldlimiterrpm=0
local defidlerpm=0
local lmtr=0
local lastinp=0
local rdmode=0

local turbospin=0
local turboangle=0

local engineruns=0

local choketype=1
local choke=0
local stall=0

	--engine:setTempRevLimiter(100)
	--engine:scaleOutputTorque(0.9999)
	--rpm = engine.outputAV1 * 9.55 --cold overrev damage
	--if rpm > 6000 + ((oilt-10) * 100) then
	--	engine:scaleFriction(1.0001)
	--end

local M = {}

local function update(jbeamData)

	electrics.values['photomodet'] = 0
	coldlimiterrpm = jbeamData.coldRPMlimit or 0	
	defidlerpm = jbeamData.defltidleRPM or 1300
	defidlerpm = defidlerpm/9.55
	engine = powertrain.getDevice("mainEngine") or powertrain.getDevicesByType("combustionEngine")[1]
	electrics.values['oilcold'] = 0
	lmtr=0
	choketype = jbeamData.choketype or 0
	----------------------------------------------------------------------------------manage required components for running engine
	idlt=2
	local harnesspresent = jbeamData.harnesspresent or 0
	local ignitionpresent = jbeamData.ignitionpresent or 0
	local carbspresent = jbeamData.carbspresent or 0
	local batterypresent = jbeamData.batterypresent or 0
	--if ignitionpresent + harnesspresent + carbspresent + batterypresent < 4 then	
	if ignitionpresent == 0 then
		engineruns=0
	else
		engineruns=1
	end

end

local function updateGFX(dt)

	if engineruns == 0 and engine.outputAV1>1 then
		controller.mainController.setEngineIgnition(false)
	end



	oilt = electrics.values['oiltemp']
	--------------------------------------------------------------------manage high idle and choke
	if oilt < 50 then --do for both types
		if electrics.values.ignitionLevel > 0 then 
			electrics.values['oilcold'] = 1
		else
			electrics.values['oilcold'] = 0
		end
		if oilt < 50 and lmtr == 0 then --cold rpm limiter
			lmtr = 1
			if coldlimiterrpm > 0 then
				engine:setTempRevLimiter(coldlimiterrpm/9.55)
			end
		end
	else
		if lmtr == 1 then
			electrics.values['oilcold'] = 0
			engine:resetTempRevLimiter()
		end
	end

	if choketype == 1 then --auto choke mode
		if oilt < 50 then 
			idlt=idlt+dt 
			--engine.idleAV = (defidlerpm + (defidlerpm * 4 * (1-(oilt/50))) + (sin(idlt*30)*(50-oilt)*1) )     --/ 9.55
			if oilt < 35 then
				if idlt < 20 then
					--engine.idleAV = (defidlerpm * idlt * 0.5)
					engine.idleAV = (defidlerpm * (2 + ((20-idlt)/10)) )
				else
					--engine.idleAV = (defidlerpm * 3)
					engine.idleAV = (defidlerpm * 2)
				end
			else
				--engine.idleAV = (defidlerpm * 2) + (sin(idlt*30)*20 )
				engine.idleAV = defidlerpm + (defidlerpm*1*(1-((oilt-35)/15)))
			end
			lmtr = 1
			if engine.outputAV1 < 10 then
				idlt = 2
			end	
		else
			if lmtr == 1 then --set high idle stuff back to default when temp > 50c
				lmtr = 0
				electrics.values['oilcold'] = 0
				engine:resetTempRevLimiter()
				engine.idleAV = defidlerpm
			end
			--idlt=idlt+dt 
			--engine.idleAV = defidlerpm + (sin(idlt*30)*30)
		end
	else --manual choke mode
		if electrics.values['chokev'] == 1 then
			electrics.values['chokev']=0
			if choke == 0 then 
				choke = 1
				guihooks.message("Choke set to full")
			elseif choke == 1 then
				choke = 0.4
				guihooks.message("Choke set to half")
			else
				choke = 0
				guihooks.message("Choke set to off")
				engine.idleAV = defidlerpm
			end
		end
		if oilt < 50 or choke > 0 then
			idlt=idlt+dt
			engine.idleAV = math.max((defidlerpm*(1-((50-oilt)*0.015))) + choke*200 + (sin(idlt*(30))*(30-(choke*20))),50)
			if engine.outputAV1 > 10 and engine.outputAV1 < defidlerpm * (0.9+ ((50-oilt)*0.01)) then
				if stall < 100 then
					stall = stall + 1
				else
					controller.mainController.setEngineIgnition(false)
				end
			else
				stall = 0
			end
		elseif idlt > 0 then
			idlt = 0
			--idlt=idlt+dt 
			engine.idleAV = defidlerpm -- + (sin(idlt*30)*30)
		end
	end

	if electrics.values.ignitionLevel > 0 then -------------------------------------------manage dash cluster lights
		if (engine.outputAV1 < 60 or engine.oilVolume < 2.9) then 
			electrics.values['oillowp'] = 1
		else
			electrics.values['oillowp'] = 0
		end
		if electrics.values.gear == 0 then	
			electrics.values['neutrallight'] = 1
		else
			electrics.values['neutrallight'] = 0
		end 
		if input.brake > 0.01 or input.parkingbrake > 0.01 then
			electrics.values['taillighto'] = 1
		elseif electrics.values.lowhighbeam == 1 then 
			electrics.values['taillighto'] = 0.49
		else
			electrics.values['taillighto'] = 0
		end
	else
		electrics.values['neutrallight'] = 0
		electrics.values['oillowp'] = 0
		electrics.values['taillighto'] = 0
	end
	
	---------------------------------------------------------------------------------------------manage turbo spin
	turbospin = turbospin - ((turbospin-(engine.outputAV1*(input.throttle+0.05)))*0.01)
	turboangle = turboangle + turbospin*100*dt
	if turboangle > 1440 then turboangle = turboangle - 2880 end
	electrics.values['turbospin'] = ((turboangle%360)-180)

	-----------------------------------------------------------------------manage chain texture sliding
	chain = chain + (electrics.values.wheelspeed * dt * -40)
	electrics.values['chaintex'] = ((chain%3)-1) * 0.5
	if chain > 1000 then chain = chain - 1000 elseif chain < -1000 then chain = chain + 1000 end

	--------------------------------------------------------------------------manage rider mount/dismounting, with AI/MP compatibility
	if playerInfo.firstPlayerSeated and electrics.values['photomodet'] == 0 then --we are seated
		electrics.values['rideron'] = 1
		--electrics.values['sidestand'] = 1
		lastinp=electrics.values.wheelspeed
		rdmode=1
	else --not seated
		if rdmode==1 then --set rider active mode to 0
			rdmode = 2
			electrics.values['rideron'] = 0
		elseif electrics.values.wheelspeed > 2 and electrics.values.wheelspeed > lastinp+1 and rdmode==2 then --rider active mode sets back to 1 if controlled by AI/another MP player
			electrics.values['rideron'] = 2
			rdmode = 3
		end
	end

end



-- public interface
M.init = nop
M.initSecondStage = update
M.updateData = update
M.updateGFX = updateGFX
M.reset = update
M.foo = foo
return M