local score = 0
local timer = 0
local timerMax = 30
local countMax = 10
local offsetCan = 0.5
local broken = false
local canList = {}
local button = 0
local bodies = {}
local bestScores = {0, 0, 0}
local timerScore = 0
local timerScoreMax = 3

function init()
	button = FindShape("button")
	bodies = FindBodies("shooter_tag")
	
	for i = 1, #bestScores do 
		bestScores[i] = GetInt("savegame.mod.shootergame.bestscores.score" .. i)
	end
end

function tick(dt)
	if broken then
		return
	end
	
	if GetPlayerInteractShape() == button and InputPressed("interact") then
		if timer > 0 then
			SaveBestScore()
			timer = 0
			SetTag(button, "interact", GetTranslatedStringByKey("START"))
		else
			timer = timerMax
			score = 0
			SetTag(button, "interact", GetTranslatedStringByKey("STOP"))
		end
	end

	if timer > 0 then
		timerScore = timerScoreMax
		CansSpawn()
		CansScore()
		timer = timer - dt
	else
		for i = 1, #canList do
			local can = canList[i]
			CansDelete(can, i)
		end
		timerScore = timerScore - dt
		SetTag(button, "interact", GetTranslatedStringByKey("START"))
	end
	
	if IsShapeBroken(button) then
		RemoveTag(button, "interact")
		broken = true
	end
end

function draw()
	if timer > 0 then
		DrawTimer()
	elseif timerScore > 0 then 
		DrawBestScore()
	end
end

function CansSpawn()
	if #canList < countMax then
		local body = bodies[math.random(1, #bodies)]
		local min, max = GetBodyBounds(body)
		for i = 1, 3 do 
			local positionCan = Vec(math.random(min[1] + offsetCan, max[1]  - offsetCan), max[2], math.random(min[3] + offsetCan, max[3] - offsetCan))
			local transformCan = Transform(positionCan)
			QueryRejectBody(body)
			if not(QueryRaycast(positionCan, Vec(0, 1, 0), 1, 0.3)) then
				local entities = Spawn('<vox file="MOD/hub/vox/shooting_range_targets.vox" object = "bottle" strength="50"/>', transformCan)
				table.insert(canList, entities[1])
				break
			end
		end
	end
end

function CansScore()
	for i = 1, #canList do
		local can = canList[i]
		if IsBodyBroken(can) then
			score = score + 1
			CansDelete(can, i)
		end
	end
end

function CansDelete(can, index)
	table.remove(canList, index)
	Delete(can)
end

function SaveBestScore()
	table.insert(bestScores, GetScorePos(), score)
	table.remove(bestScores)

	for i = 1, #bestScores do 
		SetInt("savegame.mod.shootergame.bestscores.score" .. i, bestScores[i])
	end
end

function GetScorePos()
	local firstIndex = 1 
	local lastIndex = #bestScores
	local midIndex = 0 
	while firstIndex <= lastIndex do
		midIndex = math.floor((firstIndex + lastIndex) / 2)
		if bestScores[midIndex] == score then
			firstIndex = midIndex
			break
		elseif bestScores[midIndex] > score then	
			firstIndex = midIndex + 1
		else
			lastIndex = midIndex - 1
		end
	end
	return firstIndex 
end

function DrawTimer()
	UiPush()
		UiFont("bold.ttf", 32)
		UiTranslate(UiCenter() - 50, 65)
		UiAlign("left")
		UiTextOutline(0, 0, 0, 1)
		UiColor(1, 1, 1)
		UiScale(2.0)
		if timer <= 60 then
			UiText(math.ceil(timer * 10) / 10)
		else
			local time = math.ceil(timer)
			local minutes = math.floor(t / 60)
			local seconds = math.ceil(t - m * 60)
			if s < 10 then
				UiText(m .. ":0" .. s)
			else
				UiText(m .. ":" .. s)
			end
		end
	UiPop()
end

function DrawBestScore()
	UiPush()
		UiFont("bold.ttf", 32)
		UiTranslate(UiCenter() - 450, 135)
		UiAlign("left")
		UiColor(1, 1, 1)
		UiTextOutline(0, 0, 0, 2)
		UiScale(2.0)
		if bestScores[1] > 0 then 
			UiText("BEST SCORE: " .. bestScores[1] .. " - CURRENT SCORE: " .. score)
		end
	UiPop()
end