@name HoloDrawer
@persist [Shapes Colors]:table Angle:angle
@persist [Wep O]:entity 
@persist [Green Red Blue V C Grid PosOffset AimPos]:vector 
@persist [V1 V2 V3 C1 C2 C3 A1 A2 A3 P1 P2 P3 RI K]:number
@persist [I On Alpha Load Count A Rainbow]:number
@persist [B LoadT Shadow RenderFX Snap GridOn Shade]:number
@persist [L Shape Color Mg Sg Cg Pg Ag Agg Shg]:string
@persist [Sgg Rg Save Name M File Holo String WType]:string
@persist [Model Scale Col Pos Alp Ang Shad RFX S Shading]:array

interval(100)

if(first()|dupefinished()){
    runOnChat(1)
    runOnFile(1)
    O = owner()
    hint("Welcome to the Holo Drawer! Type: '!holo help' for help!",7)
    hint("You must be using the gravgun.",7)
    File = "none"
    Name = "Adult's HoloDrawer\n File: "+File+" \n Number of holos: "+I
    Green = vec(0,255,0)
    Red = vec(255,0,0)
    Blue = vec(0,0,255)
    Shape = "cube"
    WType = "weapon_physcannon"
    C = vec(255,255,255)
    V = vec(1,1,1)
    PosOffset = vec(0,0,0)
    Alpha = 255
    Angle = entity():angles()
    RenderFX = 0
    Shadow = 1
    Snap = 12
    GridOn = 0
    On = 0
    I = 0
    Load = 0
    LoadT = 0
    Shade = 0
    Colors["red",vector]=vec(255,0,0)
    Colors["green",vector]=vec(0,255,0)
    Colors["blue",vector]=vec(0,0,255)
    Colors["purple",vector]=vec(255,0,255)
    Colors["pink",vector]=vec(255,20,147)
    Colors["white",vector]=vec(255,255,255)
    Colors["black",vector]=vec(0,0,0)
    Colors["grey",vector]=vec(150,150,150)
    Colors["yellow",vector]=vec(255,255,0)
    Colors["orange",vector]=vec(255,140,0)
    for(I=1,holoModelList():count()){
        String = holoModelList()[I,string]
        Shapes[String,string] = String
    }
    function void clearTables()
    {
        holoDeleteAll()
        I = 0
        A = 0
        B = 0
        Z = 0
        RI = 0
        Count = 0
        Model:clear()
        Scale:clear()
        Col:clear()
        Pos:clear()
        Alp:clear()
        Ang:clear()
        Shad:clear()
        RFX:clear()
        File = "none"
        if(On){
            holoCreate(200)
        }
    }
}

elseif(changed(File)|changed(I)){
    Count = I
    Name = "Adult's HoloDrawer\n File: "+File+" \n Number of holos: "+Count
    setName(Name)
}
elseif(chatClk(O)){
    L = O:lastSaid()
    S = L:explode(" ")
    if(S[1,string]=="!holo"){
        hideChat(1)
        if(S[2,string]=="shape"){
            Shape = S[3,string]
            if(Shapes:exists(Shape)){
                printColor(Green, "The holo shape is now: "+Shape+".")
                Shape=Shapes[Shape,string]
                holoModel(200,Shape)
            }
            else{
                printColor(Red, S[3,string]+" is not a valid shape.")
                Shape="cube"
            }
        }
        elseif(S[2,string]=="size"){
            if(L:length()>=16){
                V1 = S[3,string]:toNumber()
                V2 = S[4,string]:toNumber()
                V3 = S[5,string]:toNumber()
                V = vec(V1,V2,V3)
                printColor(Green, "The size is now: "+V+".")
                holoScale(200,V)
            }
            else{
                printColor(Red, "Invalid usage.")
            }
        }
        elseif(S[2,string]=="color"){
            if(S[3,string]=="custom"){
                if(L:length()>=16){
                    Rainbow = 0
                    C1 = S[4,string]:toNumber()
                    C2 = S[5,string]:toNumber()
                    C3 = S[6,string]:toNumber()
                    C = vec(C1,C2,C3)
                    holoColor(200,C)
                    printColor(Green, "The color is now: "+C:toString()+".")
                }
                else{
                    printColor(Red, "Invalid usage.")
                }
            }
            elseif(S[3,string]=="saved"){
                Color = S[4,string]
                Rainbow = 0
                if(Colors:exists(Color)){
                    C = Colors[Color,vector]
                    holoColor(200,C)
                    printColor(Green, "The color is now: "+Colors[Color,vector]:toString()+".")
                }
                else{
                    printColor(Red, "Color does not exist!.")
                }
            }
            elseif(S[3,string]=="rainbow"){
                Rainbow = 1
                printColor(Green,"The color is now: Rainbow")
            }
            elseif(S[3,string]:length()<5){
                printColor(Red, "Invalid usage.")
            }
            
        }
        elseif(S[2,string]=="angle"){
            if(L:length()>=16){
                A1 = S[3,string]:toNumber()
                A2 = S[4,string]:toNumber()
                A3 = S[5,string]:toNumber()
                Angle = ang(A1,A2,A3)
                holoAng(200,Angle)
                printColor(Green,"The angle is now "+Angle)
            }
            else{
                printColor(Red,"Invalid usage.")
            }
        }
        elseif(S[2,string]=="pos"){
            if(L:length()>=15){
                P1 = S[3,string]:toNumber()
                P2 = S[4,string]:toNumber()
                P3 = S[5,string]:toNumber()
                PosOffset = vec(P1,P2,P3)
                printColor(Green,"Position offset is now: "+PosOffset)
            }
            else{
                printColor(Red,"Invalid usage.")
            }
        }
        elseif(S[2,string]=="clear"){
            clearTables() 
            printColor(Green,"Holos cleared.")
        }
        elseif(S[2,string]=="alpha"){
            Alpha = S[3,string]:toNumber()
            printColor(Green, "The holo alpha is now: "+Alpha:toString())
        }
        elseif(S[2,string]=="shadow"){
            if(S[3,string]=="0"|S[3,string]=="1"){
                Shadow = S[3,string]:toNumber()
                printColor(Green, "The holo shadow is now "+Shadow:toString())
                holoShadow(200,Shadow)
            }
            else{
                printColor(Red, "Invalid usage.")
            }
        }
        elseif(S[2,string]=="renderfx"){
            RenderFX = S[3,string]:toNumber()
            printColor(Green, "The holo Render FX is now "+RenderFX:toString())
            holoRenderFX(200,RenderFX)
        }
        elseif(S[2,string]=="grid"){
            if(S[3,string]=="snap"){
                if(L:length() < 17){
                    printColor(Red,"Invalid usage.")
                }
                else{
                    Snap = S[4,string]:toNumber()
                    printColor(Green,"Snap is now: "+Snap)
                }
            }
            elseif(S[3,string]=="on"){
                GridOn = 1
                printColor(Green,"Grid is now on.")
            }
            elseif(S[3,string]=="off"){
                GridOn = 0
                printColor(Green,"Grid is now off.")
            }
        }
        elseif(S[2,string]=="shade"){
            if(S[3,string]=="on"){
                Shade = 0
                printColor(Green,"Shading is now on.")
            }
            elseif(S[3,string]=="off"){
                Shade = 1
                printColor(Green,"Shading is now off.")
            }
        }
        elseif(S[2,string]=="delete"){
            holoDelete(I)
            Model:removeString(I)
            Scale:removeVector(I)
            Col:removeVector(I)
            Pos:removeVector(I)
            Alp:removeNumber(I)
            Ang:removeAngle(I)
            Shad:removeNumber(I)
            RFX:removeNumber(I)
            I--
            RI--
            printColor(Green, "Holo deleted.")
        }
        elseif(S[2,string]=="reset"){
            Alpha = 255
            C = vec(255,255,255)
            V = vec(1,1,1)
            Angle = entity():angles()
            Shape = "cube"
            Shadow = 1
            RenderFX = 0
            RI = 0
            printColor(Green, "Settings reset.")
        }
        elseif(S[2,string]=="save"){
            printColor(Green, "Holo saved.")
            Mg = glonEncode(Model)
            Sg = glonEncode(Scale)
            Cg = glonEncode(Col)
            Pg = glonEncode(Pos)
            Ag = glonEncode(Alp)
            Agg= glonEncode(Ang)
            Sgg = glonEncode(Shad)
            Rg = glonEncode(RFX)
            Shg = glonEncode(Shading)
            Holo = Mg+"\n"+Sg+"\n"+Cg+"\n"+Pg+"\n"+Ag+"\n"+Agg+"\n"+Sgg+"\n"+Rg+"\n"+Shg
            Save = Holo
            File = "Holos/"+S[3,string]+".txt"
            fileWrite(File, Save)
        }
        elseif(S[2,string]=="load"){
            LoadT = 1
            File = "Holos/"+S[3,string]+".txt"
            fileLoad(File)
        }
        elseif(S[2,string]=="weapon"){
            WType = O:weapon():type()
            if(On==1){
                holoCreate(200)
                holoAlpha(200,100)
            }
            printColor(Green, "Drawing weapon is now "+WType+".")
        }
        elseif(S[2,string]=="on"){
            On = 1
            printColor(Green, "Spawner is now on.")
        }
        elseif(S[2,string]=="off"){
            On = 0
            printColor(Red, "Spawner is now off.")
            holoDelete(200)
        }
        elseif(S[2,string]=="help"){
            printColor(Green, "'!holo shape <name>' to set the shape.")
            printColor(Green, "'!holo size # # #' to set the size.")
            printColor(Green, "'!holo color custom # # #' to set a custom color.")
            printColor(Green, "'!holo color saved <color>' to set an existing color.")
            printColor(Green, "'!holo color rainbow' to make the color rainbow.")
            printColor(Green, "'!holo angle # # #' to set the angle.")
            printColor(Green, "'!holo pos # # #' to set position offset.")
            printColor(Green, "'!holo clear' to clear all holos.")
            printColor(Green, "'!holo alpha <number>' to set the alpha.")
            printColor(Green, "'!holo shadow 1/0' to set the shadow.")
            printColor(Green, "'!holo renderfx <number>' to set the RenderFX.")
            printColor(Green, "'!holo grid on/off' to toggle grids.")
            printColor(Green, "'!holo grid snap <number>' to set the grid snapping.")
            printColor(Green, "'!holo shade on/off' to enable/disable shading.")
            printColor(Green, "'!holo delete' to delete the last spawned holo.")
            printColor(Green, "'!holo reset' to reset the spawner to default settings.")
            printColor(Green, "'!holo save <file name>' to save holos.")
            printColor(Green, "'!holo load <file name>' to load holos.")
            printColor(Green, "'!holo weapon' to make the current weapon your drawing tool.")
            printColor(Green, "'!holo on' to turn the spawner on.")
            printColor(Green, "'!holo off' to turn the spawner off.")
            printColor(Green, "'!holo help' to bring up this menu.")
        }
        else{
            printColor(Red, "Invalid usage.")
        }
    }
}
elseif(On){
    Wep = O:weapon()
    if(changed(Wep) & Wep:type() == WType){
        holoCreate(200)
        holoModel(200,Shape)
        holoScale(200,V)
        holoAng(200,Angle)
        holoColor(200,C)
        holoAlpha(200,100)
        holoShadow(200,Shadow)
        holoRenderFX(200,RenderFX)
        holoDisableShading(200,Shade)
    }
    elseif(Wep:type()==WType){
        AimPos = O:aimPos()
        K = O:keyAttack1()
        if(GridOn){
            Grid = round((AimPos + PosOffset) / Snap) * Snap
            holoPos(200,Grid)
        }
        else{
            holoPos(200,AimPos + PosOffset)
        }
        if(Rainbow){
            C = hsv2rgb(10*RI,1,1)
            holoColor(200,C)
        }
        if(changed(K) & K){
            if(I!=128){
                I++
                holoCreate(I)
                holoModel(I,Shape)
                holoAng(I,Angle)
                holoScale(I,V)
                if(Rainbow){
                    RI++
                    C = hsv2rgb(10*RI,1,1)
                }
                holoColor(I,C)
                holoAlpha(I,Alpha)
                holoShadow(I,Shadow)
                holoRenderFX(I,RenderFX)
                holoDisableShading(I,Shade)
                if(GridOn){
                    Grid = round((AimPos + PosOffset) / Snap) * Snap
                    holoPos(I,Grid)
                }
                else{
                    holoPos(I,AimPos + PosOffset)
                }
                Model:setString(I,Shape)
                Scale:setVector(I,V)
                Col:setVector(I,C)
                Pos:setVector(I,holoEntity(I):pos()-entity():pos())
                Alp:setNumber(I,Alpha)
                Ang:setAngle(I,Angle)
                Shad:setNumber(I,Shadow)
                RFX:setNumber(I,RenderFX)
                Shading:setNumber(I,Shade)
            }
            else{
                printColor(Red, "Holo Limit reached!")
            }
        }
    }
    else{
        holoDelete(200)
    }
}
elseif(LoadT){
    if(fileClk(File)){
        if(fileStatus() == _FILE_OK){
            Content = fileRead():explode("\n")
            Model = glonDecode(Content[1,string])
            Scale = glonDecode(Content[2,string])
            Col = glonDecode(Content[3,string])
            Pos = glonDecode(Content[4,string])
            Alp = glonDecode(Content[5,string])
            Ang = glonDecode(Content[6,string])
            Shad = glonDecode(Content[7,string])
            RFX = glonDecode(Content[8,string])
            Shading = glonDecode(Content[9,string])
            printColor(Green, File+" loaded!")
            Load = 1
        } 
        elseif(fileStatus() == _FILE_404){
            printColor(Red,File+" not found!")
            clearTables()
        }
        elseif(fileStatus() == _FILE_TRANSFER_ERROR){
            printColor(Red,File+" had a transfer error.")
            clearTables()
        }
        else{
            printColor(Red,"Unknown error, try again.")
            clearTables()
        }
    }
    elseif(Load){
        printColor(Green, File+" is "+Model:count()+" holos.")
        holoDeleteAll()
        if(Model:count() > 30){
            timer("create",100)
            printColor(Blue,"Large file, please wait.")  
        }
        else{
            timer("create",10)
        }
        Load = 0
    }
    elseif(clk("create")){
        A++
        holoCreate(A)
        holoModel(A,Model[A,string])
        holoScale(A,Scale[A,vector])
        holoColor(A,Col[A,vector])
        holoPos(A,entity():pos()+Pos[A,vector])
        holoAlpha(A,Alp[A,number])
        holoAng(A,Ang[A,angle])
        holoShadow(A,Shad[A,number])
        holoRenderFX(A,RFX[A,number])
        holoDisableShading(A,Shading[A,number])
        if(A == Model:count()){
            printColor(Green, "Done.")
            I = A
            LoadT = 0
        }
        elseif(!holoCanCreate()){
            timer("create",200)
        }
        else{
            I = A
            timer("create",100)
        }
    }
}