concommand.Add("party_openwindow", function(ply, cmd, args)
	Party_OpenPanel()
end)

net.Receive("PartySystem_SendPartyList", function(len)
	for n, party in ipairs(PartyList) do
		if IsValid(party.Master) then
			party.Master.PartyMaster = nil
		end
		for k, v in pairs(party.Players) do
			if !IsValid(v) then continue end

			local tb = v:GetTable()

			tb.Party = nil
			tb.PartyID = nil
		end
	end
	PartyList = net.ReadTable()
	for n, party in ipairs(PartyList) do
		if IsValid(party.Master) then
			party.Master.PartyMaster = true
		end
		for k, v in pairs(party.Players) do
			if !IsValid(v) then party.Players[k] = nil continue end

			local tb = v:GetTable()

			tb.Party = party
			tb.PartyID = n
		end
	end
	if IsValid(PartyList_Panel) then
		PartyList_Panel:UpdatePartyList()
		if PartyList_Panel.CurPartyInfoMode and PartyList_Panel.CurPartyInfoMode == "partyinfo" then
			PartyList_Panel:UpdatePartyInfo(PartyList_Panel.CurPartyInfoMode, PartyList_Panel.CurPartyNum)
		end
	end
end)

local use_font = system.IsWindows() and "Trebuchet MS" or "Verdana"
local a = "Party_Treb"

for _, v in ipairs({16, 25, 20, 34, 24}) do
	surface.CreateFont(a.."_S"..v, {font = use_font, size = v, weight = 700, antialias = true, extended = true})
end

for _, v in ipairs({30, 19}) do
	surface.CreateFont(a.."Out_S"..v, {font = use_font, size = v, weight = 700, antialias = true, outline = true, extended = true})
end

local circle = Material("particle/particle_ring_wave_additive")
local showpartyrings = CreateClientConVar("cl_showpartyrings", 1, FCVAR_ARCHIVE)
local color_ring = PartySystem.Color.Ring
local color_master = PartySystem.Color.RingMaster
local local_ply
local function DrawPlayerMarks()
	local_ply = local_ply or LocalPlayer()
	if !showpartyrings:GetBool() or !local_ply:HasParty() then return end
	local party = local_ply:GetParty()
	if party then
		local systime = SysTime() * 120
		for _, v in pairs(party.Players or {}) do
			if IsValid(v) and v != local_ply and !v:IsDormant() and !v:GetNoDraw() and v:Alive() then
				local color = color_ring
				if v:IsPartyMaster() then
					color = color_master
				end
				cam.Start3D2D(v:GetPos() + Vector(0, 0, 5), Angle(0, systime, 0), 0.25)
					surface.SetMaterial(circle)
					surface.SetDrawColor(color) 
					surface.DrawTexturedRect(-100, -100, 200, 200)
				cam.End3D2D()
			end
		end
	end
end
hook.Add("PostDrawTranslucentRenderables", "Party_DrawPlayerMarks", DrawPlayerMarks)

local showpartyhealth = CreateClientConVar("cl_showpartyhealth", 1, FCVAR_ARCHIVE)
local showpartyarmor = CreateClientConVar("cl_showpartyarmor", 1, FCVAR_ARCHIVE)
local limitpartypanels = CreateClientConVar("cl_limitpartypanels", 1, FCVAR_ARCHIVE)
local extendedpartypanels = CreateClientConVar("cl_extendedpartypanels", 0, FCVAR_ARCHIVE)
local drawdots = true
local armor_display = PartySystem.Sidebar.ArmorDisplayOnHUD
local size_x = PartySystem.Sidebar.SizeX
local function DrawPlayerInfo(ply, master, pcount, extended)
	if !IsValid(ply) then return end
	local pos_x, pos_y = PartySystem.Sidebar.Position[1], PartySystem.Sidebar.Position[2]
	local size_y = 50
	if !armor_display or !showpartyarmor:GetBool() then
		size_y = size_y - 15
	end
	local enablehealth = showpartyhealth:GetBool()
	if !enablehealth then
		size_y = size_y - 15
	end
	local spacing = PartySystem.Sidebar.SpacingY
	if extendedpartypanels:GetBool() then
		if extended then
			pcount = pcount / 2 - 0.5
			pos_x = pos_x + size_x + 10
		else
			pcount = pcount / 2
		end
	end
	if limitpartypanels:GetBool() then
		local scrh = ScrH()
		if pos_y + ((pcount - 1) * (size_y + spacing)) > scrh / 2 then return end
		if pos_y + ((pcount) * (size_y + spacing)) > scrh / 2 then
			if drawdots then
				drawdots = false
				draw.SimpleText("...", "Party_TrebOut_S30", PartySystem.Sidebar.Position[1] + 15, pos_y + size_y + ((pcount - 1) * (size_y + spacing)), Color(0, 220, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
			end
			return
		end
	end
	draw.RoundedBox(6, pos_x, pos_y + (pcount * (size_y + spacing)), size_x, size_y, Color(0, 0, 0, 150))
	local nick = ply:Name()
	if master then
		nick = "★ "..nick
	end
	draw.SimpleText(nick, "Party_TrebOut_S19", pos_x + size_x / 2, pos_y + 10 + (pcount * (size_y + spacing)), color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
	if enablehealth then
		local health = ply:Health()
		local maxhealth = ply:GetMaxHealth()
		local percent = health / maxhealth
		percent = math.max(math.min(percent, 1), 0)
		draw.RoundedBox(0, pos_x + 10, pos_y + (pcount * (size_y + spacing)) + 20, (size_x - 20), 10, Color(0, 0, 0, 200))
		if percent > 0 then
			draw.RoundedBox(0, pos_x + 10, pos_y + (pcount * (size_y + spacing)) + 20, (size_x - 20) * percent, 10, Color(125, 0, 0, 255))
			draw.RoundedBox(0, pos_x + 12, pos_y + (pcount * (size_y + spacing)) + 22, (size_x - 24) * percent, 6, Color(255, 0, 0, 255))
		end
		draw.SimpleText(math.max(health, 0).." / "..maxhealth, "Party_Treb_S16", pos_x + size_x / 2, pos_y + 25 + (pcount * (size_y + spacing)), color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
	end
	if armor_display and showpartyarmor:GetBool() then
		local armor = ply:Armor()
		local percent = armor / 100
		percent = math.max(math.min(percent, 1), 0)
		draw.RoundedBox(0, pos_x + 10, pos_y + (pcount * (size_y + spacing)) + (enablehealth and 34 or 20), (size_x - 20), 10, Color(0, 0, 0, 200))
		if percent > 0 then
			draw.RoundedBox(0, pos_x + 10, pos_y + (pcount * (size_y + spacing)) + (enablehealth and 34 or 20), (size_x - 20) * percent, 10, Color(0, 0, 200, 255))
			draw.RoundedBox(0, pos_x + 12, pos_y + (pcount * (size_y + spacing)) + (enablehealth and 36 or 22), (size_x - 24) * percent, 6, Color(0, 100, 200, 255))
		end
		draw.SimpleText(armor.." / 100", "Party_Treb_S16", pos_x + size_x / 2, pos_y + (enablehealth and 39 or 25) + (pcount * (size_y + spacing)), color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
	end
end

local showparty = CreateClientConVar("cl_showparty", 1, FCVAR_ARCHIVE)
local function DrawHUD()
	local_ply = local_ply or LocalPlayer()
	if !showparty:GetBool() or !local_ply:HasParty() then return end
	local party = local_ply:GetParty()
	if party then
		local master = party.Master
		DrawPlayerInfo(master, true, 0, false)
		local pcount = 1
		local extended = true
		for _, v in pairs(party.Players or {}) do
			if IsValid(v) and v != master then
				DrawPlayerInfo(v, false, pcount, extended)
				pcount = pcount + 1
				if extended then
					extended = false
				else
					extended = true
				end
			end
		end
		drawdots = true
	end
end
hook.Add("HUDPaint", "Party_DrawHUD", DrawHUD)

function Party_CreateRequestPanel()
	local P = vgui.Create("Party_RequestPanel")
	P:SetPos(ScrW() - 300, ScrH())
	P.CreatedTime = CurTime()
	return P
end

local PANEL = {}
function PANEL:Think()
	if !self.CreatedTime then return end
	local delta = CurTime() - self.CreatedTime
	self:SetPos(ScrW() - 350, ScrH() - math.min(delta, 0.2) * 1100)
	if delta > 15 then
		self:Remove()
		return
	end
end

function PANEL:Init()
	surface.PlaySound("Town.d1_town_02_elevbell1")
	self:SetSize(300, 200)
	self.AcceptFunction = function()
	end
	local AcceptButton = vgui.Create("Party_DSWButton", self)
	AcceptButton:SetSize(100, 20)
	AcceptButton:SetPos(30, 175)
	AcceptButton:SetTexts("Akzeptieren")
	AcceptButton.Click = function(slf)
		self:AcceptFunction()
		self:Remove()
	end
	local CloseButton = vgui.Create("Party_DSWButton", self)
	CloseButton:SetSize(100, 20)
	CloseButton:SetPos(160, 175)
	CloseButton:SetTexts("Abbrechen")
	CloseButton.Click = function(slf)
		self:Remove()
	end
end

function PANEL:Paint()
	if (!IsValid(self.Player) or (!self.InParty and self.Player:HasParty())) then self:Remove() end
	surface.SetDrawColor(30, 30, 30, 255)
	surface.DrawRect(0, 0, self:GetWide(), self:GetTall())
	surface.SetDrawColor(60, 60, 60, 255)
	surface.DrawRect(0, 0, self:GetWide(), 30)
	draw.SimpleText("Partyanfrage", "Party_Treb_S25", self:GetWide() / 2, 15, Color(255, 255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
	draw.SimpleText(self.PlayerName, "Party_Treb_S20", 150, 45, Color(200, 200, 200, 200), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
	draw.SimpleText(self.TextData, "Party_Treb_S20", 150, 65, Color(200, 200, 200, 200), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
	if !self.CreatedTime then return end
	local delta = CurTime() - self.CreatedTime
	draw.SimpleText("Dieses Fenster schließt sich in "..math.Round(15 - delta).."s", "Party_Treb_S20", 150, 150 , Color(150, 150, 150, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end
vgui.Register("Party_RequestPanel", PANEL, "Panel")