if SERVER then
	AddCSLuaFile()
end

ENT.Base = "base_anim"
ENT.Type = "anim"
ENT.Category = "Sicherheit"
ENT.Spawnable = true
ENT.PrintName = "Metaldetektor"
ENT.RenderGroup = RENDERGROUP_BOTH

function ENT:SetupDataTables()
	self:NetworkVar("Entity", 0, "owning_ent")
	self:NetworkVar("Int", 0, "State")
end

function ENT:PhysgunPickup(ply)
	return ply == self:Getowning_ent() or ply:IsAdmin()
end

function ENT:CanTool(ply, trace, mode)
	return mode == "remover" and ply == self:Getowning_ent() or mode == "remover" and ply:IsAdmin()
end

if SERVER then
	util.AddNetworkString("MetalDetector_Remove")

	net.Receive("MetalDetector_Remove", function(len, ply)
		local ent = net.ReadEntity()
		if !ply:Alive() or !IsValid(ent) or ent:GetClass() != "metal_detector" or ply:GetPos():DistToSqr(ent:GetPos()) > 10000 then return end
		if !ply.LastUsedEntity or ply.LastUsedEntity[1] != ent then return end
		ply.LastUsedEntity = nil
		local owning_ent = ent:Getowning_ent()
		if IsValid(owning_ent) and ply == owning_ent then
			constraint.RemoveAll(ent)
			ent:SetNotSolid(true)
			ent:SetMoveType(MOVETYPE_NONE)
			ent:SetNoDraw(true)
			local ed = EffectData()
			ed:SetEntity(ent)
			util.Effect("entity_remove", ed, true, true)
			timer.Simple(1, function()
				if IsValid(ent) then
					ent:Remove()
				end
			end)
		end
	end)

	function ENT:Initialize()
		self:SetModel("models/props_wasteland/interior_fence002e.mdl")
		self:PhysicsInit(SOLID_VPHYSICS)
		self:SetUseType(SIMPLE_USE)
		self:SetMoveType(MOVETYPE_VPHYSICS)
		self:SetSolid(SOLID_VPHYSICS)
		local phys = self:GetPhysicsObject()
		if IsValid(phys) then
			phys:EnableMotion(false)
		end
		local owning_ent = self:Getowning_ent()
		if IsValid(owning_ent) then
			self:CPPISetOwner(owning_ent)
		end
		self:SetState(0)
		self.LastEntity = nil
		self.Ticks = 0
		self.Found = false
	end

	function ENT:SpawnFunction(ply, tr, ClassName)
		if !tr.Hit then return end
		local SpawnPos = tr.HitPos + tr.HitNormal * 65
		local SpawnAng = ply:EyeAngles()
		SpawnAng.p = 0
		SpawnAng.y = SpawnAng.y + 180
		local ent = ents.Create(ClassName)
		if !IsValid(ent) then return end
		ent:SetPos(SpawnPos)
		ent:SetAngles(SpawnAng)
		ent:Spawn()
		ent:Activate()
		return ent
	end

	function ENT:Use(activator)
		if !activator:IsPlayer() then return end
		if activator.LastUsedEntity then
			if activator.LastUsedEntity[2] > CurTime() then
				return
			end
		end
		activator.LastUsedEntity = {self, CurTime() + 0.25}
		local owning_ent = self:Getowning_ent()
		if IsValid(owning_ent) and activator == owning_ent then
			net.Start("MetalDetector_Remove")
				net.WriteEntity(self)
			net.Send(activator)
		end
	end

	local AllowedClasses = {
		["player"] = true,
		["spawned_ammo"] = true,
		["spawned_weapon"] = true,
		["spawned_shipment"] = true
	}
	
	function ENT:Think()
		local cur_time = CurTime()
		if self.LastEntity and self.Ticks < cur_time then
			self.Ticks = 0
			self.LastEntity = nil
			self:SetState(0)
		end
		local pos = self:GetPos()
		local tr = {
			start = pos, 
			endpos = pos, 
			filter = self, 
			mins = self:OBBMins() * 0.75, 
			maxs = self:OBBMaxs() * 0.75,
			filter = function(ent)
				if AllowedClasses[ent:GetClass()] then
					return true
				end
				return false
			end
		}
		local trace = util.TraceHull(tr)
		local ent = trace.Entity
		if IsValid(ent) then
			if self.LastEntity != ent then
				if self:GetState() != 1 then
					local class = ent:GetClass()
					if class == "player" then
						local w
						for _,v in pairs(ent:GetWeapons()) do
							if MetalDetector.WhiteList[v:GetClass()] != true then
								w = true
							end
						end
						for _,v in pairs(ent:getPocketItems()) do
							if v.class and MetalDetector.WhiteList[v.class] != true then
								w = true
							end
						end
						if w then
							self.LastEntity = ent
							self.Ticks = cur_time + 1
							self:EmitSound("buttons/button8.wav", MetalDetector.BuzzSoundLevel, MetalDetector.BuzzPitchPercent)
							self:SetState(1)
						else
							self.LastEntity = ent
							self.Ticks = cur_time + 1
							self:EmitSound("buttons/button3.wav", MetalDetector.DingSoundLevel, MetalDetector.DingPitchPercent)
							self:SetState(2)
						end
					elseif ((class == "spawned_ammo" and MetalDetector.DetectAmmoBoxes) or (class == "spawned_weapon" and MetalDetector.DetectWeaponEntities) or (class == "spawned_shipment" and MetalDetector.DetectShipments)) then
						self.LastEntity = ent
						self.Ticks = cur_time + 1
						self:EmitSound("buttons/button8.wav", MetalDetector.BuzzSoundLevel, MetalDetector.BuzzPitchPercent)
						self:SetState(1)
					end
				end
			else
				self.Ticks = self.Ticks > cur_time + 0.1 and self.Ticks or cur_time + 0.25
			end
		end
		self:NextThink(cur_time)
		return true
	end
end

if CLIENT then
	local dist = MetalDetector.GUIFadeDistance * MetalDetector.GUIFadeDistance
	local local_ply, distance, pos
	local vector_1 = Vector(0, 0, 1)

	function ENT:Draw()
		self:DrawModel()
	end

	function ENT:DrawTranslucent()
		local_ply = local_ply or LocalPlayer()
		pos = self:GetPos()
		distance = local_ply:EyePos():DistToSqr(self:GetPos())
		if distance >= dist then return end
		local ang = self:GetAngles()
		ang:RotateAroundAxis(ang:Up(), 90)
		ang:RotateAroundAxis(ang:Forward(), 90)
		local up, forward = self:GetUp(), self:GetForward()
		local state = self:GetState()
		cam.Start3D2D(pos + (up * 11), ang, 0.1)
			draw.RoundedBox(0, -230, -490, 450, 130, (((state == 0) and color_black) or ((state == 1) and Color(255, 0, 0, 255)) or ((state == 2) and Color(0, 255, 0, 255))))
		cam.End3D2D()
		cam.Start3D2D(pos + (up * 11) + (forward * 0.2), ang, 0.1)
			draw.RoundedBox(0, -230, -490, 450, 130, (((state == 0) and color_black) or ((state == 1) and Color(255, 0, 0, 255)) or ((state == 2) and Color(0, 255, 0, 255))))
		cam.End3D2D()
		local owner = self:Getowning_ent()
		surface.SetFont("HUDNumber5")
		owner = IsValid(owner) and owner:Name() or DarkRP.getPhrase("unknown")
		local size = surface.GetTextSize(owner)
		cam.Start3D2D(pos + (up * 11) + (forward * 1.7), ang, 0.1)
			surface.SetFont("HUDNumber5")
			draw.WordBox(2, -size / 2 + 275, -30, owner, "HUDNumber5", Color(140, 0, 0, 100), color_white)
		cam.End3D2D()
		ang:RotateAroundAxis(ang:Up(), 180)
		ang:RotateAroundAxis(ang:Forward(), 180)
		cam.Start3D2D(pos + (up * 11) + (forward * -1.7), ang, 0.1)
			surface.SetFont("HUDNumber5")
			draw.WordBox(2, -size / 2 + 275, -30, owner, "HUDNumber5", Color(140, 0, 0, 100), color_white)
		cam.End3D2D()
	end
end