@name Tetranet
@inputs Scr:wirelink UserTrigger:entity MaxEject
@outputs Eject
@persist User:entity Menu [Val Errors]:table Rate [UserID BaseURL]:string
@trigger all

interval(100)
Use=~UserTrigger & UserTrigger==User
Draw=changed(Menu) | ~Scr | first()
Global=gTable("Tetranet")

if (first()) {
    Rate=25000 # dollars per refined metal
    BaseURL="" #"http://scriptis.net/SteamBot.php?key=1820287!&action="
    Errors=table(
        "Err_Idle"="You idled during the trade.", 
        "Err_Error"="Something went wrong with the trade.",
        "Err_NoInvite"="You did not accept the bot's friend invite.",
        "Err_Offline"="You are offline on steam."    
    )
    
    function say(S:string) {
        printColor(vec(64,255,255),"[Tetranet] ",vec(255),S)
    }
    say("Loaded")
    
    if (!Global["Active",number]) {
        Global["Active",number]=1
        Global["Queue",table]=table()
        Global["Completed",number]=0
        Global["Paid",number]=0
        say("Built globaldata structure")
    }
    
    function number pIR(Num:number) {
        local O=Scr:egpCursor(User)
        local Diff=Scr:egpSize(Num)/2
        local Pos=Scr:egpPos(Num)
        return inrange(O,Pos-Diff,Pos+Diff)
    }
    
    function string prettyInt(N:number) {
        #print(N)
        local Str=ceil(N):toString():reverse():explode("")
        local Count=Str:count()
        local Add=1
        for (I=0, Str:count(), 3) {
            if (I!=0 & I!=Count & Str[I+1,string]) {Str:insertString(I+Add,",") Add++}
        }
        return Str:concat():reverse()
    }
    
    function vector getStringColor(S:string) {
        return hsv2rgb(hash(S)%360,1,0.8)
    }
    
    function sexybg(Scr:wirelink) {
        Scr:egpClear()
        Scr:egpBox(300,vec2(256),vec2(512))
        Scr:egpColor(300,vec(64))
        local Lines=5
        local Dist=512/Lines
        for (I=1, Lines+2) {
            Scr:egpLine(I+200,vec2(Dist*(I-2),-5),vec2(Dist*I,517))
            Scr:egpSize(I+200,30)
            Scr:egpMaterial(I+200,"gui/gradient_down")
            Scr:egpColor(I+200,vec(32))
        }
    }
    
    function sSymbol(ID,Vec2:vector2,Scale){
        local Offset=vec2(-248,-250)
        local SSymbol_Graph=array(vec2(242.7,311.7),vec2(249.1,304.6),vec2(256.9,298.9),vec2(267.6,293.3),vec2(272.4,295.1),vec2(281.5,286.9),vec2(286,296.4),vec2(291.3,306.8),vec2(290.5,298.6),vec2(289.7,287.6),vec2(292,280.3),vec2(293.6,276.6),vec2(295.9,280.3),vec2(299,273.6),vec2(299.7,263.1),vec2(295,251.2),vec2(289.8,244.4),vec2(285.1,241.3),vec2(280.9,238.4),vec2(275.8,236.3),vec2(271.2,234.5),vec2(274.4,231.9),vec2(270.6,231.3),vec2(264.5,231.5),vec2(256.5,229.6),vec2(250,228.1),vec2(243.3,223.2),vec2(241.1,219.4),vec2(240.7,214.7),vec2(243.1,210.8),vec2(246.7,210),vec2(247.1,214.9),vec2(248.8,218.6),vec2(250.4,215.2),vec2(254.5,215.9),vec2(256.3,220.5),vec2(261.5,223),vec2(266.7,221.4),vec2(271.8,220.9),vec2(277.4,221.8),vec2(280.7,224.7),vec2(286,229),vec2(290.7,225.2),vec2(289.9,219.1),vec2(281.5,215.1),vec2(277.4,212.9),vec2(271.8,207.2),vec2(266.5,202.9),vec2(266.8,197.4),vec2(271.2,196.4),vec2(268.2,193.6),vec2(261.2,194.3),vec2(258.1,195),vec2(253.4,190.8),vec2(245.1,183.6),vec2(239.3,181.5),vec2(244.2,190.7),vec2(235.9,191.7),vec2(231.3,191.9),vec2(223.2,190.3),vec2(208.2,190.1),vec2(197.2,189.3),vec2(203.2,191.2),vec2(214.7,194.8),vec2(221.2,198.4),vec2(208.2,199.5),vec2(213.1,202.8),vec2(208.2,207.6),vec2(201.5,224.4),vec2(210.7,221.1),vec2(219.6,213.3),vec2(215.6,221.5),vec2(211.5,235.4),vec2(211.5,242),vec2(217.2,248.8),vec2(219.6,246.5),vec2(222.8,235.4),vec2(226.7,237.3),vec2(236.8,246.5),vec2(250.5,253.1),vec2(257.3,254),vec2(262.5,253.3),vec2(272.9,260.9),vec2(271.4,266.2),vec2(275.1,268.4),vec2(278,263.2),vec2(276.6,269.9),vec2(266.9,274.3),vec2(263.2,275.8),vec2(267.3,277.3),vec2(261.7,281),vec2(250.9,281),vec2(249,275),vec2(250.5,266),vec2(246.4,267.5),vec2(242.2,270.4),vec2(236.1,271.9),vec2(235.3,266.5),vec2(226.7,267.9),vec2(231.4,261.1),vec2(238.4,255.9),vec2(235.3,255.4),vec2(217.2,263.8),vec2(207.3,273.7),vec2(201.5,283.9),vec2(197.2,294.7),vec2(196.3,306.3),vec2(203.2,309.3),vec2(203.2,300.1),vec2(204.8,291),vec2(209.8,291.7),vec2(210.7,284.7),vec2(222,281.2),vec2(228.3,279.4),vec2(235.3,284),vec2(233,287),vec2(228.3,290),vec2(231.4,293.1),vec2(229.1,295.4),vec2(223.6,297),vec2(227.1,297.7),vec2(236.5,297.6),vec2(240.7,293.7),vec2(245.2,288.5),vec2(249,288.4),vec2(253.5,290.7),vec2(246.8,298.9),vec2(243.3,303.5),vec2(240.7,310.4))
        for (I=1, SSymbol_Graph:count()) {
            SSymbol_Graph[I,vector2]=(SSymbol_Graph[I,vector2]+Offset)*Scale
        }
        #248 250
        Scr:egpPolyOutline(ID,SSymbol_Graph)
    }
    
    timer("QueueHandler",1000)
}

switch(Menu) {
    case 0,
        if (Draw) {
            sexybg(Scr)
            Scr:egpBox(1,vec2(256),vec2(512,60))
            Scr:egpColor(1,vec(128))
            Scr:egpText(2,"Tetranet Itembanking",vec2(256,246))
            Scr:egpText(3,"Trade TF2 Items for RP Cash",vec2(256,266))
            Scr:egpAlign(2,1,1)
            Scr:egpAlign(3,1,0)
            Scr:egpSize(2,40)
            
        }
        findByClass("player")
        User=findClosest(Scr:entity():pos())
        if (Use) {
            Menu=1
            UserID=User:steamID()
            if (Global[UserID,table]["Active",number]==0) {
                Global[UserID,table]=
                table(
                    "Active"=1,
                    "Name"=User:name(),
                    "SteamID"=UserID,
                    "Credit"=0,
                    "Queued"=0,
                    "Transactions"=0,
                    "Paid"=0,
                    "Color"=getStringColor(UserID),
                    "History"=table()
                )
            }
        }
    break
    
    case 1,
        if (Draw) {
            local Chars=array(
                "console/characters/xms2011_heavy",
                "console/characters/hwn_soldier",
                "console/characters/fwk_sniper",
                "console/characters/fwk_demoman",
                "console/characters/fwk_engineer"
            )
            Scr:egpBox(15,vec2(256,240),vec2(480))
            Scr:egpMaterial(15,Chars[randint(Chars:count()),string])
            Scr:egpAlpha(15,0)
            
            local Lines=4
            local Dist=512/Lines
            for (I=1, Lines+2) {
                Scr:egpLine(I+200,vec2(Dist*(I-2),-5),vec2(Dist*I,517))
                Scr:egpSize(I+200,30)
                Scr:egpMaterial(I+200,"gui/gradient_down")
                Scr:egpColor(I+200,vec(32))
            }
            
            
            Scr:egpBox(1,vec2(256,32),vec2(512,64))
            Scr:egpColor(1,vec(215,215,230))
            Scr:egpBox(2,vec2(256,512-128),vec2(512,256))
            Scr:egpColor(2,vec(215,215,230))
            Scr:egpBox(3,vec2(256,512-128),vec2(512,256))
            Scr:egpMaterial(3,"gui/gradient_up")
            Scr:egpColor(3,vec(200,200,210))
            Scr:egpBox(4,vec2(256,512-128),vec2(256,512))
            Scr:egpAngle(4,90)
            #Scr:egpMaterial(4,"gui/gradient_up")
            Scr:egpColor(4,vec(200,200,210))
            Scr:egpCopy(4,5)
            Scr:egpMaterial(5,"gui/gradient_up")
            Scr:egpColor(5,vec(180))
            Scr:egpText(11,"tetranet",vec2(10,45))
            Scr:egpAlign(11,0,1)
            Scr:egpSize(11,30)
            Scr:egpColor(11,vec(32,128,128))
            Scr:egpBox(12,vec2(256,192),vec2(512,128))
            Scr:egpMaterial(12,"gui/gradient_up")
            Scr:egpColor(12,vec(0))
            Scr:egpBox(13,vec2(256,256),vec2(512,10))
            Scr:egpColor(13,vec(180))
            Scr:egpBox(14,vec2(256,64),vec2(512,10))
            Scr:egpColor(14,vec(180))
            Scr:egpCircle(16,vec2(256,230),vec2(8))
            Scr:egpCircle(17,vec2(256-32,230),vec2(8))
            Scr:egpCircle(18,vec2(256+32,230),vec2(8))
            Scr:egpFidelity(16,100)
            Scr:egpFidelity(17,100)
            Scr:egpFidelity(18,100)
            
            function scroll01() {
                Scr:egpText(20,"Welcome to Tetranet",vec2(32,160))
                Scr:egpAlign(20,0,1)
                Scr:egpSize(20,30)
                Scr:egpText(21,"The reliable itembanker",vec2(32,175))
                Val["ScrollEnd",array]=array(15,20,21)
                foreach(I,V:number=Val["ScrollEnd",array]) {Scr:egpAlpha(V,0)}
                
                Scr:egpColor(17,vec(255,128,0))
                Scr:egpColor(16,vec(255))
                Scr:egpColor(18,vec(255))
                timer("Autofade",0)
            }
            
            function scroll02() {
                Scr:egpRoundedBox(22,vec2(128,165),vec2(128,80))
                Scr:egpColor(22,vec(128))
                Scr:egpRoundedBox(23,vec2(128,160),vec2(128,80))
                Scr:egpColor(23,vec(200,200,210))
                Scr:egpRoundedBox(24,vec2(128,160),vec2(128,80))
                Scr:egpColor(24,vec(180))
                Scr:egpMaterial(24,"gui/gradient_down")
                Scr:egpText(25,""+Global["Completed",number],vec2(128,170))
                Scr:egpColor(25,vec(128,255,255))
                Scr:egpFont(25,"Arial")
                Scr:egpSize(25,40)
                Scr:egpText(26,"Completed",vec2(128,180))
                Scr:egpColor(26,vec(1))
                Scr:egpAlign(25,1,2)
                Scr:egpAlign(26,1,1)
                
                Scr:egpText(27,"Safe, easy trading",vec2(512-32,140))
                Scr:egpSize(27,30)
                Scr:egpAlign(27,2,1)
                Scr:egpText(28,"Tetranet runs on four languages",vec2(512-32,165))
                Scr:egpAlign(28,2,1)
                Scr:egpText(29,"to bring you the best experience.",vec2(512-32,180))
                Scr:egpAlign(29,2,1)
                
                Val["ScrollEnd",array]=array(22,23,24,25,26,27,28,29)
                 foreach(I,V:number=Val["ScrollEnd",array]) {Scr:egpAlpha(V,0)}
                
                Scr:egpColor(17,vec(255))
                Scr:egpColor(16,vec(255,128,0))
                Scr:egpColor(18,vec(255))
                timer("Autofade",0)
            }
            
            function scroll03() {
                Scr:egpRoundedBox(30,vec2(128,165),vec2(128,80))
                Scr:egpColor(30,vec(128))
                Scr:egpRoundedBox(31,vec2(128,160),vec2(128,80))
                Scr:egpColor(31,vec(200,200,210))
                Scr:egpRoundedBox(32,vec2(128,160),vec2(128,80))
                Scr:egpColor(32,vec(180))
                Scr:egpMaterial(32,"gui/gradient_down")
                Scr:egpText(33,"$"+prettyInt(Global["Paid",number]),vec2(128,170))
                Scr:egpColor(33,vec(64,255,64))
                Scr:egpFont(33,"Arial")
                Scr:egpSize(33,30)
                Scr:egpText(34,"Paid Out",vec2(128,180))
                Scr:egpColor(34,vec(1))
                Scr:egpAlign(33,1,2)
                Scr:egpAlign(34,1,1)
                Scr:egpText(35,"Get paid on the spot.",vec2(512-32,140))
                Scr:egpSize(35,30)
                Scr:egpAlign(35,2,1)
                Scr:egpText(36,"If something goes wrong,",vec2(512-32,165))
                Scr:egpAlign(36,2,1)
                Scr:egpText(37,"we'll pay you even more.",vec2(512-32,180))
                Scr:egpAlign(37,2,1)
                
                Val["ScrollEnd",array]=array(30,31,32,33,34,35,36,37)
                foreach(I,V:number=Val["ScrollEnd",array]) {Scr:egpAlpha(V,0)}
                
                Scr:egpColor(16,vec(255))
                Scr:egpColor(17,vec(255))
                Scr:egpColor(18,vec(255,128,0))
                timer("Autofade",0)
            }
            scroll01()
            scroll02()
            scroll03()
            
            Scr:egpBox(100,vec2(450),vec2(0))
            sSymbol(101,vec2(188,140),0.8)
            Scr:egpColor(101,vec(255,255,0))
            Scr:egpParent(101,100)
            local Queued=Global[UserID,table]["Queued",number]
            
            Scr:egpRoundedBox(50,vec2(256,305),vec2(256,64))
            Scr:egpColor(50,!Queued ? vec(0,128,0) : vec(128))
            Scr:egpRoundedBox(51,vec2(256,300),vec2(256,64))
            Scr:egpColor(51, !Queued ? vec(64,172,64) : vec(215))
            Scr:egpText(52,Queued ? "Queued" : "Join Queue",vec2(256,300))
            Scr:egpSize(52,40)
            Scr:egpAlign(52,1,1)
            Scr:egpColor(52, !Queued ? vec(255) : vec(1))
            Scr:egpFont(52,"Arial")
            
            Scr:egpText(53,format("Rate: $%s/ref",prettyInt(Rate)),vec2(256,356))
            Scr:egpSize(53,30)
            Scr:egpAlign(53,1,1)
            
            Val["Scroller",array]=array("scroll01","scroll02","scroll03")
            Val["Curscroll",number]=0
            timer("Autoscroll",0)
        }
        
        if (pIR(51) & !Global[UserID,table]["Queued",number]) {
            Scr:egpColor(51,vec(0,200,0))
            if (Use) {
                Global[UserID,table]["Queued",number]=1
                Global["Queue",table]:pushArray(array(UserID,User:name()))
                Scr:egpPos(51,Scr:egpPos(50))
                Scr:egpPos(52,Scr:egpPos(50))
                timer("popout",100)
            }
        } elseif (!Global[UserID,table]["Queued",number]) {
            Scr:egpColor(51,vec(0,172,0))
            local Queued=Global[UserID,table]["Queued",number]
            Scr:egpColor(50,!Queued ? vec(0,128,0) : vec(128))
            Scr:egpColor(52, !Queued ? vec(255) : vec(1))
            Scr:egpSetText(52, Queued ? "Queued" : "Join Queue")
        }
        
        if (clk("popout")) {
            Scr:egpPos(51,vec2(256,300))
            Scr:egpPos(52,Scr:egpPos(51))
            
            local Queued=Global[UserID,table]["Queued",number]
            Scr:egpColor(50,!Queued ? vec(0,128,0) : vec(128))
            Scr:egpColor(51, !Queued ? vec(64,172,64) : vec(215))
            Scr:egpColor(52, !Queued ? vec(255) : vec(1))
            Scr:egpSetText(52, Queued ? "Queued" : "Join Queue")
        }
        
        if (clk("Autoscroll")) {
            Val["Curscroll",number]=Val["Curscroll",number]+1
            if (Val["Curscroll",number]>Val["Scroller",array]:count()) {
                Val["Curscroll",number]=1
            }
            Val["Scroller",array][Val["Curscroll",number],string]()
            timer("Autoscroll",10000)
        }
        
        if (clk("Autofade")) {
            for (I=1, Val["ScrollIndex",array]:count()) {
                Scr:egpAlpha(Val["ScrollIndex",array][I,number],255)
            }
            for (I=1, Val["ScrollEnd",array]:count()) {
                Scr:egpAlpha(Val["ScrollEnd",array][I,number],0)
            }
            Val["FadeState",number]=0
            timer("fadeanim",100)
        }
        
        if (clk("fadeanim")&Val["FadeState",number]<100) {
            Val["FadeState",number]=Val["FadeState",number]+5
            local Fade=Val["FadeState",number]
            local FadeOut=Fade/100 * (0-255) + 255
            local FadeIn=Fade/100 * (255-0)
            for (I=1, Val["ScrollIndex",array]:count()) {
                Scr:egpAlpha(Val["ScrollIndex",array][I,number],FadeOut)
            }
            for (I=1, Val["ScrollEnd",array]:count()) {
                Scr:egpAlpha(Val["ScrollEnd",array][I,number],FadeIn)
            }
            if (Fade==100) {
                Val["ScrollIndex",array]=Val["ScrollEnd",array]
            } else {
                timer("fadeanim",100)
            }
        }
    break
    
}

if (User & User:pos():distance(Scr:entity():pos())>120) {
    User=noentity()
    Menu=0
}

runOnHTTP(1)
if (clk("QueueHandler")) {
    timer("QueueHandler",1000)
    if (Global["Queue",table]:count()>0) {
        if (!Global["Ongoing",number]) {
            if (httpCanRequest()) {
                Global["CurrentID",string]=Global["Queue",table][1,array][1,string]
                Global["Ongoing",number]=1
                #httpRequest(BaseURL+"request&id="+Global["CurrentID",string])
                say("Queued "+Global["Queue",table][1,array][2,string])
            }
        } elseif (Global["CurrentID",string]) {
            if (httpCanRequest()) {
                #say("Checking "+Global["CurrentID",string])
                httpRequest(BaseURL+"confirm&id="+Global["CurrentID",string])
            }
        }
    }
}

if (httpClk() & httpRequestUrl()==BaseURL+"confirm&id="+Global["CurrentID",string]) {
    local Data=httpData()
    if (Data!="-1") {
        if (Data:sub(1,4)=="Err_") {
            local Error=Data:sub(5)
            say("Error: "+Error)
        } else {
            local Value=Data:toNumber()
            say("Received "+Value+" refined in items for "+Global["CurrentID",string])
            Global[Global["CurrentID",string],table]["Credit",number]=Global[Global["CurrentID",string],table]["Credit",number]+ceil(Value*Rate)
            Global[Global["CurrentID",string],table]["Transactions",number]=Global[Global["CurrentID",string],table]["Transactions",number]+1
            Global["Completed",number]=Global["Completed",number]+1
        }
        Global[Global["CurrentID",string],table]["Queued",number]=0
        Global:removeNumber("Ongoing")
        Global:removeString("CurrentID")
        Global["Queue",table]:removeArray(1)
    }
}

local Credit=Global[UserID,table]["Credit",number]
if (Credit>0) {
    Eject=clamp(Credit,0,MaxEject)
    Global[UserID,table]["Credit",number]=Global[UserID,table]["Credit",number]-Eject
    Global[UserID,table]["Paid",number]=Global[UserID,table]["Paid",number]+Eject
    Global["Paid",number]=Global["Paid",number]+Eject
}
