--// All global vars will be wiped/replaced except script

return function(data)
	local playergui = service.PlayerGui
	local localplayer = service.Players.LocalPlayer
	local gui = script.Parent.Parent
	local frame = gui.Frame
	--local cont = gui.Frame.Container
	
	local termCont = frame.termCont
	local serverCont = frame.serverCont
	local localCont = frame.localCont
	local logsCont = frame.logsCont
	local scriptCont = frame.scriptCont
	local errorCont = frame.errorCont
	
	local localTab = frame.localTab
	local scriptTab = frame.scriptTab
	local logsTab = frame.logsTab
	local termTab = frame.termTab
	local serverTab = frame.serverTab
	local errorTab = frame.errorTab
	
	local close = gui.Frame.Close
	local box = gui.Frame.Command
	local name = gui.Frame.Nameb
	local dragger = gui.Frame.Dragger
	local entry = gui.Entry
	
	local termLines = {}
	local localLines = {}
	local serverLines = {}
	local logsLines = {}
	local scriptLines = {}
	local errorLines = {}
	
	local function openLocal()
		localCont.Visible = true
		scriptCont.Visible = false
		logsCont.Visible = false
		termCont.Visible = false
		serverCont.Visible = false
		errorCont.Visible = false
		
		localTab.BackgroundTransparency = 0
		scriptTab.BackgroundTransparency = 0.5
		logsTab.BackgroundTransparency = 0.5
		termTab.BackgroundTransparency = 0.5
		serverTab.BackgroundTransparency = 0.5
		errorTab.BackgroundTransparency = 0.5
	end
	
	local function openScript()
		localCont.Visible = false
		scriptCont.Visible = true
		logsCont.Visible = false
		termCont.Visible = false
		serverCont.Visible = false
		errorCont.Visible = false
		
		localTab.BackgroundTransparency = 0.5
		scriptTab.BackgroundTransparency = 0
		logsTab.BackgroundTransparency = 0.5
		termTab.BackgroundTransparency = 0.5
		serverTab.BackgroundTransparency = 0.5
		errorTab.BackgroundTransparency = 0.5
	end
	
	local function openLogs()
		localCont.Visible = false
		scriptCont.Visible = false
		logsCont.Visible = true
		termCont.Visible = false
		serverCont.Visible = false
		errorCont.Visible = false
		
		localTab.BackgroundTransparency = 0.5
		scriptTab.BackgroundTransparency = 0.5
		logsTab.BackgroundTransparency = 0
		termTab.BackgroundTransparency = 0.5
		serverTab.BackgroundTransparency = 0.5
		errorTab.BackgroundTransparency = 0.5
	end
	
	local function openTerm()
		localCont.Visible = false
		scriptCont.Visible = false
		logsCont.Visible = false
		termCont.Visible = true
		serverCont.Visible = false
		errorCont.Visible = false
		
		localTab.BackgroundTransparency = 0.5
		scriptTab.BackgroundTransparency = 0.5
		logsTab.BackgroundTransparency = 0.5
		termTab.BackgroundTransparency = 0
		serverTab.BackgroundTransparency = 0.5
		errorTab.BackgroundTransparency = 0.5
	end
	
	local function openServer()
		localCont.Visible = false
		scriptCont.Visible = false
		logsCont.Visible = false
		termCont.Visible = false
		serverCont.Visible = true
		errorCont.Visible = false
		
		localTab.BackgroundTransparency = 0.5
		scriptTab.BackgroundTransparency = 0.5
		logsTab.BackgroundTransparency = 0.5
		termTab.BackgroundTransparency = 0.5
		serverTab.BackgroundTransparency = 0
		errorTab.BackgroundTransparency = 0.5
	end
	
	local function openErrors()
		localCont.Visible = false
		scriptCont.Visible = false
		logsCont.Visible = false
		termCont.Visible = false
		serverCont.Visible = false
		errorCont.Visible = true
		
		localTab.BackgroundTransparency = 0.5
		scriptTab.BackgroundTransparency = 0.5
		logsTab.BackgroundTransparency = 0.5
		termTab.BackgroundTransparency = 0.5
		serverTab.BackgroundTransparency = 0.5
		errorTab.BackgroundTransparency = 0
	end
	
	local function populate(cont,lines)
		cont:ClearAllChildren()
		
		local num = 0
		for i,v in next,lines do
			local new,text,color = entry:Clone()
			
			if type(v) == "table" then
				text = v.Text
				color = v.Color
			else
				text = tostring(v)
			end			
			
			new.Visible = true
			new.Text = tostring(text)
			new.Position = UDim2.new(0,0,0,num*20)
			new.Parent = cont
			new.TextColor3 = color or new.TextColor3
			num = num+1
		end
		
		cont.CanvasSize = UDim2.new(0, 0, 0, (num*20))
		local glob = ((num*20) - cont.AbsoluteWindowSize.Y)
		if glob<0 then glob=0 end
		cont.CanvasPosition = Vector2.new(0,glob)
	end
	
	local function populateAll()
		populate(scriptCont,scriptLines)
		populate(logsCont,logsLines)
		populate(serverCont,serverLines)
		populate(termCont,termLines)
		populate(localCont,localLines)
		populate(errorCont,errorLines)
	end
	
	--name.Text = localplayer.userId.."@"..game.PlaceId.." ;/>"
	
	local function out(put,lines)
		table.insert(lines,put)
		if #lines>500 then
			table.remove(lines,1)
		end
	end
	
	local function formatOutput(tab)
		local new = {}
		for i,v in next,tab do
			if type(v) == "table" then
				local typ,color = v.messageType
				if typ == "Error" then
					color = Color3.new(1,0,0)
				elseif typ == "Info" then
					color = Color3.new(0,0,1)
				elseif typ == "Warning" then
					color = Color3.new(0,1,1)
				end
				
				table.insert(new,{
					Text = v.message;
					Color = color;
				})
			else
				table.insert(new,tostring(v))
			end
		end
		return new
	end
	
	local function formatLogs(tab)
		local new = {}
		for i,v in next,tab do
			if type(v) == "table" then
				table.insert(new,{
					Text = tostring(v.Text)..": "..tostring(v.Desc);
				})
			else
				table.insert(new,tostring(v))
			end
		end
		return new
	end
	
	service.Events.TerminalLive:connect(function(rData)
		local data = rData.Data
		local rType = rData.Type
		
		out(data,termLines)
		populate(termCont,termLines)
	end)
	
	local updater = service.StartLoop("TerminalLoop",1,function() 
		service.Debounce("_TERMINAL_UPDATING",function()
			local data = client.Remote.Get("TerminalData")
			
			--termLines = data.Output
			serverLines = formatOutput(data.ServerLogs or {})
			logsLines = formatLogs(data.AdminLogs or {})
			scriptLines = formatLogs(data.ScriptLogs or {})
			errorLines = formatLogs(data.ErrorLogs or {})
			localLines = formatOutput(service.LogService:GetLogHistory() or {})
			
			--populate(termCont,termLines)
			populate(scriptCont,scriptLines)
			populate(logsCont,logsLines)
			populate(errorCont,errorLines)
			populate(serverCont,serverLines)
			populate(localCont,localLines)
		end)
	end,true)
	
	box.FocusLost:connect(function(enterPressed)
		service.Debounce("_TERMINAL_BOX_FOCUSLOST",function()
			wait(0.1)
			if enterPressed and box.Text~="" then
				local com = box.Text
				box.Text = ""
				out(">"..com,termLines)
				populate(termCont,termLines)
				local ret = client.Remote.Get("Terminal",com,{
					Time = tick();
				})
				if ret and type(ret) == "table" then
					for i,ent in next,ret do
						out(ent,termLines)
					end
					populate(termCont,termLines)
				end
				box:CaptureFocus()
				box.Text = ""
			end
		end)
	end)
	
	close.MouseButton1Click:connect(function()
		updater:Kill()
		client.Remote.Send("Session","Terminal",false) 
		out("Disconnecting session...",termLines)
		populate(termCont,termLines)
		wait(0.5)
		gui:Destroy() 
	end)
	
	localTab.MouseButton1Down:connect(openLocal)
	scriptTab.MouseButton1Down:connect(openScript)
	logsTab.MouseButton1Down:connect(openLogs)
	termTab.MouseButton1Down:connect(openTerm)
	serverTab.MouseButton1Down:connect(openServer)
	errorTab.MouseButton1Down:connect(openErrors)
	
	local mouse=service.Players.LocalPlayer:GetMouse()
	local nx,ny=frame.AbsoluteSize.X,frame.AbsoluteSize.Y--500,300
	local dragging=false
	local defx,defy=nx,ny
	mouse.Move:connect(function(x,y) 
		if dragging then
			nx=defx+(dragger.Position.X.Offset+20)
			ny=defy+(dragger.Position.Y.Offset+20)
			if nx<300 then nx=300 end
			if ny<200 then ny=200 end
			frame.Size=UDim2.new(0, nx, 0, ny) 
		end
	end)
	dragger.DragBegin:connect(function(init)
		dragging = true
		frame.Active = false
	end)
	dragger.DragStopped:connect(function(x,y)
		frame.Active = true
		dragging = false
		defx = nx
		defy = ny
		dragger.Position = UDim2.new(1,-20,1,-20)
		populateAll()
	end)
	
	populateAll()
	gTable:Ready()
end