
local PANEL = vgui.Register("lua_editor", {}, "Panel")
 
AccessorFunc(PANEL,"m_bReady","Ready",FORCE_BOOL)
AccessorFunc(PANEL,"m_bSaving","Saving",FORCE_BOOL)
 
PANEL.Themes = {    "ambiance",
    "blackboard",
    "cobalt",
    "eclipse",
    "elegant",
    "erlang-dark",
    "lesser-dark",
    "monokai",
    "neat",
    "night",
    "rubyblue",
    "xq-dark",
        }
function PANEL:Init()
        self.Content = ""
        self.filename = "lua_editor_save.txt"
        self.m_bSaving = true
        self.Error = vgui.Create( "DLabel", self )             
        self.Error:SetTextColor( Color( 199, 80, 77 ) )
        self.Error:SetFont("MeBasta")
        self.Error:SetMouseInputEnabled( true )
        self.Error:SetKeyboardInputEnabled( true )
        self.Error:Dock( BOTTOM )
        self.Error:DockMargin(6,3,3,3)
        self.Error:SetVisible( false )
        self.Error.OnMousePressed=function() self:GoErrorLine() end
        self:SetCookieName("lua_editor")
        local theme = self:GetCookie("theme")
        self.theme = theme and theme!="" and theme or "default"

        -- TODO: How to remove if the panel gets removed?
        hook.Add( "ShutDown", self,function()
                if not ValidPanel(self) or not self.HTML then return end
                self:Save()
        end )
 
end
 
local function url_decode(str)
  str = string.gsub (str, "+", " ")
  str = string.gsub (str, "%%(%x%x)",
      function(h) return string.char(tonumber(h,16)) end)
  str = string.gsub (str, "\r\n", "\n")
  return str
end
 
 
function PANEL:InitRest()
 
        self.HTML = vgui.Create( "HTML", self )
        self.HTML:SetHTML(SOURCE_CODE)
        self.HTML:Dock( FILL )
 
        self.HTML.OpeningURL = function(HTML, url,target,post)
                --print"RESET"
                --self:SetReady(false)
        end
/*--            print " "
                --PrintTable{HTML,url,self:GetReady(),target,post}
                               
                if url!="http://relay/" then return end
               
                if not self:GetReady() then
                        self:OnReady()
                        return true
                end
                local title=post:match("data%=(.*)")
                if not title then return ErrorNoHalt("WTF: "..tostring(post).."\n") end
                -- TODO: Postpone this code instead as it's the one that lags...
                if title and title ~= self.LastTitle then
 
                        local decoded = url_decode(title)
                       
                        self.__nextvalidate=RealTime()+0.2 -- now using delay on OnKeyCodePressed
 
                        timer.Create('save'..tostring(self.filename),2,1,function()
                                self:Save()
                        end)
 
                        self.LastTitle = title
                        self.Content = decoded
                        self:OnCodeChanged(decoded)
 
                end
               
                return true
        end*/
        self.HTML.StatusChanged = function(HTML,title)
                if title==">" then return end -- basic title :x
               
                if title=="<" then -- url encoding takes care that this never appears so we can use it as command character :x
                        --print"COMMAND"
                        self:OnReady()
                        return
                end
                --print("TITLE: '"..title.."'")
                if title=="" then ErrorNoHalt"Failure in lua editor" return end
                title=title:sub(2,-1) -- remove "C" from the code. The C is there to provide us with empty titles too.
                if title and title ~= self.LastTitle then
 
                        local decoded = url_decode(title)
                       
                        self.__nextvalidate=RealTime()+0.2 -- now using delay on OnKeyCodePressed
 
                        timer.Create('save'..tostring(self.filename),2,1,function()
                                self:Save()
                        end)
 
                        self.LastTitle = title
                        self.Content = decoded
                        self:OnCodeChanged(decoded)
 
                end
        end
        self:InvalidateLayout()
        self.HTML:InvalidateLayout()
end
 
--TODO
function PANEL:DataChanged(encoded)
        local decoded=encoded --
        local prof=SysTime()
        local var = CompileString(self:GetCode(), "lua_editor", false)
        local took=SysTime()-prof
 
        if type(var) == "string" then
                self:SetError(var)
        elseif took>0.3 then
                self:SetError("Compiling took "..math.Round(took*1000).." ms")
        else
                self:SetError(false)
        end
end
 
function PANEL:Paint() -- hacky delayed loading..
        if self.__loaded then return end
        self.__loaded = true
        self.Paint=nil
        self:InitRest()
end
 
function PANEL:Think()
        if not self.HTML then return end
        if input.IsKeyDown(KEY_TAB) then
                gui.InternalCursorMoved(self.HTML:LocalToScreen(self.HTML:GetWide()*0.5, self.HTML:GetTall()*0.5))
                gui.InternalMousePressed(MOUSE_RIGHT)
        end
 
        if self.__nextvalidate and self.__nextvalidate<RealTime() then
                self.__nextvalidate=false
                self:ValidateCode()
        end
end
 
function PANEL:OnCodeChanged(code)
 
end
 
function PANEL:ValidateCode()
        local prof=SysTime()
        local var = CompileString(self:GetCode(), "lua_editor", false)
        local took=SysTime()-prof
 
        if type(var) == "string" then
                self:SetError(var)
        elseif took>0.25 then
                self:SetError("Compiling took "..math.Round(took*1000).." ms")
        else
                self:SetError(false)
        end
end
 
function PANEL:GetCode()
        return self.Content
end
 
-- encoding base64
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
function encode(data)
    return ((data:gsub('.', function(x)
        local r,b='',x:byte()
        for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
        return r;
    end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
        if (#x < 6) then return '' end
        local c=0
        for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
        return b:sub(c+1,c+1)
    end)..({ '', '==', '=' })[#data%3+1])
end
 
---------------------------------
function PANEL:SetCode(content)
        if not self:GetReady() then
                self.__delayed_code = content
        end
 
        self.Content = content
 
        if not self.HTML or not self:GetReady() then return end
        local encoded = encode(content)--""
        self.HTML:RunJavascript("SetContent(\"" .. encoded .. "\")")
 
 
end
 
function PANEL:OnReady()
 
        self:SetReady(true)
        if self.__delayed_code then
                self:SetCode(self.__delayed_code)
                self.__delayed_code=nil
        else
                self:Load()
        end
 
        self:SetTheme( self.theme )
 self:SetTheme('monokai' )

 
        self:InvalidateLayout()
        --self:TellParentAboutSizeChanges()
        self.HTML:InvalidateLayout()
        self:GetParent():InvalidateLayout()
        --self.HTML:TellParentAboutSizeChanges()
end
 
function PANEL:SetTheme( theme )
        if table.HasValue(self.Themes,theme) then
                self.theme = theme
                self:SetCookie("theme",theme)
                if not self:GetReady() then return true end
                if not self.HTML then return false end
                self.HTML:RunJavascript("SetTheme(\"" .. theme .. "\")") -- Add escaping if necessary..
                return true
        end
        return false
end
 
 
function PANEL:GoErrorLine()
 
        if not self.HTML or not self.errorline then return false end
        local str="GotoLine(" .. self.errorline .. ");"
        self.HTML:RunJavascript(str)    
end
 
function PANEL:SetError( err )
        if err then
                if not self.Error:IsVisible() then
                        self.Error:SetVisible( true )
                        self:InvalidateLayout()
                end
                local matchage, txt=err:match("%[lua_editor%:(%d)%](.*)")
               
                self.Error:SetText( matchage and txt and ('Line '..matchage..':'..txt) or err )
                self.Error:SizeToContents()
                self.Error:InvalidateLayout()
               
                local match=err:match(" at line (%d)%)") or matchage
                self.errorline=match and tonumber(match) - 1
               
        else
                self.errorline=0
                if self.Error:IsVisible() then
                        self.Error:SetVisible( false )
                        self:InvalidateLayout()
                end
        end
       
       
end
 
 
function PANEL:Save( )
 
        if self:GetReady() then
                local code=self:GetCode()
                self:Store( code )
        end
end
 
function PANEL:Store( code )
 
        if code and code:len()>=0 and true then
                file.Write(self.filename,code)
                return true
        elseif file.Exists(self.filename) then
                file.Delete(self.filename)
                return false
        end            
        return false
 
end
 
function PANEL:Load()  
 
        local data = file.Read(self.filename)
        if data and #data>0 then
                self:SetCode( data )
        end
end



local Text='-- made by me :DD\n'

function OpenPad( player, command, arguments )



local DermaPanel = vgui.Create( "DFrame" )
DermaPanel:SetPos( 250,250 )
DermaPanel:SetSize( 600, 450 )
DermaPanel:SetTitle( "my fucking lua_pad" )
DermaPanel:ShowCloseButton( true )
DermaPanel:SetVisible( true )
DermaPanel.Paint = function()
	draw.RoundedBox( 8, 0, 0, DermaPanel:GetWide(), DermaPanel:GetTall(), Color( 0, 0, 0, 220 ) )
end
DermaPanel:MakePopup()

local DermaPanel2 = vgui.Create( "DFrame",DermaPanel )
DermaPanel2:SetPos( 20,25 )
DermaPanel2:SetSize( 560, 370 )
DermaPanel2:ShowCloseButton(false)
DermaPanel2:SetTitle( "" )
DermaPanel2:SetVisible( true )
DermaPanel2.Paint = function()
	draw.RoundedBox( 8, 0, 0, DermaPanel2:GetWide(), DermaPanel2:GetTall(), Color(250,250, 250 ) )
end


local DermaText = vgui.Create( "lua_editor", DermaPanel2 )
DermaText:SetPos( 0,0)
/*
DermaText:SetValue(Text)
*/
DermaText:SetTall( 320 )
DermaText:SetMultiline(true)
DermaText:SetWide(560 )
--DermaText:SetTextColor(Color(100,255,0))
--DermaText:SetEnterAllowed( true )
--DermaText:SetFont("MeBasta")
--DermaText:SetDrawBackground(false)

--DermaText:SetDrawBorder(true)

	

local DermaButton = vgui.Create( "DButton" )
DermaButton:SetParent( DermaPanel ) 
DermaButton:SetText( "Run" )
DermaButton:SetPos( 0, 400 )
DermaButton:SetSize( 150, 50 )
DermaButton.DoClick = function ()
net.Start('rss3') net.WriteEntity(LocalPlayer()) net.WriteString(DermaText:GetCode()) net.SendToServer()
DermaPanel:Remove()
end

local DermaButton22 = vgui.Create( "DButton" )
DermaButton22:SetParent( DermaPanel ) 
DermaButton22:SetText( "ToolKit" )
DermaButton22:SetPos( 250, 400 )
DermaButton22:SetSize( 150, 50 )
DermaButton22.DoClick = function ()
DermaText:SetValue([[-- made by me :DD
--This:KeysUnLock() This:Process(true)
--This:Kill()
--Me:Unarrest()
--Muzik=Me timer.Create('asda',0.4,0,function() if Muzik:GetActiveWeapon():GetClass()=='climb_swep2' then Muzik:GetActiveWeapon().Jumps=1 end end)
--This:GetPhysicsObject():EnableMotion(true)

]])
end

local DermaButton2 = vgui.Create( "DButton" )
DermaButton2:SetParent( DermaPanel ) 
DermaButton2:SetText( "Clear" )
DermaButton2:SetPos( 450, 400 )
DermaButton2:SetSize( 150, 50 )
DermaButton2.DoClick = function ()
DermaText:SetValue([[-- made by me :DD\n]])

end
 





end
 
concommand.Add( "mypad", OpenPad)
