@name Any-Degree Bezier
@persist T P:array

function number pascal(Row, Place)
{
    local Line = array(1)
    for(I = 1, Place)
    {
        local K = I - 1
        Line:pushNumber(Line[K + 1, number] * (Row - K) / (K + 1))
    }
    
    return Line[Place + 1, number]
}

function vector nbezier(Points:array, Time)
{
    # Input points in order from start to end
    
    if(Time == 0)
    {
        return Points[1, vector]
    }
    elseif(Time == 1)
    {
        return Points[Points:count(), vector]
    }
    
    local Ret = vec()
    
    local N = Points:count() - 1
    for(K = 0, N)
    {
        Ret += pascal(N, K) * (1 - Time)^(N - K) * (Time^K) * Points[K + 1, vector]
    }
    
    return Ret
}

function number array:validate(E:entity)
{
    if(!This:count())
    {
        return 0
    }
    
    foreach(I, TE:entity = This)
    {
        if(TE == E)
        {
            return I
        }
    }
    
    return 0
}

function array array:ehh()
{
    local Ret = array()
    
    foreach(I, TE:entity = This)
    {
        Ret:pushVector(TE:pos())
    }
    
    return Ret
}

interval(50)

if(first())
{
    holoCreate(1)
    holoModel(1, "icosphere")
    holoEntity(1):setTrails(10, 10, 10, "trails/smoke", vec(0), 255)
    
    timer("props", 0)
    
}


if(clk("holo"))
{
    local Interval = 30 + (P:count() * 5)
    timer("holo", Interval)
    
    print(4, "interval: " + Interval + " ms")
    
    if(P:count() > 1)
    {
        holoPos(1, nbezier(P:ehh(), clamp(0.5 + (sinr(curtime() * 1.5) / 1.95), 0, 1))) 
    }
}

if(clk("props"))
{
    timer("props", 200)
    
    local AE = owner():aimEntity()
    if(AE:isValid() & AE:owner() == owner() & AE != entity() & !P:validate(AE))
    {
        P:pushEntity(AE)
        
        if(P:count() == 1)
        {
            timer("holo", 0)
        }
    }
    
    foreach(I, TE:entity = P)
    {
        if(!TE:isValid())
        {
            P:remove(I)
            
            if(P:count() == 0)
            {
                stoptimer("holo")
            }
        }
    }
}


