rawset(_G,"votekickstuff",{})
local function initvk()
	votekickstuff = {
		voteinaction = false,
		caller = '',
		target = 0,
		reason = '',
		yay = 0,
		nay = 0,
		time = 0,
		showingkicked = false,
		kickedplayers = {},
	}
end
initvk()

freeslot("sfx_votfal","sfx_votno","sfx_votyes","sfx_votsrt","sfx_votsuc")
sfxinfo[sfx_votfal].caption = "Vote Failure"
sfxinfo[sfx_votno].caption = "Voted \x85NO\x80"
sfxinfo[sfx_votyes].caption = "Voted \x83YES\x80"
sfxinfo[sfx_votsrt].caption = "Vote Started"
sfxinfo[sfx_votsuc].caption = "Vote Succeeded"
local vk = votekickstuff
local TR = TICRATE
local prn = CONS_Printf

local function GetPlayerHelper(pname)
	-- Find a player using their node or part of their name.
	local N = tonumber(pname)
	if N ~= nil and N >= 0 and N < 32 then
		for player in players.iterate do
			if #player == N then
	return player
			end
		end
	end
	for player in players.iterate do
		if string.find(string.lower(player.name), string.lower(pname)) then
			return player
		end
	end
	return nil
end
local function GetPlayer(player, pname)
	local player2 = GetPlayerHelper(pname)
	if not player2 then
		CONS_Printf(player, "No one here has that name.")
	end
	return player2
end
local function dovote(p,option)
	if p.votekickstuff.voted
		return
	end
	
	if option == "yes"
		p.votekickstuff.choice = 1
		vk.yay = $+1
		for p2 in players.iterate
			if p2 == vk.target
				continue
			end
			S_StartSound(nil,sfx_votyes,p2)
			chatprintf(p2,"\x82*"..p.name.." votes \x83YES\x82.")
		end
		if isdedicatedserver
			prn(server,p.name.." votes YAY.")
		end
	elseif option == "no"
		p.votekickstuff.choice = 2
		vk.nay = $+1
		for p2 in players.iterate
			if p2 == vk.target
				continue
			end
			S_StartSound(nil,sfx_votno,p2)
			chatprintf(p2,"\x82*"..p.name.." votes \x85NO\x82.")
		end
		if isdedicatedserver
			prn(server,p.name.." votes NAY.")
		end

	end
	p.votekickstuff.voted = true
end

COM_AddCommand("callvote", function(p,node,reason)
	if gamestate ~= GS_LEVEL
		prn(p,"You can't use this right now.")
		return
	end
	
	if not (p.votekickstuff)
		prn(p,"You can't use this right now.")
		return	
	end
	
	if (splitscreen)
		prn(p,"Stop playing with the other person, silly.")
		return		
	end
	
	if vk.voteinaction
	or vk.showingkicked
		prn(p,"There is already a vote active.")
		return	
	end

	if (p.votekickstuff.timescalled > 5)
		prn(p,"You've been calling too many votes. Wait "..p.votekickstuff.timecall/TR.." seconds before using this again.")
		return	
	end

	if (p.votekickstuff.votewait)
		prn(p,"You can't call a vote for "..p.votekickstuff.votewait/TR.." more seconds.")
		return	
	end

	if not node
		prn(p,"Put someone's node or name to call a votekick on them. Surround your reason with \"\"")
		return
	end
	
	if reason == nil then
		reason = "No reason given"
	end
	
	local p2 = GetPlayer(p,node)
	if p2
		if p2 == server
			prn(p,"You can't kick the server.")
			return
		end
		if p2 == p
			prn(p,"You're calling a votekick on yourself. :pigtrol:")
		end
		
		if isdedicatedserver
			prn(server,p.name.." started a votekick on "..p2.name..", reason: "..reason)
		end
		for p3 in players.iterate
			if p2 == p3
				continue
			end
			S_StartSound(nil,sfx_votsrt,p3)
			prn(p3,p.name.." started a votekick on "..p2.name..".")
			prn(p3,'Use command "vote", or say "!vote" in chat.')
		end
		
		vk.time = 20*TR
		vk.caller = p
		vk.target = p2
		vk.yay,vk.nay = 0,0
		vk.reason = reason
		
		p.votekickstuff.votewait = 50*TR
		p.votekickstuff.timescalled = $+1
		p.votekickstuff.timecall = 3*60*TR
	end
	
end)
COM_AddCommand("vote", function(p,option)
	if gamestate ~= GS_LEVEL
		prn(p,"You can't use this right now.")
		return
	end
	
	if not (p.votekickstuff)
		prn(p,"You can't use this right now.")
		return	
	end
	
	if not vk.voteinaction
		prn(p,"There are no votes active.")
		return	
	end
	
	if vk.target == p
		prn(p,"There are no votes active.")
		return		
	end
	
	if option == nil
		prn(p,'Type "yes" or "no"')
		return			
	else
		option = string.lower($)
		
		if option == "yes"
			dovote(p,"yes")
		elseif option == "no"
			dovote(p,"no")
		end
		
	end
end)

addHook("PlayerThink",function(p)
	if not p
	or not p.valid
		return
	end
	
	if p.votekickstuff == nil
		p.votekickstuff = {
			voted = false,
			choice = 0,
			yaybutton = 0,
			naybutton = 0,
			votewait = 0,
			timescalled = 0,
			timecall = 0,
		}
		return
	end
	
	local vote = p.votekickstuff
	if vote.votewait
		vote.votewait = $-1
	end
	
	if not vk.voteinaction
		vote.voted = false
		vote.choice = 0
	end
	
	if vote.timecall
		vote.timecall = $-1
	else
		if vote.timescalled ~= 0
			vote.timescalled = 0
		end
	end
	
	for k,v in ipairs(vk.kickedplayers)
		if string.lower(v[1]) == string.lower(p.name)
			COM_BufInsertText(p,"exitgame")
		end
	end

end)

addHook("ThinkFrame",do
	if gamestate ~= GS_LEVEL
		initvk()
		return
	end
	
	for k,v in ipairs(vk.kickedplayers)
		if v[2]
			v[2] = $-1
		end
	end
	
	if vk.time
		if vk.voteinaction ~= true
			vk.voteinaction = true
		end
		
		if not (vk.caller and vk.caller.valid)
			if isdedicatedserver
				prn(server,"Votekick caller left, setting caller to server...")
			end
			vk.caller = server
		end
		
		if not (vk.target and vk.target.valid)
			vk.time = 0
			if isdedicatedserver
				prn(server,"Votekick target left, canceling votekick...")
			end
			S_StartSound(nil,sfx_votsuc,p)
			vk.yay = 0
			vk.nay = 0
			vk.target = 0
			vk.caller = 0
			vk.reason = ''
			vk.voteinaction = false
			return
		end
		
		if vk.time == 1
			vk.showingkicked = 3*TR
			if vk.yay > vk.nay
				if isdedicatedserver
					prn(server,"Votekick against "..vk.target.name.." succeeded.")
				end
			else
				if isdedicatedserver
					prn(server,"Votekick against "..vk.target.name.." failed.")
				end
			end
			
			for p in players.iterate
				if p == vk.target
					continue
				end
				
				if vk.yay > vk.nay
					S_StartSound(nil,sfx_votsuc,p)
				else
					S_StartSound(nil,sfx_votfal,p)
				end
			end
			
		end
		
		vk.time = $-1
	else
		vk.voteinaction = false
		if vk.showingkicked
			if vk.showingkicked == 1
				if vk.yay > vk.nay
					print("Preparing to kick "..vk.target.name.."...")
					local reason = "Votekicked: "..vk.reason
					//boring, wish i could use player_t
					table.insert(vk.kickedplayers,{vk.target.name,3*60*TR})
					COM_BufInsertText(server,"kick "..#vk.target..' '..reason)
				end
				vk.yay = 0
				vk.nay = 0
				vk.target = 0
				vk.caller = 0
				vk.reason = ''
			end
			vk.showingkicked = $-1
		end
	end
	
end)

addHook("HUD",function(v)
	local p = consoleplayer
	if not p
	or not p.valid
		return
	end
	
	if (vk.target == p)
		return
	end
	
	if vk.voteinaction
		v.drawScaled(205*FU,53*FU,FU,v.cachePatch("VOTEBACK"),V_SNAPTORIGHT|V_HUDTRANSHALF)

		v.drawString(300,80-18,vk.caller.name,V_GRAYMAP|V_HUDTRANS|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"small-right")
		v.drawString(300,80-10,"wants to call a vote on",V_GRAYMAP|V_HUDTRANS|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"small-right")
		v.drawString(300-40,80,vk.target.name,V_HUDTRANS|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"thin-center")
		v.drawString(300-40,88,vk.reason,V_RETURN8|V_HUDTRANS|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"small-center")
		
		local sec = G_TicsToSeconds(vk.time)
		local cen = G_TicsToCentiseconds(vk.time)
		local pad = ''
		if cen < 10 then pad = "0" end
		local timestring = sec.."."..pad..cen
		v.drawString(300-40,110,"Ends in "..timestring,V_HUDTRANS|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"small-center")
		
		local yesflag,noflag = 0,0
		if p.votekickstuff.choice == 1
			yesflag = V_YELLOWMAP
		elseif p.votekickstuff.choice == 2
			noflag = V_YELLOWMAP
		end
		
		v.drawString(300-60,120,vk.yay,yesflag|V_HUDTRANS|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"left")
//		v.drawString(300-60,120+8,'F1',V_RETURN8|V_HUDTRANSHALF|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"small")
//		v.drawString(300-60,120+16,'"vote yes"',V_RETURN8|V_HUDTRANSHALF|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"small")

		v.drawString(300-15,120,vk.nay,noflag|V_HUDTRANS|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"right")
//		v.drawString(300-15,120-16,'F2',V_RETURN8|V_HUDTRANSHALF|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"small-right")
//		v.drawString(300-15,120-8,'"vote no"',V_RETURN8|V_HUDTRANSHALF|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"small-right")
	elseif vk.showingkicked
		v.drawScaled(205*FU,53*FU,FU,v.cachePatch("VOTEBACK"),V_SNAPTORIGHT|V_HUDTRANSHALF)
		if vk.yay > vk.nay
			v.drawString(300,80,"Kicking player "..vk.target.name.."...",V_HUDTRANS|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"thin-right")
		else
			v.drawString(300,80,"Vote Failed",V_HUDTRANS|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"thin-right")		
		end
		
		local yesflag,noflag = 0,0
		if p.votekickstuff.choice == 1
			yesflag = V_YELLOWMAP
		elseif p.votekickstuff.choice == 2
			noflag = V_YELLOWMAP
		end
		
		v.drawString(300-60,120,vk.yay,yesflag|V_HUDTRANS|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"left")

		v.drawString(300-15,120,vk.nay,noflag|V_HUDTRANS|V_ALLOWLOWERCASE|V_SNAPTORIGHT,"right")
		
	end
end,"game")

addHook("NetVars",function(n)
	votekickstuff = n($)
end)

addHook("PlayerMsg", function(src, t, target, msg)
	if string.lower(msg) == '!callvote'
		chatprintf(src,"\x82Use the callvote command instead.")
		
		return true
	end
	
	if vk.voteinaction
		if string.lower(msg) == '!vote yes' then
			dovote(src,"yes")
			return true
		elseif string.lower(msg) == '!vote no'
			dovote(src,"no")			
			return true
		end
	end
end)
