--Main

local Linear: any = {}
Linear.__index = Linear

function Linear.new(...: Vector3): ()
    local points: {Vector3} = {...}
    local length: number do
        length = 0
        for i, point in ipairs(points) do
            if i == 1 then
                continue
            end

            local prevPoint: Vector3 = points[i - 1]
            length += (point - prevPoint).Magnitude
        end
    end
    
    
    return setmetatable({
        Points = points,
        Length = length
    }, Linear)
end

function Linear:Get(val: number): Vector3
    val = math.clamp(val, 0, 1)

    local points: {Vector3} = self.Points
    local length: number = self.Length

    local targetLength: number = length * val
    local currentLength: number = 0
    local i: number = 1

    local foundPoint: Vector3 = points[1]

    while true do
        local thisPoint: Vector3, nextPoint: Vector3 = points[i], points[i + 1]
        local thisLength: number = (nextPoint - thisPoint).Magnitude

        if currentLength + thisLength > targetLength then
            --Mid point must be somewhere between this point and next point
            local remainingLength: number = targetLength - currentLength
            foundPoint = thisPoint + (nextPoint - thisPoint).Unit * remainingLength

            break
        end

        currentLength += thisLength
        i += 1
        
        if i == #points then
            foundPoint = points[#points]
            break
        end
    end

    return foundPoint
end

return {
    Raw = Linear,
    new = Linear.new
}
