RPMmsgIdent = 808

function Initialise ()

	Call( "LightHaloHead:ActivateNode", "lighthalohead_night", 0);
	Call( "LightHaloHead:ActivateNode", "lighthalotail_night", 0);
	Call( "LightHaloTail:ActivateNode", "lighthalohead_night", 0);
	Call( "LightHaloTail:ActivateNode", "lighthalotail_night", 0);
	Call( "CablightFL:Activate", 0)
	Call( "CablightFR:Activate", 0)
	Call( "CablightRL:Activate", 0)
	Call( "CablightRR:Activate", 0)
	gReverserLock = 0
	gReverserPwrLock = 0
	gPrevRPM = 0
	gPrevRPMDelta = 0
	gTimer = 0
	gNewTimer = 0
	gFirstCheck = 1
	gTimeCheck = 0.1
	gTimerS = 0
	gNewTimerS = 0
	gFirstCheckS = 1
	gTimeCheckS = 0.1
	gTimerP = 0
	gNewTimerP = 0
	gPwrHandleLock = 0
	gTBrkLock = 0
	gPwrHandleSpring = 0
	gBrakeValue = 0.20
	gPwrHandleStg = 0.16
	gPwrHandlePrevStg = 0.16
	gPwrHandleDir = 0
	gTBStg = 0.9
	gTBPrevStg = 0.9
	gTBDir = 0
	gTBrkStepLock = 0
	Call( "*:SetControlValue", "cabsignal", 0, 1 )
	Call( "*:SetControlValue", "cabsignalsound", 0, 1 )
	Call( "*:SetControlValue", "PowerHandleAnim", 0, 0.16 )
	Call( "*:SetControlValue", "TrainBrakeHandleAnim", 0, 0.9 )
	Call( "BeginUpdate" )

end

function OnControlValueChange ( name, index, value )

	if Call( "*:ControlExists", name, index ) then
		Call( "*:SetControlValue", name, index, value );
	end

	if name == "Headlights" then
		if value == 0 then
			Call( "LightHaloHead:ActivateNode", "lighthalohead_night", 0);
			Call( "LightHaloHead:ActivateNode", "lighthalotail_night", 0);
			Call( "LightHaloTail:ActivateNode", "lighthalohead_night", 0);
			Call( "LightHaloTail:ActivateNode", "lighthalotail_night", 0);
		elseif value == 1 then
			Call( "LightHaloHead:ActivateNode", "lighthalohead_night", 1);
			Call( "LightHaloHead:ActivateNode", "lighthalotail_night", 1);
			Call( "LightHaloTail:ActivateNode", "lighthalohead_night", 0);
			Call( "LightHaloTail:ActivateNode", "lighthalotail_night", 0);
		elseif value == 2 then
			Call( "LightHaloHead:ActivateNode", "lighthalohead_night", 0);
			Call( "LightHaloHead:ActivateNode", "lighthalotail_night", 0);
			Call( "LightHaloTail:ActivateNode", "lighthalohead_night", 1);
			Call( "LightHaloTail:ActivateNode", "lighthalotail_night", 1);
		end
	end

	if name == "Cablight" then
		if value == 1 then
			Call( "CablightFL:Activate", 1)
			Call( "CablightFR:Activate", 1)
			Call( "CablightRL:Activate", 1)
			Call( "CablightRR:Activate", 1)
		else
			Call( "CablightFL:Activate", 0)
			Call( "CablightFR:Activate", 0)
			Call( "CablightRL:Activate", 0)
			Call( "CablightRR:Activate", 0)
		end
	end

	if name == "ReverserIncreaser" then
		if value > 0 then
			reverser = Call( "*:GetControlValue", "Reverser", 0 )
			if reverser == 0 and gReverserLock == 0 and gReverserPwrLock == 0 then
				Call( "*:SetControlValue", "Reverser", 0, 1 )
				gReverserLock = 1
			elseif reverser == -1 and gReverserPwrLock == 0 and gReverserLock == 0 then
				Call( "*:SetControlValue", "Reverser", 0, 0 )
				gReverserLock = 1
			end
		elseif value == 0 and gReverserLock == 1  then
			gReverserLock = 0
		end
	end
	if name == "ReverserDecreaser" then
		if value > 0 then
			reverser = Call( "*:GetControlValue", "Reverser", 0 )
			if reverser == 1 and gReverserLock == 0 and gReverserPwrLock == 0 then
				Call( "*:SetControlValue", "Reverser", 0, 0 )
				gReverserLock = 1
			elseif reverser == 0 and gReverserLock == 0 and gReverserPwrLock == 0 then
				Call( "*:SetControlValue", "Reverser", 0, -1 )
				Call( "*:SetControlValue", "HornDirection", 0, 1 )
				gReverserLock = 1
			end
		elseif value == 0 and gReverserLock == 1 then
			gReverserLock = 0
		end
	end
	if name == "PowerIncreaser" then
		pwrhandle = Call( "*:GetControlValue", "PowerHandle", 0 )
		if value > 0 and pwrhandle == 0 and gPwrHandleLock == 0 then
			Call( "*:SetControlValue", "PowerHandle", 0, 1 )
			gPwrHandleStg = 0.4
			gPwrHandleLock = 1
		elseif value > 0 and pwrhandle == 1 and gPwrHandleLock == 0 then
			Call( "*:SetControlValue", "PowerHandle", 0, 3 )
			gPwrHandleStg = 0.7
			gPwrHandleLock = 1
		elseif value == 1 and pwrhandle == 3 and gPwrHandleLock == 0 then
			Call( "*:SetControlValue", "PowerHandle", 0, 4 )
			gPwrHandleStg = 1
			gPwrHandleSpring = 1
			gPwrHandleLock = 1
		elseif value ~= 1 and pwrhandle == 4 and gPwrHandleSpring == 1 then
			Call( "*:SetControlValue", "PowerHandle", 0, 3 )
			gPwrHandleStg = 0.7
			gPwrHandleSpring = 0
			gPwrHandleLock = 0
		elseif value == 0 and gPwrHandleLock == 1 then
			gPwrHandleLock = 0
		end
	end
	if name == "PowerDecreaser" then
		pwrhandle = Call( "*:GetControlValue", "PowerHandle", 0 )
		if value > 0 and pwrhandle == 1 and gPwrHandleLock == 0 then
			Call( "*:SetControlValue", "PowerHandle", 0, 0 )
			gPwrHandleStg = 0.16
			gPwrHandleLock = 1
		elseif value == 1 and pwrhandle == 3 and gPwrHandleLock == 0 then
			Call( "*:SetControlValue", "PowerHandle", 0, 2 )
			gPwrHandleStg = 0.56
			gPwrHandleSpring = 1
			gPwrHandleLock = 1
		elseif value ~= 1 and pwrhandle == 2 and gPwrHandleSpring == 1 then
			Call( "*:SetControlValue", "PowerHandle", 0, 3 )
			gPwrHandleStg = 0.7
			gPwrHandleSpring = 0
			gPwrHandleLock = 0
		elseif value == 0 and gPwrHandleLock == 1 then
			gPwrHandleLock = 0
		end
	end
	if name == "PowerDown" then
		pwrhandle = Call( "*:GetControlValue", "PowerHandle", 0 )
		if value > 0 and pwrhandle == 3 and gPwrHandleLock == 0 then
			Call( "*:SetControlValue", "PowerHandle", 0, 1 )
			gPwrHandleStg = 0.4
			gPwrHandleLock = 1
		elseif value == 0 and gPwrHandleLock == 1 then
			gPwrHandleLock = 0
		end
	end
	if name == "TrainBrakeIncreaser" then
		trainbrk = Call( "*:GetControlValue", "TrainBrakeHandle", 0 )
		if value > 0 and trainbrk == -1 and gTBrkLock == 0 then
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, 0 )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, 0.10 )
			gTBStg = 0.9
			gTBrkLock = 1
		elseif value > 0 and trainbrk == 0 and gTBrkLock == 0 then
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, 1 )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, 0.20 )
			gTBStg = 0.85
			gTBrkLock = 1
		elseif value > 0.5 and trainbrk > 0 and trainbrk < 13 and gTBrkLock == 0 and gTBrkStepLock == 0 then
			local newtrainbrk = trainbrk + 1
			tbctrl = Call( "*:GetControlValue", "TrainBrakeControl", 0 )
			local newtbctrl = tbctrl + 0.0298877474
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, newtrainbrk )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, newtbctrl )
			gTBStg = gTBStg - 0.023076923
			if newtrainbrk == 13 then
				gTBrkLock = 1
			else
				gTBrkStepLock = 2
			end
		elseif value > 0 and trainbrk == 13 and gTBrkLock == 0 then
			overreduction = 0.20 + ( 0.0298877474 * 21 )
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, 14 )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, 0.85 )
			gTBStg = 0.55
			gTBrkLock = 1
		elseif value > 0 and trainbrk == 14 and gTBrkLock == 0 then
			overreduction = 0.20 + ( 0.0298877474 * 21 )
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, 15 )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, 0.85 )
			gTBStg = 0.42
			gTBrkLock = 1
		elseif value > 0 and trainbrk == 15 and gTBrkLock == 0 then
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, 16 )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, 1 )
			gTBStg = 0.26
			gTBrkLock = 1
		elseif value == 0 and gTBrkLock == 1 then
			gTBrkLock = 0
		end
	end
	if name == "TrainBrakeDecreaser" then
		trainbrk = Call( "*:GetControlValue", "TrainBrakeHandle", 0 )
		if value > 0 and trainbrk == 0 and gTBrkLock == 0 then
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, -1 )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, 0 )
			gTBStg = 1
			gTBrkLock = 1
		elseif value > 0 and trainbrk == 1 and gTBrkLock == 0 then
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, 0 )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, 0.10 )
			gTBStg = 0.9
			gTBrkLock = 1
		elseif value > 0 and trainbrk == 2 and gTBrkLock == 0 then
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, 1 )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, 0.20 )
			gTBStg = 0.85
			gTBrkLock = 1
		elseif value > 0.5 and trainbrk > 2 and trainbrk < 14 and gTBrkLock == 0 and gTBrkStepLock == 0 then
			local newtrainbrk = trainbrk - 1
			tbctrl = Call( "*:GetControlValue", "TrainBrakeControl", 0 )
			local newtbctrl = tbctrl - 0.0298877474
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, newtrainbrk )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, newtbctrl )
			gTBStg = gTBStg + 0.023076923
			if newtrainbrk == 2 then
				gTBrkLock = 0
			else
				gTBrkStepLock = 2
			end
		elseif value > 0 and trainbrk == 14 and gTBrkLock == 0 then
			local maxtb = 0.20 + ( 0.0298877474 * 12 )
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, 13 )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, maxtb )
			gTBStg = 0.573076923
			gTBrkLock = 1
		elseif value > 0 and trainbrk == 15 and gTBrkLock == 0 then
			overreduction = 0.20 + ( 0.0298877474 * 21 )
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, 14 )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, overreduction )
			gTBStg = 0.55
			gTBrkLock = 1
		elseif value > 0 and trainbrk == 16 and gTBrkLock == 0 then
			overreduction = 0.20 + ( 0.0298877474 * 21 )
			Call( "*:SetControlValue", "TrainBrakeHandle", 0, 15 )
			Call( "*:SetControlValue", "TrainBrakeControl", 0, 0.85 )
			gTBStg = 0.42
			gTBrkLock = 1
		elseif value == 0 and gTBrkLock == 1 then
			gTBrkLock = 0
		end
	end

end

function Update ( time )

	if gFirstCheck == 1 then
		gTimer = Call( "GetSimulationTime", 0 )
		gNewTimer = gTimer
		rpm = Call( "*:GetControlValue", "RPM", 0 )
		prevRPM = rpm
		gFirstCheck = 0
	else
		gTimer = Call( "GetSimulationTime", 0 )
		gTimerS = gTimer
		gTimerP = gTimer
		sendrpm = Call( "*:GetControlValue", "RPM", 0 )
		Call( "SendConsistMessage", RPMmsgIdent, sendrpm, 0 )
		Call( "SendConsistMessage", RPMmsgIdent, sendrpm, 1 )
		timediff = gTimer - gNewTimer
		if timediff >= 0.1 then
			gNewTimer = gTimer
			rpm = Call( "*:GetControlValue", "RPM", 0 )
			rpmdiff = rpm - prevRPM
			rpmRatio = rpmdiff / timediff * 0.06
			if rpmRatio > 1.0 then
				rpmRatio = 1.0
			elseif rpmRatio <= 0 then
				rpmRatio = 0
			end
			emitRate = 0.20 - ( 0.19 * rpmRatio )
			Call( "Exhaust1:SetEmitterRate", emitRate )
			Call( "Exhaust2:SetEmitterRate", emitRate )
			emitColour = 1.0 - rpmRatio
			Call( "Exhaust1:SetEmitterColour", emitColour, emitColour, emitColour )
			Call( "Exhaust2:SetEmitterColour", emitColour, emitColour, emitColour )
			prevRPM = rpm
		end
		timediffS = gTimerS - gNewTimerS
		if timediffS >= 7.0 then
			gNewTimerS = gTimerS
			cabsigsound = Call( "*:GetControlValue", "cabsignalsound", 0 )
			Call( "*:SetControlValue", "cabsignalsound", 0, 0 )
		end
		timediffP = gTimerP - gNewTimerP
		if timediffP >= 0.1 then
			gNewTimerP = gTimerP
			pwrhandle = Call( "*:GetControlValue", "PowerHandle", 0 )
			regulator = Call( "*:GetControlValue", "Regulator", 0 )
			if gTBrkStepLock ~= 0 then
				gTBrkStepLock = gTBrkStepLock - 1
			end
			if pwrhandle == 0 then
				Call( "*:SetControlValue", "Regulator", 0, 0 )
				gReverserPwrLock = 0
			else
				gReverserPwrLock = 1
				if pwrhandle == 1 then
					Call( "*:SetControlValue", "Regulator", 0, 0.1 )
				elseif pwrhandle == 2 and regulator >= 0.106667 then
					newpower = regulator - 0.006667
					Call( "*:SetControlValue", "Regulator", 0, newpower )
				elseif pwrhandle == 2 and regulator < 0.106667 then
					Call( "*:SetControlValue", "PowerHandle", 0, 1 )
					gPwrHandleStg = 0.090
				elseif pwrhandle == 4 and regulator < 1 then
					newpower = regulator + 0.006667
					Call( "*:SetControlValue", "Regulator", 0, newpower )
				end
			end
		end
	end
	if gTBStg ~= gTBPrevStg then
		dir = gTBStg - gTBPrevStg
		if dir > 0 then
			gTBDir = 1
		elseif dir < 0 then
			gTBDir = -1
		end
		Print( "Train brakes previously set to " .. gTBPrevStg .. ", now set to " .. gTBStg .. ", moving in direction " .. gTBDir )
		gTBPrevStg = gTBStg

	end
	if gTBDir ~= 0 then
		tbcurr = Call( "*:GetControlValue", "TrainBrakeHandleAnim", 0 )
		Print( "Brakes at " .. tbcurr .. ", moving to " .. gTBStg .. ", in direction " .. gTBDir )
		if gTBDir == 1 then
			if tbcurr < gTBStg then
				tbstg = tbcurr + 0.01
				Call( "*:SetControlValue", "TrainBrakeHandleAnim", 0, tbstg )
				Print( "Setting brake handle to " .. tbstg )
			else
				gTBDir = 0
			end
		elseif gTBDir == -1 then
			if tbcurr > gTBStg then
				tbstg = tbcurr - 0.01
				Call( "*:SetControlValue", "TrainBrakeHandleAnim", 0, tbstg )
				Print( "Setting brake handle to " .. tbstg )
			else
				gTBDir = 0
			end
		end
	end
	if gPwrHandleStg ~= gPwrHandlePrevStg then
		dir = gPwrHandleStg - gPwrHandlePrevStg
		if dir > 0 then
			gPwrHandleDir = 1
		elseif dir < 0 then
			gPwrHandleDir = -1
		end
		gPwrHandlePrevStg = gPwrHandleStg
	end
	if gPwrHandleDir ~= 0 then
		pwrhandlecurr = Call( "*:GetControlValue", "PowerHandleAnim", 0 )
		if gPwrHandleDir == 1 then
			if pwrhandlecurr < gPwrHandleStg then
				pwrhandlestg = pwrhandlecurr + 0.01
				Call( "*:SetControlValue", "PowerHandleAnim", 0, pwrhandlestg )
			else
				gPwrHandleDir = 0
			end
		elseif gPwrHandleDir == -1 then
			if pwrhandlecurr > gPwrHandleStg then
				pwrhandlestg = pwrhandlecurr - 0.01
				Call( "*:SetControlValue", "PowerHandleAnim", 0, pwrhandlestg )
			else
				gPwrHandleDir = 0
			end
		end
	end

end

function OnConsistMessage ( msg, arg, dir )
	driven = Call( "*:GetControlValue", "Driven", 0 )
	if driven == 0 then
		Call( "SendConsistMessage", msg, arg, dir )
		if ( msg == RPMmsgIdent ) then
			Call( "*:SetControlValue", "RPM", 0, arg )
		end
	end
end

function OnCustomSignalMessage( NewCode )
	Call( "*:SetControlValue", "cabsignal", 0, 0 )
	Call( "*:SetControlValue", "cabsignalsound", 0, 0 )
	local cabSigCode = NewCode + 1
	Call( "*:SetControlValue", "cabsignal", 0, cabSigCode )
	Call( "*:SetControlValue", "cabsignalsound", 0, cabSigCode )
	gNewTimerS = gTimerS
end
