@name hcgui2
@inputs 
@outputs Ops Mover:table MoveList:string PrevMoveList:string
@persist [Player Owner Entity]:entity [MeshX MeshY] [Center HScale PScale]:vector Spawn Load LoadString:string
@persist [Radius] Colors:array Material:string Models:table
@persist [AimCell PrevAimCell] Pieces:array Mover:table Board:table
@trigger none

if (!Entity) {
    
    Load = 1
    #LoadString = "......P.....pRP....prN.P...p.nQ..P..p..qBBB.P.p.bbbK..P..p..kN.P...p.nRP....prP.....p......"
    LoadString  = "...................................Q......................................................."
    
    #-- Options
    Radius   = 16
    Material = "phoenix_storms/fender_white"

    Colors = array(
        vec(255, 255, 255), #light cells
        vec(125, 125, 125), #mid cells
        vec( 25,  25,  25)  #dark cells
    )
    
    Models = table(
        "r" = "models/props_phx/games/chess/black_rook.mdl",
        "n" = "models/props_phx/games/chess/black_knight.mdl",
        "b" = "models/props_phx/games/chess/black_bishop.mdl",
        "q" = "models/props_phx/games/chess/black_queen.mdl",
        "k" = "models/props_phx/games/chess/black_king.mdl",
        "p" = "models/props_phx/games/chess/black_pawn.mdl",
        "R" = "models/props_phx/games/chess/white_rook.mdl",
        "N" = "models/props_phx/games/chess/white_knight.mdl",
        "B" = "models/props_phx/games/chess/white_bishop.mdl",
        "Q" = "models/props_phx/games/chess/white_queen.mdl",
        "K" = "models/props_phx/games/chess/white_king.mdl",
        "P" = "models/props_phx/games/chess/white_pawn.mdl"
    )

    #-- Setup
    #include "games/chess/hex/lib/lib"

    Entity = entity()
    Owner  = owner()
    
    MeshX  = Radius*0.5*sqrt(3)
    MeshY  = Radius*0.5 + Radius*0.25
    Center = vec(-MeshX*3, MeshY*6, 0)
    HScale = vec(Radius - 0):setZ(sqrt(Radius))
    PScale = vec(Radius - 0) / 24
    
    findClearWhiteList()
    findClearBlackList()
    findIncludePlayerProps(Owner)
    
    Mover["stage", number] = 0
    Mover["frac", number] = 0

    interval(100)
}
else {
    if (Load & Spawn < 91) {
        interval(15)

        while (perf() & holoCanCreate() & Spawn < 91) {
            Spawn++

            holoCreate(Spawn)
            holoParent(Spawn, Entity)
            holoModel(Spawn, "hexagon")
            holoScaleUnits(Spawn, HScale)
            holoColor(Spawn, Colors[getColor(Spawn, 1), vector])
            holoMaterial(Spawn, Material)
            holoAng(Spawn, Entity:angles())
            
            findIncludeEntity(holoEntity(Spawn))

            local File = getFile(Spawn)
            local Rank = getRank(Spawn)
            
            switch (File < 7) {
                case 1, holoPos(Spawn, Entity:toWorld(Center + vec(Rank*MeshX - File*MeshX*0.5, -File*MeshY, 0))), break
                case 0, holoPos(Spawn, Entity:toWorld(Center + vec(Rank*MeshX + (File - 12)*MeshX*0.5, -File*MeshY, 0))), break    
            }
            
            local Piece = LoadString[Spawn]
            if (Piece != "." & Piece != "") {
                local PieceIndex = hash(getNotation(Spawn))
                local IsBlack = isBlack(Piece)

                holoCreate(PieceIndex)
                holoParent(PieceIndex, Entity)
                holoMaterial(PieceIndex, Material)
                holoModel(PieceIndex, Models[Piece, string])
                holoColor(PieceIndex, IsBlack ? mix(Colors[3, vector], Colors[2, vector], 3/4) : Colors[1, vector])
                holoPos(PieceIndex, holoEntity(Spawn):toWorld(vec(0, 0, HScale[3]/2)))
                holoAng(PieceIndex, Entity:toWorld(ang(0, 180*IsBlack, 0)))
                holoScale(PieceIndex, PScale)
                
                findExcludeEntity(holoEntity(PieceIndex))
                
                Pieces[Spawn, number] = PieceIndex
            }
        }    
    }
    elseif (!Load) {
        interval(90)
        
        while (perf() & Board:count() < 91) {
            local Index = Board:count() + 1
            
            Board[Index, table] = table(
                "piece_type" = ".",
                "neighbors" = getNeighbors(Index)
            )
        }

        if (Board:count() > 91) {
            Spawn = 0
            Load = 1
        }
    }
    else {
        interval(90)
        
        #[
        Ops = ops()

        if (findCanQuery()) {
            local Player = owner()
            local Eye = linePlaneIntersection( Player, Entity:toWorld(HScale/2), Entity:up() )
            
            findClipToClass("gmod_wire_hologram")
            findInSphere(Eye, Radius/2)
            findSortByDistance(Eye)
            
            AimCell = holoIndex(find())
        }
        
        if (changed(AimCell)) {
            
            #holoColor(PrevAimCell, Colors[getColor(PrevAimCell, 1), vector])
            #foreach (K, Neighbor:number = getNeighbors(PrevAimCell)) {
            #    holoColor(Neighbor, Colors[getColor(Neighbor, 1), vector])
            #}
            
            #holoColor(AimCell, vec(255, 125, 0))
            #foreach (K, Neighbor:number = getNeighbors(AimCell)) {
            #    holoColor(Neighbor, vec(255, 0, 0))
            #}
            
            for (I = 1, PrevMoveList:length(), 5) {
                local Move = PrevMoveList:sub(I, I + 4)
                local To = Move:sub(3, 4):toNumber() 
                
                holoColor(To, Colors[getColor(To, 1), vector])
            }
            
            
            
            MoveList = ""
            local PieceIndex = Pieces[AimCell, number]
            if (PieceIndex) {
                local Model = holoEntity(PieceIndex):model()
                local Piece = invert(Models)[Model, string]
                
                if (Piece == "Q") {
                    MoveList = getKnightMoves(AimCell, Piece)

                    for (I = 1, MoveList:length(), 5) {
                        local Move = MoveList:sub(I, I + 4)
                        local To = Move:sub(3, 4):toNumber() 
                        
                        holoColor(To, Move[5] == "." ? vec(0, 255, 255) : vec(255, 0, 0))
                    }
                }
            }

            PrevAimCell = AimCell
            PrevMoveList = MoveList
    
        }
        
        ]#

    }
}







        #[
        local Click = owner():keyAttack2()

        if (changed(Click) & Click) {
            if (Mover["stage", number] == 0) {
                local PieceIndex = Pieces[AimCell, number]
                if (PieceIndex) {
                    #local Model = holoEntity(PieceIndex):model()
                    #local Piece = invert(Models)[Model, string]
                    
                    Mover["holo", number] = PieceIndex
                    Mover["start", number] = AimCell
                    Mover["stage", number] = 1
                }                
            }
            elseif (Mover["stage", number] == 1) {
                Mover["finish", number] = AimCell
                Mover["stage", number] = (Mover["start", number] != Mover["finish", number]) ? 2 : 0
            }        
        }
        
        if (Mover["stage", number] == 2) {
            Mover["frac", number] = min(Mover["frac", number] + 0.125, 1)
            
            local Pos = mix(holoEntity(Mover["finish", number]):pos(), holoEntity(Mover["start", number]):pos(), cosine(0, 1, Mover["frac",number]))
            holoPos(Mover["holo", number], Pos)
            
            if (Mover["frac", number] == 1) {
                Mover["holo", number] = 0
                Mover["frac", number] = 0
                Mover["stage", number] = 0
            }
        }]#
