#include "../../config/events.lua"
#include "../../script/helpers/entity.lua"
#include "../../script/helpers/mathfr.lua"

rollers = nil
body = nil
sound_locs = nil
snd = nil
vol = nil
delay = 0
disabled = nil

function init()
    rollers     = FindJoints("roller")
    sound_locs  = FindLocations("sound_pos")
    for i = 1, #sound_locs do
        local loc = sound_locs[i]
        sound_locs[i] = GetLocationTransform(loc).pos
        Delete(loc)
    end
    snd         = LoadLoop("MOD/snd/grinder.ogg")
    vol         = 1.0
    max_dmg     = 0.1
    bodies      = FindShapes("unbreakable")
    for i = 1, #bodies do
        bodies[i] = GetShapeBody(bodies[i])
    end
end

function tick(dt)
    if disabled then return end

    for i = 1, #sound_locs do
        PlayLoop(snd, sound_locs[i], vol)
    end

    for i = #rollers, 1, -1 do
        local joint = rollers[i]
        if IsJointBroken(joint) then
            table.remove(rollers, i)
            table.remove(sound_locs, i)
            if #rollers == 0 then
                disabled = cEntity:EnqueueDeletion()
            end
        else
            SetJointMotor(joint, 3.0)
        end
    end
end

function update(dt)
    if disabled then return end
    if delay > dt then delay = delay - dt return end

    local no_hits = 0
    local seen = {}
    for i = 1, #bodies do
        local body = bodies[i]
        WatchBodyHit(body)
        if not IsBodyHitted(body) then
            no_hits = no_hits + 1
        else
            for index = 0, GetBodyHitsCount(body) - 1 do
                local other_body, impulse, pos, normal, this_vel, other_vel = GetBodyHit(body, index)
                local veh = GetBodyVehicle(other_body)
                impulse = math.abs(impulse)
                if veh > 0 and HasTag(veh, "customhealth") and impulse > 25 and not seen[veh] and GetVehicleHealth(veh) > 0 then
                    local dmg = math:MapRangeClamped(math.sqrt(impulse), 15, 150, 0, max_dmg)
                    if dmg > 0 then
                        TriggerEvent(EVENTS.UPDATE_HEALTH, veh .. ";" .. dmg)
                        seen[veh] = true
                    end
                end
            end
        end
    end
    if no_hits ~= #bodies then
        delay = 0.5
    end
end
