DarkRP.registerDarkRPVar("ArrestTime", fp{fn.Flip(net.WriteInt), 32}, fp{net.ReadInt, 32})

if CLIENT then
	surface.CreateFont("police_font", {font = "BebasNeue", size = 30, weight = 500, blursize = 0, scanlines = 0, antialias = true})

	local hook_exists = false

	local screen_messages = {}
	local function PoliceMessage()
		if #screen_messages == 0 then
			hook_exists = false
			hook.Remove("HUDPaint", "DarkRP_PoliceMessage")
		end
		local sys_time = SysTime()
		local font = "police_font"
		local scrw = ScrW()
		local scrh = ScrH()
		for k, v in ipairs(screen_messages) do
			if v[2] < sys_time then
				table.remove(screen_messages, k)
				break
			end
			if !screen_messages[k][4] then
				screen_messages[k][2] = sys_time + v[3]
				screen_messages[k][4] = true
			end
			local origin = scrh / 3
			local order = 0
			for i=#v[1], 1, -1 do
				order = order + 1
				draw.SimpleTextOutlined(v[1][i], "police_font", scrw / 2, origin - ((order - 1) * 34), Color(225, 225, 225, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM, 1, color_black)
			end
			break
		end
	end

	net.Receive("DarkRP_PoliceMessage", function()
		local str = net.ReadString()
		MsgC(Color(50, 50, 200), str.."\n")
		local texts = string.Split(str, "\n")
		local add_time = math.Clamp(#texts * 2, 2.5, 4.5)
		if #screen_messages > 10 then
			table.remove(screen_messages, #screen_messages)
		end
		table.insert(screen_messages, {texts, SysTime() + add_time, add_time})
		if !hook_exists then
			hook_exists = true
			hook.Add("HUDDrawTargetID", "DarkRP_PoliceMessage", PoliceMessage)
		end
	end)
end

local plyMeta = FindMetaTable("Player")
function plyMeta:isArrested()
	return self:getDarkRPVar("Arrested")
end

function plyMeta:isWanted()
	return self:getDarkRPVar("wanted")
end

function plyMeta:getWantedReason()
	return self:getDarkRPVar("wantedReason")
end

function plyMeta:isCP()
	return GAMEMODE.CivilProtection and GAMEMODE.CivilProtection[self:Team()] or false
end

plyMeta.isMayor = fn.Compose{fn.Curry(fn.GetValue, 2)("mayor"), plyMeta.getJobTable}
plyMeta.isChief = fn.Compose{fn.Curry(fn.GetValue, 2)("chief"), plyMeta.getJobTable}

function DarkRP.hooks:canRequestWarrant(target, actor, reason)
	if !reason or string.len(reason) == 0 then return false, DarkRP.getPhrase("vote_specify_reason") end
	if string.len(reason) > 200 then return false, DarkRP.getPhrase("too_long") end
	if !IsValid(target) then return false, DarkRP.getPhrase("suspect_doesnt_exist") end
	if !IsValid(actor) then return false, DarkRP.getPhrase("actor_doesnt_exist") end
	if !actor:Alive() then return false, DarkRP.getPhrase("must_be_alive_to_do_x", DarkRP.getPhrase("get_a_warrant")) end
	if target.warranted then return false, DarkRP.getPhrase("already_a_warrant") end
	if !actor:isCP() then return false, DarkRP.getPhrase("incorrect_job", DarkRP.getPhrase("get_a_warrant")) end
	return true
end

function DarkRP.hooks:canRemoveWarrant(target, actor)
	if !IsValid(target) then return false, DarkRP.getPhrase("suspect_doesnt_exist") end
	if !IsValid(actor) then return false, DarkRP.getPhrase("actor_doesnt_exist") end
	if !actor:Alive() then return false, DarkRP.getPhrase("must_be_alive_to_do_x", DarkRP.getPhrase("remove_a_warrant")) end
	if !target.warranted then return false, DarkRP.getPhrase("not_warranted") end
	if !actor:isCP() then return false, DarkRP.getPhrase("incorrect_job", DarkRP.getPhrase("remove_a_warrant")) end
	if actor:isArrested() then return false, DarkRP.getPhrase("unable", DarkRP.getPhrase("remove_a_warrant"), "") end
	return true
end

function DarkRP.hooks:canWanted(target, actor, reason)
	if !reason or string.len(reason) == 0 then return false, DarkRP.getPhrase("vote_specify_reason") end
	if string.len(reason) > 200 then return false, DarkRP.getPhrase("too_long") end
	if !IsValid(target) then return false, DarkRP.getPhrase("suspect_doesnt_exist") end
	if !IsValid(actor) then return false, DarkRP.getPhrase("actor_doesnt_exist") end
	if !actor:Alive() then return false, DarkRP.getPhrase("must_be_alive_to_do_x", DarkRP.getPhrase("make_someone_wanted")) end
	if !actor:isCP() then return false, DarkRP.getPhrase("incorrect_job", DarkRP.getPhrase("make_someone_wanted")) end
	if target:isWanted() then return false, DarkRP.getPhrase("already_wanted") end
	if !target:Alive() then return false, DarkRP.getPhrase("suspect_must_be_alive_to_do_x", DarkRP.getPhrase("make_someone_wanted")) end
	if target:isArrested() then return false, DarkRP.getPhrase("suspect_already_arrested") end
	return true
end

function DarkRP.hooks:canUnwant(target, actor)
	if !IsValid(target) then return false, DarkRP.getPhrase("suspect_doesnt_exist") end
	if !IsValid(actor) then return false, DarkRP.getPhrase("actor_doesnt_exist") end
	if !actor:Alive() then return false, DarkRP.getPhrase("must_be_alive_to_do_x", DarkRP.getPhrase("remove_wanted_status")) end
	if !actor:isCP() then return false, DarkRP.getPhrase("incorrect_job", DarkRP.getPhrase("remove_wanted_status")) end
	if !target:isWanted() then return false, DarkRP.getPhrase("not_wanted") end
	if !target:Alive() then return false, DarkRP.getPhrase("suspect_must_be_alive_to_do_x", DarkRP.getPhrase("remove_wanted_status")) end
	return true
end

for _, cmd in ipairs{"cr", "911", "999", "110", "112", "000"} do
	DarkRP.declareChatCommand{
		command = cmd,
		description = "Cry for help, the police will come (hopefully) !",
		delay = 1.5
	}
end

DarkRP.declareChatCommand{
	command = "warrant",
	description = "Get a search warrant for a certain player. With this warrant you can search their house.",
	delay = 1.5,
	condition = fn.FAnd{plyMeta.Alive, plyMeta.isCP, fn.Compose{fn.Not, plyMeta.isArrested}},
	tableArgs = true
}

DarkRP.declareChatCommand{
	command = "unwarrant",
	description = "Remove a search warrant for a certain player. With a warrant you can search their house.",
	delay = 1.5,
	condition = fn.FAnd{plyMeta.Alive, plyMeta.isCP, fn.Compose{fn.Not, plyMeta.isArrested}},
	tableArgs = true
}

DarkRP.declareChatCommand{
	command = "wanted",
	description = "Make a player wanted. This is needed to get them arrested.",
	delay = 1.5,
	condition = fn.FAnd{plyMeta.Alive, plyMeta.isCP, fn.Compose{fn.Not, plyMeta.isArrested}},
	tableArgs = true
}

DarkRP.declareChatCommand{
	command = "unwanted",
	description = "Remove a player's wanted status.",
	delay = 1.5,
	condition = fn.FAnd{plyMeta.Alive, plyMeta.isCP, fn.Compose{fn.Not, plyMeta.isArrested}}
}

DarkRP.declareChatCommand{
	command = "agenda",
	description = "Set the agenda.",
	delay = 1.5,
	condition = fn.Compose{fn.Not, fn.Curry(fn.Eq, 2)(nil), plyMeta.getAgenda}
}

DarkRP.declareChatCommand{
	command = "addagenda",
	description = "Add a line of text to the agenda.",
	delay = 1.5,
	condition = fn.Compose{fn.Not, fn.Curry(fn.Eq, 2)(nil), plyMeta.getAgenda}
}

DarkRP.declareChatCommand{
	command = "lottery",
	description = "Start a lottery.",
	delay = 1.5,
	condition = plyMeta.isMayor
}

DarkRP.declareChatCommand{
	command = "lockdown",
	description = "Start a lockdown. Everyone will have to stay inside.",
	delay = 1.5,
	condition = plyMeta.isMayor
}

DarkRP.declareChatCommand{
	command = "unlockdown",
	description = "Stop a lockdown.",
	delay = 1.5,
	condition = plyMeta.isMayor
}

DarkRP.declareChatCommand{
	command = "arrest",
	description = "Forcefully arrest a player.",
	delay = 0.5,
	tableArgs = true
}

DarkRP.declareChatCommand{
	command = "unarrest",
	description = "Forcefully unarrest a player.",
	delay = 0.5,
	tableArgs = true
}

local noMayorExists = fn.Compose{fn.Null, fn.Curry(fn.Filter, 2)(plyMeta.isMayor), player.GetAll}
local noChiefExists = fn.Compose{fn.Null, fn.Curry(fn.Filter, 2)(plyMeta.isChief), player.GetAll}

DarkRP.declareChatCommand{
	command = "requestlicense",
	description = "Request a gun license.",
	delay = 1.5,
	condition = fn.FAnd {
		fn.FOr {
			fn.Curry(fn.Not, 2)(noMayorExists),
			fn.Curry(fn.Not, 2)(noChiefExists),
			fn.Compose{fn.Not, fn.Null, fn.Curry(fn.Filter, 2)(plyMeta.isCP), player.GetAll}
		},
		fn.Compose{fn.Not, fn.Curry(fn.Flip(plyMeta.getDarkRPVar), 2)("HasGunlicense")},
		fn.Compose{fn.Not, fn.Curry(fn.GetValue, 2)("LicenseRequested")}
	}
}

DarkRP.declareChatCommand{
	command = "givelicense",
	description = "Give someone a gun license",
	delay = 1.5,
	condition = fn.FOr{
		plyMeta.isMayor,
		fn.FAnd{plyMeta.isChief, noMayorExists},
		fn.FAnd{plyMeta.isCP, noChiefExists, noMayorExists}
	}
}

DarkRP.declareChatCommand{
	command = "demotelicense",
	description = "Start a vote to get someone's license revoked.",
	delay = 1.5,
	tableArgs = true
}

DarkRP.declareChatCommand{
	command = "setlicense",
	description = "Forcefully give a player a license.",
	delay = 1.5
}

DarkRP.declareChatCommand{
	command = "unsetlicense",
	description = "Forcefully revoke a player's license.",
	delay = 1.5
}