STATE_NONE = ""
STATE_READY = "ready"
STATE_START = "start"
STATE_RACE = "race"
STATE_FINISH = "finish"
STATE_BROKEN = "broken"


function init()
	state = ""
	startTrigger = FindTrigger("start")
	finishTrigger = FindTrigger("finish")
	timer = 0
	startFrame = 0
	finishFrame = 0
	finishFrame = 0
	readySnd = LoadSound("MOD/main/Racetrack Props/snd/ready.ogg")
	startSnd = LoadSound("MOD/main/Racetrack Props/snd/start.ogg")
	failSnd = LoadSound("MOD/main/Racetrack Props/snd/fail.ogg")
	cp1 = false
	cp2 = false
	cp3 = false
	cpSnd = LoadSound("MOD/main/Racetrack Props/snd/checkpoint.ogg")
	finishSnd = LoadSound("MOD/main/Racetrack Props/snd/finish.ogg")
	readyPos = Vec()
	bestTime = 0
	lastTime = 0
	timeNotInCar = 0
end


function update(dt)
	local driving = GetBool("game.player.usevehicle")
	local pos = GetPlayerPos()

	if driving then
		if state == STATE_NONE then
			if IsPointInTrigger(startTrigger, pos) then
				state = STATE_READY
				readyFrame = 0
			end
		end
		if state == STATE_READY then
			if IsPointInTrigger(startTrigger, pos) then
				if VecLength(VecSub(pos, readyPos)) > 0.1 then
					readyFrame = 0
					readyPos = VecCopy(pos)
				end
				readyFrame = readyFrame + 1
				if readyFrame == 90 then
					state = STATE_START
					startFrame = 0
				end
			else
				state = STATE_NONE
			end
		end
		if state == STATE_START then
			if IsPointInTrigger(startTrigger, pos) then
				if startFrame == 0 then
					PlaySound(readySnd)
				end
				if startFrame == 60 then
					PlaySound(readySnd)
				end
				if startFrame == 120 then
					PlaySound(readySnd)
				end
				if startFrame == 180 then
					PlaySound(startSnd)
					state = STATE_RACE
					timer = 0
					cp1 = false
					cp2 = false
					cp3 = false
					SetBool("level.track.gate.1", false)
					SetBool("level.track.gate.2", false)
					SetBool("level.track.gate.3", false)
				end
				startFrame = startFrame + 1
			else
				state = STATE_NONE
				PlaySound(failSnd)			
			end
		end
		if state == STATE_RACE then
			if not cp1 then
				if GetBool("level.track.gate.1") then 
					cp1 = true
					PlaySound(cpSnd)
				end
			end
			if not cp2 and cp1 then
				if GetBool("level.track.gate.2") then 
					cp2 = true
					PlaySound(cpSnd)
				end
			end
			if not cp3 and cp1 and cp2 then
				if GetBool("level.track.gate.3") then 
					cp3 = true
					PlaySound(cpSnd)
				end
			end
			if cp1 and cp2 and cp3 then
				if IsPointInTrigger(finishTrigger, pos) then 
					state = STATE_FINISH
					PlaySound(finishSnd)
					finishFrame = 0
					lastTime = timer
					if timer < bestTime then 
						bestTime = timer
					end
				end
			else
				if timer > 5 and IsPointInTrigger(startTrigger, pos) then 
					PlaySound(failSnd)
					state = STATE_NONE
				end
			end
		end
		if state == STATE_FINISH then
			finishFrame = finishFrame + 1
			if finishFrame > 120 then
				state = STATE_NONE
			end
		end
	else
		--If not driving and not in race, reset state
		if state ~= STATE_RACE then
			state = STATE_NONE
		end
	end

	--Abort race if player exit vehicle for ten seconds
	if driving then
		timeNotInCar = 0
	else
		timeNotInCar = timeNotInCar + dt
	end
	if timeNotInCar > 10 and state == STATE_RACE then
		state = STATE_NONE
	end

	if state == STATE_RACE then
		timer = timer + dt
		SetFloat("level.track.timer", timer)
	end
		
	if GetBool("level.track.gatebroken") then
		state = STATE_BROKEN
	end
	SetString("level.track.state", state)

	if state == STATE_START then
		SetString("level.track.start", 3-math.floor(startFrame/60))
	else
		SetFloat("level.track.best", bestTime)
		SetFloat("level.track.last", lastTime)
	end
end


function draw()
	if not GetBool("game.map.enabled") then
		local state = GetString("level.track.state")
		if state == "race" then
			local timer = math.floor(GetFloat("level.track.timer") * 100) / 100
			gRaceFinishNotification = nil
			UiPush()
				UiTranslate(UiCenter()-40, UiHeight()-80)
				UiFont("bold.ttf", 32)
				UiText(timer)
			UiPop()
		end
		if state == "finish" and not gRaceFinishNotification then
			gRaceFinishNotification = true
			local bestTime = math.floor(GetFloat("level.track.best") * 100) / 100
			local lastTime = math.floor(GetFloat("level.track.last") * 100) / 100
			if bestTime == lastTime then
				SetString("hud.notification", "New record "..bestTime)
			else
				SetString("hud.notification", "Lap time "..lastTime)
			end
		end
	end
end