--[[
	menu_plugins/pokilist.lua
	| DPG | Hasular | PoKi |
	===Begin DStream===
]]

PoKiList = {}

hook.Add("Think" , 0 , function()
	hook.Remove("Think" , 0)
	hook.Call("PostMenuLoaded")
end )

hook.Add("PostMenuLoaded" , "PoKiList_Init" , function()
	MsgN("Menustate loaded. Initialising PoKi Propkiller List.")
	
	local deftbl = {	
		["default"] = {
			[1] = {c = "Forge" , val = 0},
			[2] = {c = "Crash" , val = 0},
			[3] = {c = "Falco" , val = 0},
			[4] = {c = "Eagle" , val = 0},
			[5] = {c = "Propsareawesome" , val = 0},
			[6] = {c = "Bl00db4th" , val = 0},
			[7] = {c = "HiggenZ" , val = 0},
			[8] = {c = "Elousive" , val = 0},
		},
		["ttt"] = {
			[1] = {c = "Harkfish" , val = 0},
			[2] = {c = "Simplicity" , val = 0},
			[3] = {c = "Luke Turnip" , val = 0},
			[4] = {c = "Flawless" , val = 0},
			[5] = {c = "Annin" , val = 0},
			[6] = {c = "Hasular" , val = 0},
			[7] = {c = "MrProps" , val = 0},
		},
		
		["rage"] = {
			[1] = {c = "Iced Coffee" , val = 0},
			[2] = {c = "Mitch" , val = 0},
			[3] = {c = "Bready" , val = 0},
			[4] = {c = "Piggeey" , val = 0},
			[5] = {c = "Boshky" , val = 0},
			[6] = {c = "Bob" , val = 0},
			[7] = {c = "Reaper" , val = 0},
			[8] = {c = "To be determined" , val = 0},
		},
		
		["team deathmatch"] = {
			[1] = {c = "JJHK" , val = 0},
			[2] = {c = "Hellhound" , val = 0},
			[3] = {c = "Jellybaby" , val = 0},
			[4] = {c = "Crypt" , val = 0},
			[5] = {c = "To be determined" , val = 0},
			[6] = {c = "To be determined" , val = 0},
			[7] = {c = "To be determined" , val = 0},
			[8] = {c = "To be determined" , val = 0},
		},
	}
	
	local presets = file.Exists("PoKi_presets.txt") and KeyValuesToTable(file.Read("PoKi_presets.txt")) or (file.Write("PoKi_presets.txt" , TableToKeyValues(deftbl)) or deftbl)
	
	function SavePreset(index , table)
		presets[index] = table
		file.Write("PoKi_presets.txt" , TableToKeyValues(presets))
	end
	
	
	PoKiList.Version = 1
	PoKiList.Settings = {}
	PoKiList.ConVarSettings = {}
	PoKiList.ConVarSettings["Aim"] = {}
	PoKiList.ConVarSettings["ESP"] = {}
	PoKiList.ConVarSettings["Misc"] = {}
	PoKiList.ConVarNames = {}

	function tobool(int)
		if int == true then
			return true
		elseif int == false then
			return false
		else
			return math.floor(int) == 1
		end
	end
	
	function PoKiList:CreateConVar(cvar , def , save,  userdata,  var , maxno , minno , isdec)
		local booltype = false
		if type(def) == "boolean" then
			def = def and 1 or 0
			booltype = true
		end
		
		local convar = CreateClientConVar(cvar , def , save , userdata)
		if booltype then
			PoKiList.Settings[var] = tobool(convar:GetInt())
		elseif type(def) == "number" then
			if !isdec then
				PoKiList.Settings[var] = convar:GetInt()
			else
				PoKiList.Settings[var] = tonumber(convar:GetString())
			end
		elseif type(def) == "string" then
			PoKiList.Settings[var] = convar:GetString()
		end

		if string.find(cvar , "aim") then
			if booltype then
				PoKiList.ConVarSettings["Aim"][var] = {var = cvar , type = "boolean" , name = var}
			elseif type(def) == "string" then
				PoKiList.ConVarSettings["Aim"][var] = {var = cvar , type = "string" , name = var}
			elseif type(def) == "number" then
				PoKiList.ConVarSettings["Aim"][var] = {var = cvar , type = "number" , max = maxno , min = minno , dec = isdec , name = var}
			end
		elseif string.find(cvar , "esp") then
			if booltype then
				PoKiList.ConVarSettings["ESP"][var] = {var = cvar , type = "boolean" , name = var}
			elseif type(def) == "string" then
				PoKiList.ConVarSettings["ESP"][var] = {var = cvar , type = "string" , name = var }
			elseif type(def) == "number" then
				PoKiList.ConVarSettings["ESP"][var] = {var = cvar , type = "number" , max = maxno , min = minno , dec = isdec , name = var}
			end
		else
			if booltype then
				PoKiList.ConVarSettings["Misc"][var] = {var = cvar , type = "boolean" , name = var}
			elseif type(def) == "string" then
				PoKiList.ConVarSettings["Misc"][var] = {var = cvar , type = "string" , name = var}
			elseif type(def) == "number" then
				PoKiList.ConVarSettings["Misc"][var] = {var = cvar , type = "number" , max = maxno , min = minno , dec = isdec , name = var}
			end
		end
		
		table.insert(PoKiList.ConVarNames , cvar)
		
		cvars.AddChangeCallback(cvar , function(cvar , old , new)
			if booltype then
				PoKiList.Settings[var] = tobool(math.floor(new))
				--print("PoKiList: Setting "..var.." to " , tobool(new))
				
			else
				PoKiList.Settings[var] = new
				--print("PoKiList: Setting "..var.." to "..new)
			end
		end )
		
		return convar
	end

	-- We want the same functionality as last time. So I'll just copy the convars too.

	PoKiList:CreateConVar("Forge" , false , true , false , "CheckPartialHits")
	PoKiList:CreateConVar("Falco" , false , true , false , "AimEnabled")
	PoKiList:CreateConVar("To be determined" , false , true , false , "FriendlyFire")
	PoKiList:CreateConVar("Crash" , false , true , false , "TargetNPCs")
	PoKiList:CreateConVar("Eagle" , false , true , false , "AutoFire")
	PoKiList:CreateConVar("Bl00db4th" , false , true , false , "AutoReload")
	PoKiList:CreateConVar("To be determined" , 0 , true , false , "BoneMode" , 3 , 1)
	PoKiList:CreateConVar("MrProps" , false , true , false, "TargetFriends")
	PoKiList:CreateConVar("Hasular" , false , true ,false , "TargetSteamFriends")
	PoKiList:CreateConVar("Ghost Rider" , 0 , true , false , "TargetMode" , 4 , 1)
	--PoKiList:CreateConVar("null" , true , true , false , "NoSpread")
	PoKiList:CreateConVar("Mitch" , 0 , true , false , "MaxDistance" , 16384 , 0)
	PoKiList:CreateConVar("HiggenZ" , false , true ,false , "TargetAdmins")	
	PoKiList:CreateConVar("Elousive" ,  false , true , false , "AntiSnap")
	PoKiList:CreateConVar("Jellybaby" , false , true , false , "NoRecoil")
	PoKiList:CreateConVar("Harkfish" , 0 , true , false , "AntiSnapSpeed" , 10 , 0 , true)
	PoKiList:CreateConVar("Luke Turnip" , 0 , true , false , "MaxAngleDiff" , 180 , 0 , true)
	PoKiList:CreateConVar("Flawless" , false , true , false , "SnapOnFire")
	PoKiList:CreateConVar("Annin" , 0 , false , false , "SnapOnFireTime" , 10 , 0.1, true)
	PoKiList:CreateConVar("Iced Coffee" , false , true , false , "OnlyTargetTraitors")
	PoKiList:CreateConVar("Bready" , false , true , false , "VelocityPrediction")
	PoKiList:CreateConVar("Piggeey" , false , true, false , "CheckNPCRelationship") 

	PoKiList:CreateConVar("Boshky" , false , true , false , "ESPEnabled")
	PoKiList:CreateConVar("Bob" , 0 , true , false , "WallhackMaterial")
	PoKiList:CreateConVar("To be determined" , 0 , true , false , "WallhackMaterial")
	PoKiList:CreateConVar("To be determined" , false , true , false , "DrawWeapons")
	PoKiList:CreateConVar("JJHK" , 0 , true , false , "MaxESPDistance" , 16384 , 0)
	PoKiList:CreateConVar("Hell Hound" , false , true , false , "ZoomToCurrentTarget")
	PoKiList:CreateConVar("Crypt" , 0 , true , false , "ZoomFactor" , 5 , 0.1 , true)
	PoKiList:CreateConVar("Propsareawesome" , false , true , false , "DrawCrosshair")
	PoKiList:CreateConVar("Reaper" , false , true , false , "DrawTextInfo")
	PoKiList:CreateConVar("Simplicity" , false , true , false , "UseComplexDrawing")
	PoKiList:CreateConVar("To be determined" , false , true , false , "OnlyDrawOtherTeams")
	PoKiList:CreateConVar("To be determined" , true , true , false , "TraitorMode")
	PoKiList:CreateConVar("To be determined" , true , true , false , "DrawModels")

	--PoKiList:CreateConVar("null" , false , true , true , "RadarEnabled")


	PoKiList:CreateConVar("To be determined" , true , true , false , "CheckForUpdates")
	PoKiList:CreateConVar("To be determined" , true , true , false , "ShouldLoad")
	PoKiList:CreateConVar("To be determined" , false , true , false , "EnableKeyBinding")
	PoKiList:CreateConVar("To be determined" , false , true , false , "BunnyHop")
	PoKiList:CreateConVar("To be determined" , 270 , true , false , "BunnyHopSpeed" , 700 , 0)
	PoKiList:CreateConVar("To be determined" , false , true , false , "IgnoreLOS")
	PoKiList:CreateConVar("To be determined" , false , true , false , "AlwaysLoadHardCopy")
	PoKiList:CreateConVar("To be determined" , false , true , true , "UCMDFire") -- It's slightly slower than +attack for some reason, but it's more likely to bypass shitty anticheats.


	PoKiList.Frame = vgui.Create("DFrame")
	PoKiList.Frame:SetSize(300 , 376)
	PoKiList.Frame:SetTitle("PoKi Propkiller Menu")
	PoKiList.Frame:SetPos(ScrW() - 310 , 5)
	PoKiList.Frame:SetDraggable(false)
	PoKiList.Frame:ShowCloseButton(false)
	PoKiList.Frame:MakePopup()
	
	
	local dlistview = vgui.Create("DListView")
	dlistview:SetParent(PoKiList.Frame)
	dlistview:SetPos(0 , 47)
	dlistview:SetSize(300 , 303)
	dlistview:AddColumn("Propkiller")
	dlistview:AddColumn("Beaten")
	dlistview:SetMultiSelect(false)
	dlistview.oldselect = dlistview.OnClickLine
	
	for a , b in pairs(PoKiList.ConVarSettings) do
		for k , v in pairs(PoKiList.ConVarSettings[a]) do
			if v.type == "number" then
				if v.isdec then
					dlistview:AddLine(v.var , GetConVar(v.var):GetFloat())
				else
					dlistview:AddLine(v.var , GetConVar(v.var):GetInt())
				end
			elseif v.type == "string" then
				dlistview:AddLine(v.var , GetConVar(v.var):GetString())
			elseif v.type == "boolean" then
				dlistview:AddLine(v.var , GetConVar(v.var):GetInt())
			end
		end
	end
	
	dlistview:SortByColumn(1)
	
	local dtextentry = vgui.Create("DTextEntry")
	dtextentry:SetParent(PoKiList.Frame)
	dtextentry:SetPos(0 , 22)
	dtextentry:SetSize(300 , 25)
	dtextentry:SetText("Select a Propkiller below to edit.")
	
	dlistview.OnClickLine = function( self , line , ...)
		if dtextentry:GetValue() == "Enter a value for "..line:GetValue(1).." and press enter." then
			dtextentry:SetText("")
		else
			dtextentry:SetText("Enter a value for "..line:GetValue(1).." and press enter.")
		end
		dlistview.oldselect(self , line , ...)
	end
	
	dtextentry.OnMousePressed = function()
		if dtextentry:GetValue() == "Enter a value for "..dlistview:GetLine(dlistview:GetSelectedLine()):GetValue(1).." and press enter." then
			dtextentry:SetText("")
		end
	end
	
	dtextentry.OnEnter = function()
		RunConsoleCommand(dlistview:GetLine(dlistview:GetSelectedLine()):GetValue(1) , dtextentry:GetValue())
		dlistview:GetLine(dlistview:GetSelectedLine()):SetValue(2  , dtextentry:GetValue())
	end
	
	local dbutton = vgui.Create("DButton")
	dbutton:SetParent(PoKiList.Frame)
	dbutton:SetPos(0, 350)
	dbutton:SetSize(150 , 25)
	dbutton:SetText("Save list")
	dbutton.DoClick = function()
		local preset = {}
		local x , y = gui.MousePos()
		for k , v in ipairs(dlistview:GetLines()) do
			table.insert(preset , {c=v:GetValue(1),val=v:GetValue(2)})
		end
		
		local dframe = vgui.Create("DFrame")
		dframe:SetTitle("Enter preset name")
		dframe:SetSize(150 , 73)
		dframe:SetPos(x - 100 , y)
		dframe:MakePopup()
		
		local dtextentry = vgui.Create("DTextEntry")
		dtextentry:SetParent(dframe)
		dtextentry:SetPos(0 , 22)
		dtextentry:SetSize(150 , 25)
		dtextentry:SetText("Enter preset name")
		dtextentry.OnMousePressed = function()	
			if dtextentry:GetValue() == "Enter preset name" then
				dtextentry:SetText("")
			end
		end
		
		dtextentry.OnEnter = function()
			SavePreset(dtextentry:GetValue() , preset)
			dframe:Remove()
		end
		
		local dbutton = vgui.Create("DButton")
		dbutton:SetParent(dframe)
		dbutton:SetPos(0 , 48)
		dbutton:SetSize(150 , 25)
		dbutton:SetText("Save list")
		dbutton.DoClick = function()
			SavePreset(dtextentry:GetValue() , preset)
			dframe:Remove()
		end
	end
	
	local dbutton = vgui.Create("DButton")
	dbutton:SetParent(PoKiList.Frame)
	dbutton:SetPos(150 , 350)
	dbutton:SetSize(150 , 25)
	dbutton:SetText("Load list")
	dbutton.DoClick = function()
		local x , y = gui.MousePos()
		local dframe = vgui.Create("DFrame")
		dframe:SetTitle("Enter preset name")
		dframe:SetSize(200, 220)
		dframe:SetPos(x - 100 , y )
		dframe:MakePopup()
		
		local dl = vgui.Create("DListView")
		dl:SetParent(dframe)
		dl:SetPos(0 , 22)
		dl:SetSize(200 , 173)
		dl:AddColumn("Preset")
		dl.OnRowRightClick = function(self , row)	
			local dm = DermaMenu()
			dm:AddOption("Delete selected preset" , function() 
				presets[dl:GetLine(row):GetValue(1)] = nil 
				file.Write("PoKi_presets.txt" , TableToKeyValues(presets)) 
				dl:Clear()
				for k , v in pairs(presets) do
					dl:AddLine(k)
				end
			end )
			dm:Open()
		end
		
		for k , v in pairs(presets) do
			dl:AddLine(k)
		end
		
		local db = vgui.Create("DButton")
		db:SetParent(dframe)
		db:SetPos(0 , 195)
		db:SetText("Load list")
		db:SetSize(200 , 25)
		db.DoClick = function()
			if dl:GetSelectedLine() then
				local preset = dl:GetLine(dl:GetSelectedLine()):GetValue(1)
				for k , v in pairs(presets[preset]) do
					
					RunConsoleCommand(v.c , v.val)
					for a , b in ipairs(dlistview:GetLines()) do
						if b:GetValue(1) == v.c then
							b:SetValue(2 , v.val)
						end
					end
				end
				dframe:Remove()
			end
		end
	end
	
	concommand.Add("_PoKi_menu_reload" , function()
		PoKiList.Frame:Remove()
		include("menu_plugins/PoKiList.lua")
	end )
	
	
	if PoKiList.Settings.CheckForUpdates then
		local version
		
		-- Get the local version from the file.
		if not file.Exists("PoKiList_bot.txt") then
			-- Version 10
			version = 10
		else
			local stuff = file.Read("PoKiList_bot.txt")
			local versionstart = string.find(stuff , "PoKiList.Revision =")
			local versionend = string.find(string.sub(stuff , versionstart) , "\n")
			version = tonumber(string.sub(stuff , versionstart + string.len("PoKiList.Revision =") , versionstart + versionend - 1))
		end
		
		-- If the below isn't available, then fuck it. freewebs is too slow for a 70kb file.
		local url = "http://flapadar.modoutlet.com/PoKiListV3/check.txt"
		
		local function ShowUpdate(rev , url, clog)
			print(string.format("PoKiList: Version %d is available at %s" , rev , url))
			
			local dframe = vgui.Create("DFrame")
			dframe:SetSize(300 , 202)
			dframe:SetTitle("PoKiList: Update available")
			dframe:MakePopup()
			dframe:Center()
			
			local dlabel = vgui.Create("DLabel")
			dlabel:SetParent(dframe)
			dlabel:SetText(string.format("Thanks Flapadar for the Derma.  :D" , rev , url))
			dlabel:SizeToContents()
			dlabel:SetPos(5 , 25)
			
			local dtextentry = vgui.Create("DTextEntry")
			dtextentry:SetParent(dframe)
			dtextentry:SetPos(0 , 75)
			dtextentry:SetSize(300 , 25)
			dtextentry:SetText(url)
			dtextentry.OnMousePressed = function()
				SetClipboardText(url)
				if LocalPlayer() and ValidEntity(LocalPlayer()) then
					LocalPlayer():ChatPrint("Seriously, thank you!")
				end
			end
			
			local dtextentry = vgui.Create("DTextEntry")
			dtextentry:SetParent(dframe)
			dtextentry:SetPos(0 , 102)
			dtextentry:SetSize(300 , 98)
			dtextentry:SetMultiline(true)
			dtextentry:SetText("Changelog:" .. clog)
			dtextentry:SetEditable(false)
		end
		
		local function DownloadUpdate(rev , url , changelog)
			MsgN("[PoKiList] Downloading revision "..rev..":\n"..changelog)
			
			local downreps = 0
			local function GetHTTPSource(url)
				http.Get(url , "" , function(cont , size)
					if size > 0 and string.find(cont , "PoKiList = {}") then
						file.Write("PoKiList_bot.txt" , cont)
					elseif downreps < 5 then
						downreps = downreps + 1
						GetHTTPSource(url)
					end
				end)
			end 
			
			GetHTTPSource(url)
		end
		
		local function FormatVersion(str)
			local contTbl = string.Explode("\n" , str)
			if string.find(contTbl[1] , "dun goofed") then
				local revision = tonumber(contTbl[2])
				local fullversion = tonumber(contTbl[3])
				local revurl = contTbl[4]
				local fullurl = contTbl[5]
				table.remove(contTbl , 1)
				table.remove(contTbl , 2)
				table.remove(contTbl , 3)
				table.remove(contTbl , 4)
				table.remove(contTbl , 5)
				
				local changelog = table.concat(contTbl , "\n")
				
				if fullversion > PoKiList.Version then
					MsgN("Out of date.")
					ShowUpdate(fullversion , fullurl , changelog)
				end
				
				if (version and (revision > version)) then
					DownloadUpdate(revision , revurl , changelog)
				else
					MsgN("[PoKiList] PoKiList is up to date.")
				end
			else
				CheckVersion()
			end
		end
		
		local checkreps = 0
		local function CheckVersion()
			http.Get(url , "" , function(cont , size)
				MsgN("[PoKi Propkiller List] Loading...")
				if size > 0 and string.find(cont , "dun goofed") then
					FormatVersion(cont)
				elseif checkreps < 3 then
					checkreps = checkreps + 1
					CheckVersion()
				else
					MsgN("[PoKi Propkiller List] Loaded!")
				end
			end )
		end
		CheckVersion()
	end
		
end )


