local hwid = [[342387F8D6C0201A069D989008002700C49A{846ee340-7039-11de-9d20-806e6f6e6963}]];
local steamip = [[]];
print('***[M] - Loading');

print("***[D] - DEV");

dismay = dismay or {};
dismay.version = 8;
dismay.link = "";
dismay.private = dismay.private or {};

local function ReplaceG(index)
	dismay[index] = _G[index];
	_G[index] = nil;
end
local function ReplaceUN(index)
	dismay.private[index] = _G[index];
	_G[index] = nil;
end

ReplaceG	("SetIGN");
ReplaceG	("RunClient");
ReplaceG	("OpenClient");
ReplaceG	("RunMenu");
ReplaceG	("OpenMenu");
ReplaceG	("rversion");
ReplaceG	("CreateMenuItem");
ReplaceG	("RemoveMenuItem");
ReplaceG	("SetItemActive");
ReplaceG	("SetItemCallback");
ReplaceG	("SetItemName");
ReplaceG	("Paint");
ReplaceG	("LoadWebScript");

dismay.SpeedNum 	= 0;
dismay.SpeedKey 	= false;
dismay.SKey			= cookie.GetNumber("__skey", KEY_G);
dismay.AddHook 		= hook.Add;

local self;
self = dismay.CreateMenuItem("Change sh key", function(bOn)
	local a = vgui.Create("DFrame");
	hook.Add("DrawOverlay", "SpeedKey", function()
		draw.DrawText("Open Menu! (esc key)", "BudgetLabel", 2, 3, Color(255,0,255,255));
	end)
	function a:OnKeyCodePressed(key)
		dismay.SKey = key;
		cookie.Set("__skey", key);
		dismay.RunClient("dismay.SKey = "..tostring(key)..";");
		self:Remove();
		a:SetIsMenu(false);
	end
	function a:Think()
		self:RequestFocus();
	end
	a:SetSize(ScrW(), ScrH());
	a:MakePopup();
	a.self = self;
	function a:OnRemove()
		hook.Remove("DrawOverlay", "SpeedKey");
		dismay.SetItemActive(a.self, false);
	end
	dismay.SetItemActive(a.self, true);
end);
local self;
self = dismay.CreateMenuItem("Speedhack key", function(bOn)
	dismay.SpeedKey = bOn;
	dismay.RunClient("dismay.SpeedKey = "..tostring(bOn)..";");
	dismay.SetItemName(self, "Speedhack key");
end);
local self;
self = dismay.CreateMenuItem("Speedhack Speed (0)", function(bOn)
	if(dismay.SpeedNum > 20) then dismay.SpeedNum = -1; end
	dismay.SpeedNum = dismay.SpeedNum + 1;
	dismay.RunClient("dismay.SpeedNum = "..tostring(dismay.SpeedNum)..";");
	dismay.SetItemName(self, "Speedhack Speed ("..dismay.SpeedNum..")");
	dismay.SetItemActive(self, false);
end);

dismay.real_g = {};

dismay.metas = {};

local fetch = http.Fetch;
local abort = abort;

dismay.metas._G = {
	__index = function(self, k)
		if dismay.real_g[k] then return dismay.real_g[k]; end
	end;
	__newindex = function(self, k, v)
		if (string.find(string.lower(k), "g_")) then
			if (v == "") then
				return;
			end
			dismay.real_g[k] = v;
			return;
		end
	end;
};

setmetatable(_G, dismay.metas._G);

g_ServerName		= nil;
g_MapName		= nil;
g_ServerURL		= nil;
g_MaxPlayers		= nil;
g_SteamID		= nil;

dismay.adrsrvlist = {};
local adrsrvlist = dismay.adrsrvlist;
dismay.gmsrvlist = {};
local gmsrvlist = dismay.gmsrvlist;
dismay.nmsrvlist = {};
local nmsrvlist = dismay.nmsrvlist;

function GetServers(type, id)
	local data =
	{
		Finished = function()
		end,
		Callback = function( ping , name, desc, map, players, maxplayers, botplayers, pass, lastplayed, address, gamemode, workshopid )
			
			nmsrvlist[name] = {
				ping = ping;
				desc = desc;
				map = map;
				players = players;
				maxplayers = maxplayers;
				botplayers = botplayers;
				pass = pass and "true" or "false";
				lastplayed = lastplayed;
				address = address;
				gamemode = gamemode;
				workshopid = workshopid;
			}
			
			adrsrvlist[address] = {
				ping = ping;
				name = name;
				desc = desc;
				map = map;
				players = players;
				maxplayers = maxplayers;
				botplayers = botplayers;
				pass = pass and "true" or "false";
				lastplayed = lastplayed;
				address = address;
				gamemode = gamemode;
				workshopid = workshopid;
			}
			
			gmsrvlist[gamemode] = gmsrvlist or {};
			gmsrvlist[gamemode][address] = {
				ping = ping;
				name = name;
				desc = desc;
				map = map;
				players = players;
				maxplayers = maxplayers;
				botplayers = botplayers;
				pass = pass and "true" or "false";
				lastplayed = lastplayed;
				address = address;
				workshopid = workshopid;
			}
			
			name	= string.JavascriptSafe( name );
			desc	= string.JavascriptSafe( desc );
			map		= string.JavascriptSafe( map );
			address = string.JavascriptSafe( address );
			gamemode = string.JavascriptSafe( gamemode );
			workshopid = string.JavascriptSafe( workshopid );
			
			if (pass) then pass = "true" else pass = "false" end
			
			pnlMainMenu:Call("AddServer( '"..type.."', '"..id.."', "..ping..", \""..name.."\", \""..desc.."\", \""..map.."\", "..players..", "..maxplayers..", "..botplayers..", "..pass..", "..lastplayed..", \""..address.."\", \""..gamemode.."\", \""..workshopid.."\", 50 )");
			
		end,
		Type = type,
		GameDir = 'garrysmod',
		AppID = 4000,
	}
	serverlist.Query(data)	
end

function dismay.GetServersByName(name, bRemoveCurrent)
	local ret = {};
	for n, info in pairs(nmsrvlist) do
		if(string.find(string.lower(n), string.lower(name))) then
			ret[n] = info;
		end
	end
	if(bRemoveCurrent) then
		for k,v in pairs(ret) do
			if(v.address == dismay.LastJoin) then 
				ret[k] = nil;
			end
		end
	end
	return ret;
end

function dismay.GetServersByGamemode(gm)
	return gmsrvlist[gm];
end

local o = JoinServer;

function JoinServer(ip)
	dismay.LastJoin = ip;
	(dismay.OnJoinServer or function() end)(ip);
	return o(ip);
end
dismay.Panel = {};

function dismay.Panel:OnMousePressed()
	self:SetBeingPressed(true);
	local mx, my = input.GetCursorPos();
	local x, y = self:GetPos();
	self.OffX = mx - x;
	self.OffY = my - y;
end
function dismay.Panel:Think()
	if(self:GetDraggable() and self:GetBeingPressed() and not self:GetMinimized()) then
		if(input.IsMouseDown(MOUSE_LEFT)) then
			local mx, my = input.GetCursorPos();
			local rx = math.min(ScrW(), math.max(0, mx - self.OffX) + self:GetWide()) - self:GetWide();
			local ry = math.min(ScrH(), math.max(0, my - self.OffY) + self:GetTall()) - self:GetTall();
			self:SetPos(rx, ry);
		else
			self:SetBeingPressed(false);
		end
	end
	
	if(self:GetMinimized()) then
		if(not self:GetWasMinimized()) then
			local x, y = self:GetPos();
			local w, h = self:GetWide(), self:GetTall();
			local r = {
				x = x;
				y = y;
				w = w;
				h = h;
			};
			self.oldInfo = r;
			dismay.WindowList:AddPnl(self);
		end
		self.btnMaxim:SetDisabled(false);
		self.btnMinim:SetDisabled(true);
	else
		if(self:GetWasMinimized()) then
			self:SetPos(self.oldInfo.x, self.oldInfo.y);
			self:SetTall(self.oldInfo.h);
			self:SetWide(self.oldInfo.w);
			self.btnMaxim:SetDisabled(true);
			self.btnMinim:SetDisabled(false);
		end
	end
	self:SetWasMinimized(self:GetMinimized());
end

dismay.Panel.btnMaxim = {}
function dismay.Panel.btnMaxim:DoClick()
	self:GetParent():SetMinimized(false);
	dismay.WindowList:RemPnl(self:GetParent())
end
dismay.Panel.btnMinim = {}
function dismay.Panel.btnMinim:DoClick()
	self:GetParent():SetMinimized(true);
end

function dismay.Panel:Init()
	self.m_bMinimized = false;
	self.m_bWasMinimized = false;
	self.m_bIsBeingPressed = false;
	
	function self.GetMinimized(self) 
		return self.m_bMinimized;
	end
	
	function self.SetMinimized(self, b) 
		self.m_bMinimized = b;
	end
	
	function self.GetWasMinimized(self) 
		return self.m_bWasMinimized;
	end
	
	function self.SetWasMinimized(self, b) 
		self.m_bWasMinimized = b;
	end
	
	function self.GetBeingPressed(self) 
		return self.m_bIsBeingPressed;
	end
	
	function self.SetBeingPressed(self, b) 
		self.m_bIsBeingPressed = b;
	end
	
	self.btnClose:SetDisabled(true);
	
	self.btnMaxim.DoClick = dismay.Panel.btnMaxim.DoClick;
	
	self.btnMinim:SetDisabled(false);
	self.btnMinim.DoClick = dismay.Panel.btnMinim.DoClick;
end

local PANEL = {};

PANEL.m_pPanels = {};
PANEL.pWidth = 220;
PANEL.pHeight = 21;

function PANEL:AddPnl(pnl)
	table.insert(self.m_pPanels, pnl);
end
function PANEL:RemPnl(rpnl)
	for i, pnl in ipairs(self.m_pPanels) do
		if(pnl == rpnl) then
			table.remove(self.m_pPanels, i);
		end
	end
end
function PANEL:Think()
	local curx = 0;
	local width = math.min(self.pWidth, #self.m_pPanels > 0 and ScrW() / #self.m_pPanels or ScrW());
	for i, pnl in ipairs(self.m_pPanels) do
		if(not pnl or not IsValid(pnl)) then table.remove(self.m_pPanels, i); end
		local s, c = pcall(function()
			pnl:SetPos(curx, ScrH() - self.pHeight);
			pnl:SetTall(self.pHeight);
			pnl:SetWide(width);
			curx = curx + width;
		end)
		if(not s) then table.remove(self.m_pPanels,i); end
	end
end
function PANEL:Init()
	
end

vgui.Register("DWindowList", PANEL, "EditablePanel")
dismay.WindowList = vgui.Create("DWindowList");

local PANEL = {};

PANEL.colDev = Color(0,255,125,255);
PANEL.colOld = Color(255,0,0,255);
PANEL.colRel = Color(0,255,0,255);

function PANEL:Think()
end

function PANEL:Paint()
end

function PANEL:Init()
	if(dismay.version == dismay.rversion) then
		self.colCur = self.colRel;
		self.szExtra = "(Current)";
	elseif(dismay.version < dismay.rversion) then
		self.colCur = self.colDev;
		self.szExtra = "(Dev)";
	else
		self.colCur = self.colOld;
		self.szExtra = "(Old)\n"..dismay.link;
	end
	self:SetWide(ScrW() / 2);
	self:SetTall(40);
	self:SetPos(ScrW() / 2 - self:GetWide() / 2, 0);
	self:MakePopup();
	
	self.lbl1 = vgui.Create("DLabel", self);
	self.lbl1:SetFont("BudgetLabel");
	self.lbl1:SetText("DLL Version r"..dismay.rversion.." "..self.szExtra)
	self.lbl1:SizeToContents();
	self.lbl1:SetTextColor(self.colCur);
	self.lbl1:SetPos(self:GetWide() / 2 - self.lbl1:GetWide() / 2, 2);
end

vgui.Register("DVersionWin", PANEL, "EditablePanel")

dismay.VersionPanel = vgui.Create("DVersionWin");


dismay.LuaPanel = false
function dismay.CreateWindow()
	if(IsValid(dismay.LuaPanel)) then return; end
	dismay.LuaPanel = vgui.Create("DFrame");
	dismay.LuaPanel:SetSize(300, 200);
	dismay.LuaPanel:SetTitle("Lua Options");
	dismay.Panel.Init(dismay.LuaPanel);
	function dismay.LuaPanel:OnMousePressed()
		dismay.Panel.OnMousePressed(self);
	end
	function dismay.LuaPanel:Think()
		dismay.Panel.Think(self);
	end
	dismay.LuaPanel:Center()
	local t = vgui.Create("DTextEntry", dismay.LuaPanel);
	local b = vgui.Create("DComboBox", dismay.LuaPanel);
	b:SetValue("CL - Run");
	b:AddChoice("CL - Run");
	b:AddChoice("CL - Open");
	b:AddChoice("MN - Run");
	b:AddChoice("MN - Open");

	b.m_pFunc = dismay.RunClient;

	dismay.LuaPanel.m_pText = t;
	dismay.LuaPanel.m_pBox = b;

	function b:OnSelect(index, value, data)
		if(index == 1) then
			self.m_pFunc = dismay.RunClient;
		elseif(index == 2) then
			self.m_pFunc = dismay.OpenClient;
		elseif(index == 3) then
			self.m_pFunc = dismay.RunMenu;
		elseif(index == 4) then
			self.m_pFunc = dismay.OpenMenu;
		end
	end
	function b:Think()
		self:SetWide(self:GetParent():GetWide() * 3 / 4);
		self:SetPos(self:GetParent():GetWide() / 2 - self:GetWide() / 2, 30);
	end

	function t:Think()
		self:SetWide(self:GetParent():GetWide() * 2 / 3);
		self:SetTall(self:GetParent():GetTall() / 2);
		self:SetPos(self:GetParent():GetWide() / 2 - self:GetWide() / 2, self:GetParent():GetTall() / 2 - self:GetTall() / 2 + 30)
	end

	function t:OnEnter()
		self:GetParent().m_pBox.m_pFunc(self:GetValue());
	end

	dismay.LuaPanel:MakePopup();
end

hook.Add("DrawOverlay", "H", function()
	dismay.Paint();
end);


print("***[M] - Loaded");
MsgC(Color(200,100, 100,255),[[
*** - menu autorun file is C:\\dismay\\dismay_menu.lua
*** - Hit insert to toggle menu input. Up/Down arrows go up and down on the menu. 
*** - Hit the right arrow to toggle the option highlighted.
*** - G is speedhack key. Highlighted speedhack on top right is faster. (16 compared to 9 disabled)
]]);
if(dismay.version == dismay.rversion) then
	MsgC(Color(0,255,0,255), [[
[!] - YOU HAVE THE LATEST VERSION.
]]);
elseif(dismay.version > dismay.rversion) then
	MsgC(Color(255,0,0,255), [[
*** - YOU DON'T HAVE THE LATEST VERSION.
*** - ]]..dismay.link..[[
]]);
else
	MsgC(Color(0,255,125,255), [[
*** - YOU HAVE A DEV VERSION.
]]);
end

MsgC(Color(0,255,200,255),"\n\n\tSpecial thanks to:\n\t\tNanoCat (for help)\n\t\tvec (for helping me learn)\n\t\tsasha\n\n");
