local LocalPlayer, IsValid, CurTime, math, string, hook, Lerp = LocalPlayer, IsValid, CurTime, math, string, hook, Lerp
local ScrW, ScrH, surface, draw = ScrW, ScrH, surface, draw
local Color, color_white, color_black = Color, color_white, color_black
local ply, cur_time

local surface_SetFont = surface.SetFont
local surface_SetDrawColor = surface.SetDrawColor
local surface_SetTextColor = surface.SetTextColor
local surface_SetTextPos = surface.SetTextPos
local surface_SetMaterial = surface.SetMaterial
local surface_GetTextSize = surface.GetTextSize
local surface_DrawLine = surface.DrawLine
local surface_DrawText = surface.DrawText
local surface_DrawRect = surface.DrawRect
local surface_DrawTexturedRect = surface.DrawTexturedRect
local surface_DrawTexturedRectRotated = surface.DrawTexturedRectRotated

local draw_SimpleText = draw.SimpleText
local draw_SimpleTextOutlined = draw.SimpleTextOutlined
local draw_DrawNonParsedText = draw.DrawNonParsedText
local draw_DrawNonParsedSimpleText = draw.DrawNonParsedSimpleText
local draw_RoundedBox = draw.RoundedBox
local draw_RoundedBoxEx = draw.RoundedBoxEx

local function DrawRect(x, y, w, h, color)
	surface_SetDrawColor(color)
	surface_DrawRect(x, y, w, h)
end

surface.CreateFont("namef", {font = "BebasNeue", size = 24, weight = 500, blursize = 0, scanlines = 0, antialias = true})
surface.CreateFont("namefsmall", {font = "BebasNeue", size = 16, weight = 500, blursize = 0, scanlines = 0, antialias = true})
surface.CreateFont("jobf", {font = "BebasNeue", size = 34, weight = 500, scanlines = 0, antialias = true})
surface.CreateFont("jobfsmall", {font = "BebasNeue", size = 24, weight = 500, blursize = 0, antialias = true})
surface.CreateFont("jobfxsmall", {font = "BebasNeue", size = 20, weight = 500, scanlines = 0, antialias = true})
surface.CreateFont("jobfxxsmall", {font = "BebasNeue", size = 16, weight = 500, scanlines = 0, antialias = true})
surface.CreateFont("moneyf", {font = "BebasNeue", size = 48, weight = 500, blursize = 0, scanlines = 0, antialias = true})
surface.CreateFont("moneyfsmall", {font = "BebasNeue", size = 26, weight = 500, scanlines = 0, antialias = true})
surface.CreateFont("moneyfxsmall", {font = "BebasNeue", size = 36, weight = 500, scanlines = 0, antialias = true})
surface.CreateFont("salaryf", {font = "BebasNeue", size = 24, weight = 500, blursize = 0, scanlines = 0, antialias = true})
surface.CreateFont("healthf", {font = "BebasNeue", size = 18, weight = 500, blursize = 0, scanlines = 0, antialias = true})
surface.CreateFont("healthf2", {font = "BebasNeue", size = 20, weight = 500, blursize = 0, scanlines = 0, antialias = true})
surface.CreateFont("wantf", {font = "BebasNeue", size = 36, weight = 500, blursize = 0, scanlines = 0, antialias = true})
surface.CreateFont("hungerf", {font = "BebasNeue", size = 20, weight = 500, blursize = 0, scanlines = 0, antialias = true})
surface.CreateFont("wantxtf", {font = "Trebuchet MS", size = 22, weight = 1000, blursize = 0, scanlines = 0, antialias = true})
surface.CreateFont("lockdownf", {font = "Trebuchet MS", size = 24, weight = 1000, blursize = 0, scanlines = 0, antialias = true})
surface.CreateFont("arrestedf", {font = "Trebuchet MS", size = 20, weight = 1000})
surface.CreateFont("foodf", {font = "Arial", size = 35, weight = 1000, antialias = true, shadow = false})
surface.CreateFont("iconf", {font = "Arial", size = 60, weight = 1000, antialias = true, shadow = false})
surface.CreateFont("adminf", {font = "BebasNeue", size = 25, weight = 500, antialias = true, shadow = false})
surface.CreateFont("weaponf", {font = "BebasNeue", size = 35, weight = 500, antialias = true, shadow = false})
surface.CreateFont("ammof", {font = "BebasNeue", size = 35, weight = 500, antialias = true, shadow = false})
surface.CreateFont("ammofsmall", {font = "BebasNeue", size = 25, weight = 500, antialias = true, shadow = false})

surface.CreateFont("DarkRPHUD2_Underline", {size = 23, weight = 400, antialias = true, shadow = false, font = "Roboto", underline = true})

local hide = {
	["DarkRP_HUD"] = false, 
	["DarkRP_EntityDisplay"] = true, 
	["DarkRP_LocalPlayerHUD"] = true, 
	["DarkRP_Hungermod"] = true, 
	["DarkRP_Agenda"] = true, 
	["DarkRP_LockdownHUD"] = true, 
	["DarkRP_ArrestedHUD"] = true,
	["CHudHealth"] = true,
	["CHudBattery"] = true,
	["CHudSuitPower"] = true,
	["CHudAmmo"] = true,
	["CHudSecondaryAmmo"] = true,
	["CHUDQuickInfo"] = true
}

timer.Simple(0, function()
	function GAMEMODE:HUDShouldDraw(name)
		if hide[name] then return false end
		return self.Sandbox.HUDShouldDraw(self, name)
	end
end)

local meta = FindMetaTable("Player")
local page = Material("icon16/page_white_text.png")

local wep_tbl = {
	["spawned_weapon"] = true,
	["spawned_shipment"] = true
}
local gen_mat = Material("mg_marker/wrench.png")
local gun_mat = Material("mg_marker/gun.png")

local pos, pos_x, pos_y, wanted, time, name, tm, health, hcolor, armorfont, tmname, arrested, bail, item
local arrested_color = Color(255, 0, 0, 200)

local healthcolors = {
	healthy = Color(0, 200, 0, 255),
	scratched = Color(50, 230, 10, 255),
	hurt = Color(170, 230, 10, 255),
	wounded = Color(230, 215, 10, 255),
	badwound= Color(255, 140, 0, 255),
	death = Color(200, 0, 0, 255)
}
local hpJobs = {}
timer.Simple(0, function()
	hpJobs = {
		[TEAM_OWNER] = true,
		[TEAM_STAFF] = true,
		[TEAM_DOCTOR] = true,
	}
end)

local function HealthToString(health, maxhealth)
	ply = ply or LocalPlayer()
	maxhealth = maxhealth or 100
	if health >= maxhealth then
		return hpJobs[ply:Team()] and math.max(health, 0).." Leben" or "Gesund", healthcolors.healthy
	elseif health > maxhealth * 0.9 then
		return hpJobs[ply:Team()] and math.max(health, 0).." Leben" or "Angekratzt", healthcolors.scratched
	elseif health > maxhealth * 0.75 then
		return hpJobs[ply:Team()] and math.max(health, 0).." Leben" or "Verletzt", healthcolors.hurt
	elseif health > maxhealth * 0.5 then
		return hpJobs[ply:Team()] and math.max(health, 0).." Leben" or "Verwundet", healthcolors.wounded
	elseif health > maxhealth * 0.25 then
		return hpJobs[ply:Team()] and math.max(health, 0).." Leben" or "Schwer verwundet", healthcolors.badwound
	elseif health > 0 then
		return hpJobs[ply:Team()] and math.max(health, 0).." Leben" or "Nahe dem Tod", healthcolors.death
	else
		return hpJobs[ply:Team()] and math.max(health, 0).." Leben" or "Verstorben", healthcolors.death
	end
end

meta.drawPlayerInfo = function(self, pos)
	pos = pos or self:EyePos()
	pos.z = pos.z + 10
	pos = pos:ToScreen()
	wanted = self:getDarkRPVar("wanted")
	if !wanted then
		pos.y = pos.y - 50
	end
	pos_x, pos_y = pos.x, pos.y
	item = self:GetNW2Int("ItemStore_DoAction", 0)
	if item > 0 then
		surface_SetMaterial(item == 2 and gun_mat or gen_mat)
		surface_SetDrawColor(color_white)
		surface_DrawTexturedRectRotated(pos_x, wanted and pos_y - 64 or pos_y - 20, 32, 32, (CurTime() % 360) * 250)
	end
	name, tm = self:Name(), self:Team()
	if GAMEMODE.Config.showname then
		draw_DrawNonParsedText(name, "DarkRPHUD2", pos_x + 1, pos_y + 1, color_black, 1)
		tm = RPExtraTeams[tm]
		draw_DrawNonParsedText(name, "DarkRPHUD2", pos_x, pos_y, tm and tm.color or team.GetColor(tm), 1)
	end
	if GAMEMODE.Config.showjob then
		tmname = self:getDarkRPVar("job") or team.GetName(tm)
		draw_DrawNonParsedText(tmname, "DarkRPHUD2", pos_x + 1, pos_y + 21, color_black, 1)
		draw_DrawNonParsedText(tmname, "DarkRPHUD2", pos_x, pos_y + 20, color_white, 1)
	end
	if GAMEMODE.Config.showhealth then
		health, hcolor = HealthToString(self:Health(), self:GetMaxHealth())
		armorfont = self:Armor() > 0 and "DarkRPHUD2_Underline" or "DarkRPHUD2"
		draw_DrawNonParsedText(health, armorfont, pos_x + 1, pos_y + 41, color_black, 1)
		draw_DrawNonParsedText(health, armorfont, pos_x, pos_y + 40, hcolor, 1)
	end
	time = self:getDarkRPVar("ArrestTime")
	if time and time != 0 then
		arrested = true
	else
		arrested = false
	end
	if arrested then
		time = math.max(math.abs(CurTime() - time), 0)
		bail = "In Haft: "..string.ToMinutesSeconds(time)
		draw_DrawNonParsedText(bail, "DarkRPHUD2", pos_x + 1, pos_y + 61, color_black, 1)
		draw_DrawNonParsedText(bail, "DarkRPHUD2", pos_x, pos_y + 60, arrested_color, 1)
	end
	if self:getDarkRPVar("HasGunlicense") then
		surface_SetMaterial(page)
		surface_SetDrawColor(color_white)
		surface_DrawTexturedRect(pos_x - 16, pos_y + 64 + (arrested and 16 or 0), 32, 32)
	end
end

local agenda = CreateClientConVar("cl_agenda", 1, FCVAR_ARCHIVE)
local agenda_txt, agenda_tbl
local box_color = Color(0, 0, 0, 155)
local box_color2 = Color(51, 58, 51,100)
local box_color3 = Color(0, 0, 70, 100)
local text_color = Color(255, 50, 50, 255)
local function DrawAgendaHUD(ply)
	if !agenda:GetBool() then return end
	agenda_tbl = ply:getAgendaTable()
	if !agenda_tbl then return end
	agenda_txt = DarkRP.textWrap((ply:getDarkRPVar("agenda") or ""):gsub("//", "\n"):gsub("\\n", "\n"), "DarkRPHUD1", 440)
	draw_RoundedBox(4, 10, 10, 460, 110, box_color)
	draw_RoundedBox(4, 12, 12, 456, 106, box_color2)
	draw_RoundedBox(4, 12, 12, 456, 20, box_color3)
	draw_DrawNonParsedText(agenda_tbl.Title, "DarkRPHUD1", 25, 12, text_color, 0)
	draw_DrawNonParsedText(agenda_txt, "DarkRPHUD1", 22, 35, color_white, 0)
end

local lockdown = CreateClientConVar("cl_lockdown", 1, FCVAR_ARCHIVE)
local cin, text, offset
local function DrawLockdownHUD(ply, scrw, scrh, cur_time)
	if !lockdown:GetBool() then return end
	if GetGlobalBool("DarkRP_LockDown") then
		cin = (math.sin(cur_time) + 1) / 2
		text = DarkRP.getPhrase("lockdown_started")
		offset = ply:isWanted() and 185 or 170
		cin = cin * 255
		draw_SimpleTextOutlined(text, "lockdownf", 10, scrh - offset, Color(cin, 0, 255 - cin, 255), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
	end
end

local time, text, w, h, ybase
local padding = 5
local box_color = Color(0, 0, 0, 150)
local function DrawArrestHUD(ply, scrw, scrh, cur_time)
	time = ply:getDarkRPVar("ArrestTime")
	if time and time!= 0 then
		surface_SetFont("arrestedf")
		time = math.max(math.abs(cur_time - time), 0)
		text = "Du wirst in "..string.ToMinutesSeconds(time).." min aus der Haft entlassen."
		w, h = surface_GetTextSize(text)
		surface_SetDrawColor(box_color)
		surface_SetTextColor(color_white)
		ybase = scrh - 80 - padding - h
		surface_DrawRect(scrw / 2 - w / 2 - padding, ybase - padding, w + (padding * 2), h + (padding * 2))
		surface_SetTextPos(scrw / 2 - w / 2, ybase)
		surface_DrawText(text)
	end
end

local hungershown = false
local function DrawHungerAlarm()
	if hungershown then return end
	chat.AddText(Color(205, 45, 2), "Du verhungerst!")
	surface.PlaySound("buttons/button8.wav")
	hungershown = true
end

local avatar, wep
local function DrawPlayerAvatar(ply, scrw, scrh)
	if !IsValid(avatar) then
		avatar = vgui.Create("AvatarImage")
		avatar:SetPos(64, scrh - 130)
		avatar:SetSize(56, 56)
		avatar:SetPlayer(ply, 64)
		avatar:ParentToHUD()
		avatar.Think = function(self)
			wep = ply:GetActiveWeapon()
			if wep:IsValid() and wep:GetClass() == "gmod_camera" then
				self:Remove()
			end
		end
		avatar.OnScreenSizeChanged = function(self)
			self:SetPos(64, ScrH() - 130)
		end
	end
end

local function RemovePlayerAvatar()
	if IsValid(avatar) then
		avatar:Remove()
	end
end

local foodicons_alpha = -1
local foodicons_y = 0
local function AddFoodIcon()
	foodicons_alpha = 1
	foodicons_y = ScrH() - 105
end
usermessage.Hook("AteFoodIcon", AddFoodIcon)

local arrested = 0
local next_release = 0
local next_check = 0
local function GetArrestedPlayers()
	if next_check >= CurTime() then
		return arrested, next_release
	end
	next_check = CurTime() + 1
	arrested = 0
	next_release = math.huge
	for _, v in ipairs(player.GetAll()) do
		if v:isArrested() then
			arrested = arrested + 1
			local time_left = math.max(math.abs(cur_time - v:getDarkRPVar("ArrestTime")), 0)
			if time_left and time_left < next_release then
				next_release = time_left
			end
		end
	end
	if next_release == math.huge then
		next_release = "X"
	end
	return arrested, next_release
end

local health_lerp, armor_lerp, money_lerp = 0, 0, 0
local ply_health, ply_maxhealth, ply_armor, ply_name, ply_team, ply_job, ply_hunger, ply_money
local nfont, jfont, mfont, jof, hof, mof, scrw, scrh, scrh_2, scrh_3, scrh_4, scrh_5, scrh_6, scrh_7, w, h, hungercolor, moneycolor, health_draw, armor_draw, wanted
local invis, god, noclip = utf8.char(9201), utf8.char(9876), utf8.char(9992)
local license = Material("icon16/page.png")
local colors = {
	boxcolor = Color(38, 38, 38, 255),
	boxcolor2 = Color(54, 54, 54, 255),
	boxcolor3 = Color(0, 0, 0, 200),
	jobcolor = Color(220, 220, 220, 255),
	loancolor = Color(200, 200, 200, 255),
	textcolor = Color(255, 255, 255, 200),
	healthcolor = Color(255, 40, 40, 180),
	reghealthcolor = Color(255, 40, 40, 25),
	armorcolor = Color(40, 40, 255, 255),
	plusmoneycolor = Color(100, 255, 100),
	minusmoneycolor = Color(255, 100, 100)
}
local function DrawPlayerHUD(ply, scrw, scrh, cur_time, ply_team)
	draw_RoundedBox(4, 9, scrh - 143, 392, 134, color_black)
	scrh_2 = scrh - 142
	draw_RoundedBox(4, 10, scrh_2, 390, 132, colors.boxcolor)
	draw_RoundedBoxEx(4, 10, scrh_2, 40, 80, colors.boxcolor2, true, false, false, false)
	draw_RoundedBoxEx(4, 244, scrh_2, 156, 80, colors.boxcolor2, false, true, false, false)
	surface_SetDrawColor(color_black)
	scrh_3 = scrh - 102
	surface_DrawLine(10, scrh_3, 50, scrh_3)
	surface_SetDrawColor(61, 61, 61, 255)
	scrh_4 = scrh - 101
	surface_DrawLine(10, scrh_4, 50, scrh_4)
	surface_SetDrawColor(4, 4, 4, 255)
	scrh_5 = scrh - 62
	surface_DrawLine(10, scrh_5, 400, scrh_5)
	surface_SetDrawColor(61, 61, 61, 255)
	scrh_5 = scrh - 61
	surface_DrawLine(10, scrh_5, 400, scrh_5)
	surface_SetDrawColor(84, 84, 84, 255)
	scrh_5 = scrh - 142
	surface_DrawLine(11, scrh_5, 398, scrh_5)
	surface_SetDrawColor(24, 24, 24, 255)
	scrh_5 = scrh - 142
	scrh_6 = scrh - 62
	surface_DrawLine(244, scrh_5, 244, scrh_6)
	surface_SetDrawColor(24, 24, 24, 255)
	surface_DrawLine(50, scrh_5, 50, scrh_6)
	ply_name = ply:Name()
	surface_SetFont("namef")
	w = surface_GetTextSize(ply_name)
	if w > 100 then
		nfont = "namefsmall"
	else
		nfont = "namef"
	end
	surface_SetFont(nfont)
	w, h = surface_GetTextSize(ply_name)
	jof = h * 0.8 + 2
	if nfont == "namefsmall" and #ply_name > 20 then
		ply_name = string.sub(ply_name, 1, 20)..".."
	end
	draw_SimpleText(ply_name, nfont, 130, scrh - 134, color_white)
	ply_job = team.GetName(ply_team)
	surface_SetFont("jobf")
	w = surface_GetTextSize(ply_job)
	if w > 180 then
		jfont = "jobfxxsmall"
	elseif w > 140 then
		jfont = "jobfxsmall"
	elseif w > 100 then
		jfont = "jobfsmall"
	else
		jfont = "jobf"
	end
	surface_SetFont(jfont)
	w, h = surface_GetTextSize(ply_job)
	draw_SimpleText(ply_job, jfont, 130, scrh - 134 + jof, colors.jobcolor)
	ply_hunger = ply:getDarkRPVar("Energy") or 100
	ply_hunger = math.floor(ply_hunger)
	hungercolor = color_white
	if ply_hunger > 80 then
		hungershown = false
		hungercolor = Color(44, 201, 144, 255)
	elseif ply_hunger > 60 and ply_hunger <= 80 then
		hungershown = false
		hungercolor = Color(122, 201, 100, 255)
	elseif ply_hunger > 40 and ply_hunger <= 60 then
		hungershown = false
		hungercolor = Color(238, 230, 87, 255)
	elseif ply_hunger > 20 and ply_hunger <= 40 then
		hungershown = false
		hungercolor = Color(205, 88, 2, 255)
	elseif ply_hunger <= 20 then
		DrawHungerAlarm()
		hungercolor = Color(205, 45, 2, 255)
	end
	hof = jof + h * 0.8 + 4
	draw_SimpleText("Energie: "..ply_hunger, "hungerf", 130, scrh - 134 + hof, hungercolor)
	ply_money = ply:getDarkRPVar("money") or 0
	if math.Round(money_lerp) != ply_money then
		last_money = ply_money
		money_lerp = Lerp(FrameTime() * 8, money_lerp, ply_money or 0)
		moneycolor = money_lerp < last_money and colors.plusmoneycolor or money_lerp > last_money and colors.minusmoneycolor or color_white
	else
		moneycolor = color_white
	end
	ply_money = string.Comma(math.Round(money_lerp))
	surface_SetFont("moneyf")
	w = surface_GetTextSize(ply_money)
	if w > 180 then
		mfont = "moneyfsmall"
	elseif w > 140 then
		mfont = "moneyfxsmall"
	else
		mfont = "moneyf"
	end
	surface_SetFont(mfont)
	w, h = surface_GetTextSize(ply_money)
	mof = h * 0.8
	draw_SimpleText("$"..ply_money, mfont, 320, scrh - 132, moneycolor, TEXT_ALIGN_CENTER)
	if EconomyConfig then
		local taxes = EconomyConfig.TaxPayers and EconomyConfig.TaxPayers[ply_team] and (EconomyConfig.Taxes and EconomyConfig.Taxes[ply_team] or EconomyConfig.DefaultTaxes)
		draw_SimpleText("Lohn: $"..string.Comma(ply:getDarkRPVar("salary") or 0)..(taxes and " (-"..math.Round(taxes).."%)" or ""), "salaryf", 320, scrh - 132 + mof, colors.loancolor, TEXT_ALIGN_CENTER)
	else
		draw_SimpleText("Lohn: $"..string.Comma(ply:getDarkRPVar("salary") or 0), "salaryf", 320, scrh - 132 + mof, colors.loancolor, TEXT_ALIGN_CENTER)
	end
	scrh_7 = scrh - 53
	draw_RoundedBox(4, 80, scrh_7, 302, 16, colors.boxcolor3)
	ply_maxhealth = ply:GetMaxHealth()
	ply_health = ply:Health()
	health_lerp = math.min(ply_maxhealth, (health_lerp == ply_health and health_lerp) or Lerp(FrameTime() * 5, health_lerp, ply_health))
	health_draw = math.min(health_lerp / ply_maxhealth, 1)
	if health_draw > 0.01 then
		draw_RoundedBox(4, 81, scrh - 52, 300 * health_draw, 14, colors.healthcolor)
	end
	if ply_health < 25 and ply:Alive() then
		draw_RoundedBox(4, 81, scrh - 52, math.min(75 * (100 / ply_maxhealth), 300), 14, colors.reghealthcolor)
	end
	draw_SimpleText(math.max(0, math.ceil(ply_health)), "healthf", 231, scrh_7 - 1, colors.textcolor, TEXT_ALIGN_CENTER)
	draw_RoundedBox(4, 80, scrh - 34, 302, 16, colors.boxcolor3)
	ply_armor = ply:Armor()
	armor_lerp = math.min(100, (armor_lerp == ply_armor and armor_lerp) or Lerp(FrameTime() * 5, armor_lerp, ply_armor))
	armor_draw = math.min(armor_lerp / 100, 1)
	if armor_draw > 0.01 then
		draw_RoundedBox(4, 81, scrh - 33, 300 * armor_draw, 14, colors.armorcolor)
	end
	draw_SimpleText(math.max(0, math.ceil(ply_armor)), "healthf", 231, scrh - 34, colors.textcolor, TEXT_ALIGN_CENTER)
	draw_SimpleText("Leben:", "healthf2", 20, scrh - 54, color_white, TEXT_ALIGN_LEFT)
	draw_SimpleText("Rüstung:", "healthf2", 20, scrh - 36, color_white, TEXT_ALIGN_LEFT)
	wanted = ply:isWanted()
	draw_SimpleText("!", "wantf", 30, scrh - 98, wanted and Color(math.sin(cur_time * 3) * 255, 0, 0) or color_black, TEXT_ALIGN_CENTER)
	if wanted then
		local text = "Gesucht wegen "..ply:getDarkRPVar("wantedReason").."."
		local sin = math.sin(cur_time * 3) * 255
		local color = Color(255, sin, sin)
		draw_SimpleTextOutlined(text, "wantxtf", 10, scrh - 165, color, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
	end
	if ply:getDarkRPVar("HasGunlicense") then
		surface_SetDrawColor(color_white)
	else
		surface_SetDrawColor(color_black)
	end
	surface_SetMaterial(license)
	surface_DrawTexturedRect(20, scrh - 130, 20, 20)
	DrawPlayerAvatar(ply, scrw, scrh)
	if foodicons_alpha > -1 then
		local mul = 1
		if foodicons_y <= scrh - 175 then
			mul = -0.5
		end
		local alpha = foodicons_alpha * 255
		draw_DrawNonParsedSimpleText("++", "foodf", 137, foodicons_y + 1, Color(0, 0, 0, alpha), 0)
		draw_DrawNonParsedSimpleText("++", "foodf", 136, foodicons_y, Color(20, 100, 20, alpha), 0)
		local ftime = FrameTime()
		foodicons_alpha = math.Clamp(foodicons_alpha + 4 * ftime * mul, -1, 1)
		foodicons_y = foodicons_y - 50 * ftime
	end
end

local icon_offx, icon_offy
local function DrawIconHUD(ply, scrw, scrh, cur_time)
	icon_offx = 0
	icon_offy = 0
	if ply:GetNoDraw() and !ply:IsFrozen() then
		draw_SimpleTextOutlined(invis, "iconf", 408, scrh - 156, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
		draw_SimpleTextOutlined("Unsichtbar", "adminf", 450, scrh - 130, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
		icon_offy = 40
	end
	if ply:HasGodMode() and !ply:IsFrozen() then
		draw_SimpleTextOutlined(god, "iconf", 410, scrh - 156 + icon_offy, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
		draw_SimpleTextOutlined("Unbesiegbar", "adminf", 450, scrh - 130 + icon_offy, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
		icon_offy = icon_offy + 40
		if icon_offy == 80 then
			icon_offy = 0
			icon_offx = 140
		end
	end
	if ply:GetMoveType() == MOVETYPE_NOCLIP and !ply:IsFrozen() and !ply:InVehicle() then
		draw_SimpleTextOutlined(noclip, "iconf", 400 + icon_offx, scrh - 150 + icon_offy, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
		draw_SimpleTextOutlined("Im Flug", "adminf", 450 + icon_offx, scrh - 130 + icon_offy, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
	end
end

local show_props = {
	["weapon_physgun"] = true,
	["weapon_physcannon"] = true,
	["gmod_tool"] = true
}

local hide_name = {
	["glorifiedbanking_card"] = true
}

local w, ammo_x, ammo_y, ammo_typ, ammo_typ2, clip, clip1_clr, clip1_txt, clip1_txtsize, clip2, clip2_clr, clip2_txtsize, clip2_txt, spacer_txtsize, clip3, box_x, wep, wep_name, wep_class, wep_drawprops, prop_limit, fire_mode, silenced, wep_hud, wep_huduse, origin_pos
local box_color, depleted_color, spacer_txt = Color(54, 54, 54, 150), Color(255, 125, 125, 255), " / "
local function DrawAmmoHUD(ply, scrw, scrh)
	wep = ply:GetActiveWeapon()
	if wep:IsValid() then
		local veh = ply:GetVehicle()
		if veh:IsValid() and !ply:GetAllowWeaponsInVehicle() then return end
		wep_class = wep:GetClass()
		if hide_name[wep_class] then return end
		wep_name = wep:GetPrintName() or wep_class or "Unbekannt"
		surface_SetFont("weaponf")
		w = surface_GetTextSize(wep_name)
		w = math.max(150, w + 20)
		ammo_x = scrw - 20
		ammo_y = scrh - 110
		box_x = ammo_x - w
		DrawRect(box_x, ammo_y, w, 40, box_color)
		DrawRect(box_x - 2, ammo_y - 2, w + 4, 44, box_color)
		draw_SimpleText(wep_name, "weaponf", ammo_x - w / 2, ammo_y + 4, color_white, TEXT_ALIGN_CENTER)
		wep_drawprops = show_props[wep_class]
		if wep_drawprops then
			prop_limit = ply:GetCount("props")
			prop_limit = prop_limit == 1 and prop_limit.." Prop" or prop_limit.." Props"
			DrawRect(box_x, ammo_y + 50, w, 40, box_color)
			DrawRect(box_x - 2, ammo_y + 50 - 2, w + 4, 44, box_color)
			draw_SimpleText(prop_limit, "weaponf", ammo_x - w / 2, ammo_y + 54, color_white, TEXT_ALIGN_CENTER)
		end
		if (wep.CanLower or wep.CanSelectFire) and wep.GetFireMode then
			fire_mode = wep:GetFireMode()
			fire_mode = fire_mode == "auto" and "Auto." or fire_mode == "semi" and "Semi." or fire_mode == "burst" and "Ausbr." or "Sicher"
			DrawRect(ammo_x - 70, ammo_y - 28, 70, 20, box_color)
			DrawRect(ammo_x - 70 - 2, ammo_y - 28 - 2, 70 + 4, 24, box_color)
			draw_SimpleText(fire_mode, "ammofsmall", ammo_x - 36, ammo_y - 30, color_white, TEXT_ALIGN_CENTER)
		end
		if wep.CanSilence and wep.GetSilenced then
			silenced = wep:GetSilenced()
			silenced = wep:GetSilencing() and "..." or silenced and "Leise" or "Laut"
			DrawRect(box_x, ammo_y - 28, 70, 20, box_color)
			DrawRect(box_x - 2, ammo_y - 28 - 2, 70 + 4, 24, box_color)
			draw_SimpleText(silenced, "ammofsmall", box_x + 34, ammo_y - 30, color_white, TEXT_ALIGN_CENTER)
		end
		if wep_drawprops or wep.DrawAmmo == false then return end
		ammo_typ = wep:GetPrimaryAmmoType()
		ammo_typ2 = wep:GetSecondaryAmmoType()
		wep_hud = wep.CustomAmmoDisplay and wep:CustomAmmoDisplay()
		wep_huduse = wep_hud and wep_hud.Draw
		if ammo_typ != -1 or ammo_typ2 != -1 or wep_huduse then
			DrawRect(box_x, ammo_y + 50, w, 40, box_color)
			DrawRect(box_x - 2, ammo_y + 50 - 2, w + 4, 44, box_color)
			if wep_huduse then
				local primary = wep_hud.PrimaryClip and wep_hud.PrimaryClip or ""
				local spare = wep_hud.PrimaryAmmo and wep_hud.PrimaryAmmo or ""
				local secondary = wep_hud.SecondaryAmmo and wep_hud.SecondaryAmmo or ""
				spare = spare != "" and (primary != "" and " / "..spare) or spare
				secondary = secondary != "" and (primary != "" or spare != "" and " / "..secondary) or secondary
				draw_SimpleText(primary..spare..secondary, "ammof", ammo_x - w / 2, ammo_y + 54, color_white, TEXT_ALIGN_CENTER)
			else
				if ammo_typ == -1 then
					clip3 = ply:GetAmmoCount(ammo_typ2)
					draw_SimpleText(clip3, "ammof", ammo_x - w / 2, ammo_y + 54, color_white, TEXT_ALIGN_CENTER)
				elseif ammo_typ2 == -1 then
					clip = wep:Clip1()
					clip2 = ply:GetAmmoCount(ammo_typ)
					if clip == -1 then
						draw_SimpleText(clip2, "ammof", ammo_x - w / 2, ammo_y + 54, color_white, TEXT_ALIGN_CENTER)
					else
						clip1_clr = clip / (wep.Primary and wep.Primary.ClipSize or 0) <= 0.25 and depleted_color or color_white
						clip1_txt = clip
						surface_SetFont("ammof")
						clip1_txtsize = surface_GetTextSize(clip1_txt)
						clip2_clr = clip2 < (wep.Primary and wep.Primary.ClipSize or 0)and depleted_color or color_white
						clip2_txt = clip2
						clip2_txtsize = surface_GetTextSize(clip2_txt)
						origin_pos = ammo_x - w / 2
						spacer_txtsize = surface_GetTextSize(spacer_txt)
						draw_SimpleText(clip1_txt, "ammof", origin_pos - clip1_txtsize / 2 - clip2_txtsize / 2 - spacer_txtsize / 2, ammo_y + 54, clip1_clr, TEXT_ALIGN_LEFT)
						draw_SimpleText(spacer_txt, "ammof", origin_pos + clip1_txtsize / 2 - spacer_txtsize / 2 - clip2_txtsize / 2, ammo_y + 54, color_white, TEXT_ALIGN_LEFT)
						draw_SimpleText(clip2_txt, "ammof", origin_pos + clip1_txtsize / 2 + spacer_txtsize / 2 - clip2_txtsize / 2, ammo_y + 54, clip2_clr, TEXT_ALIGN_LEFT)
					end
				else
					clip = wep:Clip1()
					clip2 = ply:GetAmmoCount(ammo_typ)
					clip3 = ply:GetAmmoCount(ammo_typ2)
					draw_SimpleText(clip.." / "..clip2.." / "..clip3, "ammof", ammo_x - w / 2, ammo_y + 54, color_white, TEXT_ALIGN_CENTER)
				end
			end
		end
	end
end

arrest_view_tms = {}
timer.Simple(0, function()
	arrest_view_tms = {
		[TEAM_LAWYER] = true,
		[TEAM_JAILGUARD] = true,
	}
end)

local function DrawExtraHUD(ply, scrw, scrh, cur_time, ply_team)
	if zrush and zrush.config.Jobs[ply_team] then
		draw_SimpleTextOutlined("Treibstoff: "..string.Comma(zrush.InventoryAmt or 0).." / "..string.Comma(zrush.config.Player.FuelInvSize).."l", "namef", 410, scrh - 30, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
	elseif arrest_view_tms[ply_team] then
		arrested, next_release = GetArrestedPlayers()
		draw_SimpleTextOutlined("Inhaftierte Personen: "..arrested, "namef", 410, scrh - 50, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
		draw_SimpleTextOutlined("Nächste Freilassung: "..(next_release == "X" and next_release or string.ToMinutesSeconds(next_release)), "namef", 410, scrh - 30, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP, 1, color_black)
	end
end

local max_dist = 400 * 400 -- +100
local max_dist2 = 300 * 300

local plys_to_render = {}
local function CheckForPlayers()
	local ply = LocalPlayer()
	if !ply:IsValid() then return end
	plys_to_render = {}
	local pos = ply:EyePos()
	for _, v in ipairs(player.GetAll()) do
		if pos:DistToSqr(v:EyePos()) <= max_dist and ply != v then
			table.insert(plys_to_render, v)
		end
	end
end
timer.Create("DarkRP_CheckForPlayers", 0.1, 0, CheckForPlayers)

local globalshow = GAMEMODE.Config.globalshow
local function DrawEntityDisplay(ply)
	local shootPos, aimVec
	for _, v in ipairs(plys_to_render) do
		if !v:IsValid() or not v:Alive() or v:GetNoDraw() or v:IsDormant() then continue end
		shootPos = shootPos or ply:GetShootPos()
		aimVec = aimVec or ply:GetAimVector()
		local hisPos = v:GetShootPos()
		if v:getDarkRPVar("wanted") then
			v:drawWantedInfo()
		end
		if globalshow then
			v:drawPlayerInfo()
		elseif hisPos:DistToSqr(shootPos) < max_dist2 then
			local pos = hisPos - shootPos
			local unitPos = pos:GetNormalized()
			if unitPos:Dot(aimVec) > 0.95 then
				local trace = util.QuickTrace(shootPos, pos, ply)
				if trace.Hit and trace.Entity ~= v then
					if trace.Entity:IsPlayer() then
						trace.Entity:drawPlayerInfo()
					end
					break
				end
				v:drawPlayerInfo()
			end
		end
	end
	local ent = ply:GetEyeTrace().Entity
	if IsValid(ent) and ent:isKeysOwnable() and ent:GetPos():DistToSqr(ply:GetPos()) < 40000 then
		ent:drawOwnableInfo()
	end
end

local function DrawEverything()
	ply, scrw, scrh, cur_time = ply or LocalPlayer(), ScrW(), ScrH(), CurTime()
	ply_team = ply:Team()
	
	DrawPlayerHUD(ply, scrw, scrh, cur_time, ply_team)
	DrawExtraHUD(ply, scrw, scrh, cur_time, ply_team)
	DrawIconHUD(ply, scrw, scrh, cur_time, ply_team)
	DrawAmmoHUD(ply, scrw, scrh, cur_time, ply_team)
	DrawAgendaHUD(ply, scrw, scrh, cur_time, ply_team)
	DrawLockdownHUD(ply, scrw, scrh, cur_time, ply_team)
	DrawArrestHUD(ply, scrw, scrh, cur_time, ply_team)
	DrawEntityDisplay(ply, scrw, scrh, cur_time, ply_team)
end
hook.Add("HUDPaint", "DarkRP_HUD", DrawEverything)