#@name tetris_holo
@inputs 
@outputs INCP INCR FRAC Ang PrevR NextR
@persist HOLO_Base HOLO_ID INCP INCR PrevR NextR Tetromino:table Colors:table PrevP NextP
@trigger none

if (first()) {
    
#------------------------
#-- PIECE: Shapes 
Tetromino = table(
    1 = table( #-- i
        array(0, 0, 0, 0),
        array(1, 1, 1, 1),
        array(0, 0, 0, 0),
        array(0, 0, 0, 0)
    ),
    2 = table( #-- j
        array(1, 0, 0),
        array(1, 1, 1),
        array(0, 0, 0)    
    ),
    3 = table( #-- l
        array(0, 0, 1),
        array(1, 1, 1),
        array(0, 0, 0)
    ),
    4 = table( #-- o
        array(1, 1),
        array(1, 1)
    ),
    5 = table( #-- s
        array(0, 1, 1),
        array(1, 1, 0),
        array(0, 0, 0)
    ),
    6 = table( #-- t
        array(0, 1, 0),
        array(1, 1, 1),
        array(0, 0, 0)
    ),
    7 = table( #-- z
        array(1, 1, 0),
        array(0, 1, 1),
        array(0, 0, 0)
    )
)

    
#------------------------
#-- PIECE: Colors
Colors = table(
    0 = hsv2rgb(  0, 0, 1), #-- white
    1 = hsv2rgb(180, 1, 1), #-- i, cyan
    2 = hsv2rgb(240, 1, 1), #-- j, blue
    3 = hsv2rgb( 30, 1, 1), #-- l, orange
    4 = hsv2rgb( 60, 1, 1), #-- o, yellow
    5 = hsv2rgb(120, 1, 1), #-- s, green
    6 = hsv2rgb(300, 1, 1), #-- t, magenta
    7 = hsv2rgb(360, 1, 1)  #-- z, red
)


HOLO_ID++
HOLO_Base = HOLO_ID
holoCreate(HOLO_Base)
holoAlpha(HOLO_Base, 50)

function void demo1( PieceType, Rotate ) {
    
    local Piece = Tetromino[PieceType, table]:clone()
    local Color = Colors[PieceType, vector]
    
    local Dim = Piece:count()

    for (PieceRow = 1, Dim) {
        for (PieceCol = 1, Dim) {
            if (Piece[PieceRow, array][PieceCol, number]) {
                HOLO_ID++
                holoCreate(HOLO_ID)
                holoParent(HOLO_ID, HOLO_Base)
                holoPos(HOLO_ID, holoEntity(HOLO_Base):toWorld(vec(0, 12*PieceCol - 6*Dim - 6, -12*PieceRow + 6*Dim + 6)))
                holoScaleUnits(HOLO_ID, vec(sqrt(11), 11, 11))
                holoColor(HOLO_ID, Color)    
                holoDisableShading(HOLO_ID, 1)
                holoMaterial(HOLO_ID, "models/shiny")
                holoModel(HOLO_ID, "rcube")
            }
        }
    }
    
    for (I = 1, abs(Rotate)) {
        holoAng(HOLO_Base, holoEntity(HOLO_Base):toWorld(ang(0, 0, -90*sign(Rotate))))
    }
}

function void demo2( PieceType ) {
    local Piece = Tetromino[PieceType, table]:clone()
    local Color = Colors[PieceType, vector]
    
    local Dim = Piece:count()
    
    local N = HOLO_ID - 4
    for (PieceRow = 1, Dim) {
        for (PieceCol = 1, Dim) {
            if (Piece[PieceRow, array][PieceCol, number]) {
                N++
                #print(N)
                holoPos(N, holoEntity(HOLO_Base):toWorld(vec(0, 12*PieceCol - 6*Dim - 6, -12*PieceRow + 6*Dim + 6)))
                holoColor(N, Color)    

            }
        }
    }    
    
}

PrevR = 0
NextR = 90

function number smoothstep(Frac) {
    return 6*Frac^5 - 15*Frac^4 + 10*Frac^3    
}

    function number lerp(A, B, X) {
        #return A + (B - A) * X
        #return N0*T + N1*(1-T)
        return (1-X)*A + X*B
    }
    function number linear( Y0, Y1, T ) {
        return Y0 + T * (Y1 - Y0)
    }

    function number cosine( Y0, Y1, T ) {
        return linear( Y0, Y1, -cosr( pi() * T ) / 2 + 0.5 )
    }    
    demo1( 1, 0 )
    
    interval(200)
}

else {
    interval(100)
    
    
    INCR = min(INCR + 0.0625, 1)
    if (INCR == 1) {
        INCR = 0
        
        PrevR = NextR
        NextR = NextR + 90 
        
        PrevP = NextP 
        NextP = NextP - 12
        
        
        if (NextR % 360 == 0) {
            INCP = (INCP + 1) % 7
            demo2(INCP + 1)
        }
    }
    
    Ang = angnorm(lerp(PrevR, NextR, smoothstep(INCR)))
    holoAng(HOLO_Base, entity():toWorld(ang(0, 0, Ang)))
    holoPos(HOLO_Base, entity():toWorld(vec(0, 0, cosine(PrevP, NextP, INCR))))
}





#demo( 5, 2 )
