
util.AddNetworkString("RHC_Jailer_Menu")
util.AddNetworkString("RHC_jail_player")
util.AddNetworkString("RHC_Bailer_Menu")
util.AddNetworkString("RHC_bail_player")
util.AddNetworkString("RHC_add_npc_jailpos")

concommand.Add("save_rhc_npcs", function(Player, CMD, Args)
	if !Player:IsAdmin() then return end

	local NPCTbl = {}		
	for k,v in pairs(ents.FindByClass("npc_jailer")) do
		local tr = util.TraceLine( {
			start = v:GetPos(),
			endpos = v:GetPos()-Vector(0,0,50),
			filter = {"npc_jailer"}
		} )
		
		local NPCIns = {}
		NPCIns.Pos = tr.HitPos
		NPCIns.Angles = v:GetAngles()
		NPCIns.Ent = v:GetClass()
		if v.JailPos then
			NPCIns.JailPos = v.JailPos
		end
		
		table.insert(NPCTbl,NPCIns)
	end
	
	for k,v in pairs(ents.FindByClass("npc_bailer")) do
		local tr = util.TraceLine( {
			start = v:GetPos(),
			endpos = v:GetPos()-Vector(0,0,50),
			filter = {"npc_bailer"}
		})
		
		local NPCIns = {}
		NPCIns.Pos = tr.HitPos
		NPCIns.Angles = v:GetAngles()
		NPCIns.Ent = v:GetClass()
		table.insert(NPCTbl,NPCIns)
	end	
		
	local CurrentMap = string.lower(game.GetMap())	
	file.Write("rhandcuffs/npcs/" .. CurrentMap .. ".txt", util.TableToJSON(NPCTbl))

	TBFY_Notify(Player, 1, 4, "Successfully saved " .. #NPCTbl .. " NPCs.")
end)

function RHandCuffsNPCSpawn()
	local CurrentMap = string.lower(game.GetMap())
	
	local NPCLocTable = {}
	if file.Exists( "rhandcuffs/npcs/" .. CurrentMap .. ".txt" ,"DATA") then
		NPCLocTable = util.JSONToTable(file.Read( "rhandcuffs/npcs/" .. CurrentMap .. ".txt" ))
	end
	
	for k,v in pairs(NPCLocTable) do		
		local PNPC = ents.Create(v.Ent)
		PNPC:SetPos(v.Pos)
		PNPC:SetAngles(v.Angles)
		PNPC:Spawn()
		local Phys = PNPC:GetPhysicsObject()
		if Phys then
			Phys:EnableMotion(false)
		end
		if v.JailPos then
			PNPC.JailPos = v.JailPos
		end
	end
end
hook.Add("InitPostEntity", "RHandCuffsNPCSpawn", RHandCuffsNPCSpawn)

hook.Add("PostCleanupMap", "RepsawnJailerNPCCleanup", function()
	RHandCuffsNPCSpawn()
end)

hook.Add("canArrest", "MustBeArrestAtJailerNPC", function(Player, ArrestedPlayer)
    if RHandcuffsConfig.NPCArrestOnly then
        return false,"Talk with the jailer NPC while dragging a player in order to arrest."
    end
end)

local RHC_DCAPlayers = {}
net.Receive("RHC_jail_player", function(len, Player)
	local APlayer, Time, Reason = net.ReadEntity(), net.ReadFloat(), net.ReadString()
	if APlayer != Player.Dragging or !Player:IsRHCWhitelisted() or !APlayer.Restrained then return end
	if APlayer:RHC_IsArrested() then TBFY_Notify(Player, 1, 4, "This player is already arrested!")   return end
	
	Time = math.Clamp(math.Round(Time), 1, RHandcuffsConfig.MaxJailYears)
	Time = Time*60
	
	APlayer:RHC_Arrest(Time, Player, Reason, true)
	
	TBFY_Notify(APlayer, 1, 4, "You were jailed by " .. Player:Nick() .. " for " .. Time .. " seconds. Reason: " .. Reason)
	
	hook.Call("rhc_jailed_player", GAMEMODE, APlayer, Player, Time, Reason)
end)

hook.Add("PlayerInitialSpawn", "RHC_RejailIfJailTime", function(Player)
	//So player can fully load in first
	timer.Simple(10, function()
		if IsValid(Player) then
			local SID = Player:SteamID()
			local CheckJailTime = RHC_DCAPlayers[SID]
			if CheckJailTime and CheckJailTime > 0 then
				Player:RHC_Arrest(CheckJailTime, nil)
				RHC_DCAPlayers[SID] = nil
			else
				net.Start("rhc_update_jailtime")
					net.WriteBool(false)
					net.WriteFloat(0)
					net.WriteString(SID)
					net.WriteString("")
				net.Broadcast()				
			end
		end
	end)
end)

hook.Add("PlayerDisconnected", "RHC_SaveJailTime", function(Player)
	if Player:RHC_IsArrested() then
		local JailTimeLeft = Player:RHC_GetATime()
		if JailTimeLeft > 0 then
			RHC_DCAPlayers[Player:SteamID()] = JailTimeLeft
		end
	end
end)

net.Receive("RHC_add_npc_jailpos", function(len, Player)
	local Ent, Pos = Player.LastEntC, net.ReadVector()
	
	Ent.JailPos = Ent.JailPos or {}
	table.insert(Ent.JailPos, Pos)
	
	TBFY_Notify(Player, 1, 4, "Successfully added jailposition to last placed Jailer NPC.")
end)

net.Receive("RHC_bail_player", function(len, Player)
	local ToBailP = net.ReadEntity()
	if !IsValid(ToBailP) or !ToBailP:IsPlayer() or !ToBailP:RHC_IsArrested() then return end
	if RHandcuffsConfig.RestrictBailing and !activator:CanRHCBail() then return end
	
	local BailCost = ToBailP:RHC_GetATime()/60 * RHandcuffsConfig.BailPricePerYear
	if Player:canAfford(BailCost) then
		ToBailP:RHC_UnArrest()
		Player:addMoney(-BailCost)
		ToBailP.RHC_JailTime = nil
		TBFY_Notify(Player, 1, 4, "You successfully bailed " .. ToBailP:Nick() .. " out of jail.")
	end
end)

local TGBlacklist = {"rhandcuffsent","npc_jailer"}
hook.Add("CanTool", "DisableRemovingRHCEntsTool", function(Player, trace, tool)
    local ent = trace.Entity
	if table.HasValue(TGBlacklist, ent:GetClass()) then
		if !Player:IsAdmin() then
			return false
		end
	end
end)

hook.Add("CanProperty", "DisableRemovingRHCEntsProperty", function(Player, stringproperty, ent)
	if table.HasValue(TGBlacklist, ent:GetClass()) then
		if !Player:IsAdmin() then
			return false
		end
	end
end)
