#include "../../config/events.lua"
#include "../helpers/utils.lua"
#include "../helpers/entity.lua"

pVelocityStrength = GetIntParam("velocity_strength", 100)
pTag = GetStringParam("affect_tag", "")
pDistance = GetIntParam("affect_distance", 7)
pDuration = GetFloatParam("duration", 0.0)
pFrequency = GetFloatParam("frequency", 0.0)
pListener = GetStringParam("listener", "")

function init()
    loc = GetLocationTransform(FindLocation())
    local fwdPos = TransformToParentPoint(loc, Vec(0, 0, -pDistance))
    loc = loc.pos
    dir = VecNormalize(VecSub(fwdPos, loc))
    local distance = {pDistance, pDistance, pDistance}
    low = VecSub(loc, distance)
    high = VecAdd(loc, distance)

    if pFrequency ~= 0.0 then timer = 0 end

    if pListener == "" then
        InitStart()
    else
        RegisterListenerToFiltered(EVENTS.CALL_FUNCTION, "CallWithArgs", { wind=true })
    end
end

function update(dt)
    if not isStarted then return end
    if timer then timer=timer+dt if timer > pFrequency then timer = 0 else return end end

    QueryRequire("dynamic")
	local shapes = QueryAabbShapes(low, high)

	--Apply force to dynamic shapes
	for i = 1, #shapes do repeat
		local s = shapes[i]
        if not HasTag(s, pTag) then break end

		local _, point = GetShapeClosestPoint(s, loc)
		local l = VecLength(VecSub(point, loc))

		if l > 0 then
			local scale = 1.0 - l/pDistance

			--Apply impulse to the shape's body 
			local b = GetShapeBody(s)

            ApplyBodyImpulse(b, point, VecScale(dir, pVelocityStrength * scale))
            utils:LimitVelocity(b, 15, 15)
		end
	until true end
end

function wind(name)
    if name ~= pListener then return end

    InitStart()

    utils:SetTimer(UnregisterListenerFiltered, { EVENTS.CALL_FUNCTION, "CallWithArgs" }, { delay=GetTimeStep() } )
end

function InitStart()
    isStarted = true

    if pDuration <= 0 then return end

    utils:SetTimer(function()
        isStarted = false
        cEntity:EnqueueDeletion()
    end, nil, { delay = pDuration } )
end
