#include "../script/common/utils.lua"

local isfireOn = GetEnvironmentProperty("nightlight")
local broken = false
local maxVelocityPlayer = 4.99
local maxVelocityCandle = 14.0
local maxDistFromPlayer = 22.0

function init()
	torchbody = FindBody("torchbody")
	velocity = FindBody("velocity")
	lightthing = FindLight("lightthing")
	candle = FindShape("candle")
	fire = FindShape("fire")

	soundCandleOn = LoadSound("MOD/sound/candle-on.ogg")
	soundCandleOff = LoadSound("MOD/sound/candle-off.ogg")

	SetTagOnCandleFire(isfireOn)
	SetLightEnabled(lightthing, isfireOn)
end

function SpawnFireEffect(startPos)
	ParticleReset()
	ParticleType("smoke")
	ParticleColor(1.0, 0.65, 0.5, 0.85, 0.33, 0.0)
	ParticleRadius(0.05)
	ParticleTile(1)
	ParticleEmissive(3.0, 0.5, "easein")
	ParticleRotation(1, 0, "linear")
	SpawnParticle(startPos, Vec(0.05, rnd(0.05, 1.55), 0.05), 0.5)
end

function SetCandleEnabled(enabled, flamePos)
	isfireOn = enabled
	SetTagOnCandleFire(isfireOn)
	SynchronizationCandleLight(isfireOn)
	PlaySound(isfireOn and soundCandleOn or soundCandleOff, flamePos)
end

function tick(dt)
	if broken then
		return
	end

	local min, max = GetShapeBounds(fire)
	local flamePos = VecAdd(VecLerp(min, max, 0.5), Vec(0, 0.05, 0))

	if GetPlayerInteractShape() == candle and InputPressed("interact") then
		SetCandleEnabled(not isfireOn, flamePos)
	end

	if isfireOn then
		local playerPos = GetPlayerPos()
		local candleTransfrom = GetBodyTransform(velocity)

		local distToPlayer = GetPointsDistance(playerPos, candleTransfrom.pos)

		if distToPlayer > maxDistFromPlayer and IsLightActive(lightthing) then
			SetLightEnabled(lightthing, false)
		elseif distToPlayer <= maxDistFromPlayer and not IsLightActive(lightthing) then
			SetLightEnabled(lightthing, true)
		end

		if IsLightActive(lightthing) then
			SpawnFireEffect(flamePos)
			SynchronizationCandleLight(isfireOn)
			TryToFireUp(flamePos)
		end

		if IsPointInWater(flamePos) then
			SetCandleEnabled(false, flamePos)
		end
	end

	local isVelocityPlayerMax = isfireOn and VecLength(GetPlayerVelocity()) >= maxVelocityPlayer
	local isVelocityCandleMax = isfireOn and VecLength(GetBodyVelocity(velocity)) >= maxVelocityCandle

	if (GetPlayerGrabShape() == candle and isVelocityPlayerMax) or isVelocityCandleMax then 
		SetCandleEnabled(false, flamePos)
	end

	if not broken and IsShapeBroken(candle) then
		RemoveTag(candle, "interact")
		broken = true
		SetLightEnabled(lightthing, false)
	end
end

function SetTagOnCandleFire(switch)
	SetTag(candle, "interact", GetTranslatedStringByKey(switch == false and "CANDLE_ON" or "CANDLE_OFF"))
end

function SynchronizationCandleLight(switch)
	if switch then 
		lightpos = VecAdd(GetShapeWorldTransform(fire).pos, Vec(math.random(-1, 1) / 50, math.random(-1, 1) / 50, math.random(-1, 1) / 50))
		SetLightColor(lightthing, 0.9, 0.35, 0)
		SetLightIntensity(lightthing, math.random(2.0, 2.7))
		SetBodyTransform(torchbody, Transform(lightpos))
	else
		SetLightIntensity(lightthing, 0)
	end
end

function GetPointsDistance(left, right)
	return math.sqrt((left[1] - right[1]) ^ 2 + (left[2] - right[2]) ^ 2 + (left[3] - right[3]) ^ 2)
end

function TryToFireUp(firePos)
	if not isfireOn then return end

	QueryRejectBody(velocity)

	local castFwd = TransformToParentVec(GetShapeWorldTransform(fire), Vec(0, 1, 0))
	local hit, dist = QueryRaycast(firePos, castFwd, 0.3, 0.15)

	if hit then
		SpawnFire(VecAdd(firePos, VecScale(castFwd, dist)))
	end
end