#@name tetris_holo_3
@inputs 
@outputs 
@persist GamePhase:string [Mover Entity]:entity Holo
@persist GamePiece:table [Tetromino Colors]:table [GameRowNext GameRowPrev] [GameNextStep GameStep]
@trigger none



if (first()) {
    
    Entity = entity()
    Mover = holoCreate(1000), holoParent(1000, Entity), holoAlpha(1000, 50)

    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)
        )
    ) 
    
    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
    )

        
    GamePhase = "EVALUATE"

    function gameSpawnPiece() {
        local Color = 1#randint(1, 7)
        
        GamePiece = Tetromino[Color, table]:clone()
        
        local Dim = GamePiece:count()
        for (R = 1, Dim) {
            for (C = 1, Dim) {
                if (GamePiece[R, array][C, number]) {
                    GamePiece[R, array][C, number] = Color
                    
                    Holo++
                    holoCreate(Holo)
                    holoParent(Holo, Entity)
                    holoPos(Holo, Entity:toWorld(vec(0, (C - 1)*12, (R - 1)*12)))
                    #holoPos(Holo, Entity:toWorld(vec(0, 12*C - 6*Dim - 6, -12*R + 6*Dim + 6)))
                    holoScaleUnits(Holo, vec(sqrt(11), 11, 11))
                    holoColor(Holo, Colors[Color, vector])
                    holoMaterial(Holo, "models/shiny")
                    holoModel(Holo, "rcube")
                    holoDisableShading(Holo, 1)
                }
            }
        } 
    }

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

    gameSpawnPiece()
    
}

interval(45)

switch (GamePhase) {
    case "EVALUATE", 
        GameRowPrev = GameRowNext
        GameRowNext = GameRowNext + 1
        
        GamePhase = "MOVE_DOWN"
    break

    case "MOVE_DOWN", 
        GameStep = min(GameStep + 0.25, 1)
        
        local BlendFrac = smoothstep(GameStep)
        local BlendRow = GameRowPrev + BlendFrac * (GameRowNext - GameRowPrev)
        
        local Dim = GamePiece:count()
        local Num = Holo

        for (R = 1, Dim) {
            for (C = 1, Dim) {
                if (GamePiece[R, array][C, number]) {
                    holoPos(Num, Entity:toWorld(vec(0, (C - 1)*12, -(R + BlendRow)*12)))
                    #(C + CurCol - 1)*12, -(R + CurRow - 1)*12)))
                    Num--    
                }
            }
        }
        
        #holoPos(1000, Entity:toWorld(vec(0, 0, -BlendRow*12)))

        if (GameStep == 1) {
            GameStep     = 0
            GameNextStep = curtime()
            GamePhase    = "STEP_DELAY"    
        }
    break
    
    case "STEP_DELAY", 
        if (GameRowPrev == 10) {
            #for (H = Holo, Holo - 4, -1) {
            #    holoParent(H, Entity)
            #}
            
            gameSpawnPiece()
            
            #holoPos(1000, Entity:pos())
    
            GameRowPrev = GameRowNext = 0    
        }
        if (curtime() - GameNextStep > 0.5) {
            GamePhase = "EVALUATE"
        }
    break
}
