local ears = {}

-- config --
local config = {
    leftEar = models.model.root.Body.UpperBody.offset_head.Head.Ears.LeftEar, -- model part of left ear
    rightEar = models.model.root.Body.UpperBody.offset_head.Head.Ears.RightEar, -- model part of right ear

    velocityStrength = 0.8,

    extraAngle = 15, -- rotates ears by this angle when crouching
    useExtraAngle = {}, -- if any of variables in this table is true extraAngle will be used even when not crouching

    addAngle = {}, -- adds angle to ear rotation
}

local defaultLeftEarRot = config.leftEar:getRot()
local defaultRightEarRot = config.rightEar:getRot()
local rot = vec(0, 0, 0, 0)
local rotL = vec(0, 0, 0, 0)
local oldRotL = rotL
local rotR = vec(0, 0, 0, 0)
local oldRotR = rotR
local vel = vec(0, 0, 0, 0)
local oldPlayerRot = nil

function events.tick()
    -- set oldRot
    oldRotL = rotL
    oldRotR = rotR
    -- set target rotation
    local targetRot = 0
    if player:getPose() == "CROUCHING" then
        targetRot = config.extraAngle
    else
        for _, v in pairs(config.useExtraAngle) do
            if v then
                targetRot = config.extraAngle
                break
            end
        end
    end
    for _, v in pairs(config.addAngle) do
        targetRot = targetRot + v
    end
    -- player velocity
    local playerRot = player:getRot()
    if not oldPlayerRot then
        oldPlayerRot = playerRot
    end
    local playerRotVel = (playerRot - oldPlayerRot) * 0.75 * config.velocityStrength
    oldPlayerRot = playerRot
    local playerVel = player:getVelocity()
    playerVel = vectors.rotateAroundAxis(playerRot.y, playerVel, vec(0, 1, 0))
    playerVel = vectors.rotateAroundAxis(-playerRot.x, playerVel, vec(1, 0, 0))
    playerVel = playerVel * config.velocityStrength * 40
    -- update velocity and rotation
    vel = vel * 0.6 + (vec(0, 0, 0, targetRot) - rot) * 0.2
    rot = rot + vel
    rotL = rot + vel
    rotR = rot + vel
    rot.x = rot.x + math.clamp(playerVel.z + playerRotVel.x, -14, 14)
    rot.z = rot.z + math.clamp(-playerVel.x, -6, 6)
    rot.w = rot.w + math.clamp(playerVel.y * 0.25, -4, 4)

    rotL.x = rot.x + math.clamp(playerVel.z + playerRotVel.x, -14, 14)
    rotL.z = rot.z + math.clamp(-playerVel.x, -6, 6)
    rotL.w = rot.w + math.clamp(playerVel.y * 0.25, -4, 4)
    
    rotR.x = rot.x + math.clamp(playerVel.z + playerRotVel.x, -14, 14)
    rotR.z = rot.z + math.clamp(-playerVel.x, -6, 6)
    rotR.w = rot.w + math.clamp(playerVel.y * 0.25, -4, 4)

    rotL.y = rotL.y + math.clamp(playerRotVel.y * 1.75, -14, 14)
    rotR.y = rotR.y + math.clamp(-playerRotVel.y * 1.75, -14, 14)
end

function events.render(delta)
    ears.currentRotL = math.lerp(oldRotL, rotL, delta)
    ears.currentRotR = math.lerp(oldRotR, rotR, delta)
    config.leftEar:setRot(defaultLeftEarRot + ears.currentRotL.xy_ - ears.currentRotL._yz)
    config.rightEar:setRot(defaultRightEarRot + ears.currentRotR.x__ - ears.currentRotR.__z)
end

function ears.setEarsRot(leftEarRot,rightEarRot)
    config.rightEar:setOffsetRot(rightEarRot)
    config.leftEar:setOffsetRot(leftEarRot)
end

return ears -- by Auria <3