if SERVER then 
	include("ballistic_shields/sh_bs_util.lua") 
	include("ballistic_shields/sv_bs_util.lua") 
end
include("bs_config.lua") 
include("ballistic_shields/sh_bs_lang.lua") 

SWEP.PrintName = "Platzierbares Schild"
SWEP.Instructions = "Linksklick zum Platzieren des Schildes.\nRechtsklick um die Sichtbarkeit zu Konfigurieren."
SWEP.Spawnable = true

SWEP.ViewModel = ""
SWEP.WorldModel = Model("models/bshields/dshield.mdl")

SWEP.AutoSwitchTo = false
SWEP.AutoSwitchFrom	= false

SWEP.Slot = 3
SWEP.SlotPos = 20
SWEP.DrawAmmo = false
SWEP.DrawCrosshair = false

SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "none"
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"

SWEP.CanVisToggle = 0
SWEP.VisToggle = false
SWEP.HitDistance = 55
SWEP.IsShield = true

function SWEP:Initialize()
	self:SetHoldType("melee2")
end

function SWEP:DrawWorldModel()
	self:SetNoDraw(true) 
end

local ShieldIcon = Material("bshields/ui/deployable_shield", "smooth")
local ShieldIconClosed = Material("bshields/ui/deployable_shield_closed", "smooth")
local BackgroundIcon = Material("bshields/ui/background")
function SWEP:DrawHUD()
	if (bshields.config.disablehud) then return end
	surface.SetDrawColor(255,255,255,200)	
	surface.SetMaterial(BackgroundIcon)
	surface.DrawTexturedRect(ScrW()/2-ScrH()/10, ScrH()/2-ScrH()/30+ScrH()/3, ScrH()/5, ScrH()/15)
	surface.SetDrawColor(255,255,255,125)

	local ply = LocalPlayer()
	local aim = ply:EyeAngles():Forward()
	local tr = util.TraceLine({
		start  = ply:GetShootPos() ,
		endpos = ply:GetShootPos() + aim * 100,
		filter = {ply, ply.bs_shieldIndex and Entity(ply.bs_shieldIndex)}
	})
	local flat = tr.HitNormal.z > 0.75 and true or tr.HitNormal.z < -0.75 and true or false
	if (tr.Hit and tr.HitPos:DistToSqr(LocalPlayer():GetPos()) > 1500 and tr.HitPos.z <= (LocalPlayer():GetPos().z + 30) and !self:CheckForDoors(tr.HitPos) and flat) then
		draw.SimpleTextOutlined(bshields.lang[bshields.config.language].dshieldprim, "bshields.HUD", ScrW()/2-ScrH()/32, ScrH()/2-ScrH()/28+ScrH()/3+ScrH()/22, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, 1, Color(20,20,20,255)) 
		surface.SetMaterial(ShieldIcon)
	else
		draw.SimpleTextOutlined(bshields.lang[bshields.config.language].dshieldprim, "bshields.HUD", ScrW()/2-ScrH()/32, ScrH()/2-ScrH()/28+ScrH()/3+ScrH()/22, Color(255, 255, 255, 25), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, 1, Color(20,20,20,255)) 
		surface.SetMaterial(ShieldIconClosed)
	end
	surface.DrawTexturedRect(ScrW()/2-ScrH()/10.2, ScrH()/2-ScrH()/32+ScrH()/3, ScrH()/16, ScrH()/16) 
	if (self.VisToggle) then
		draw.SimpleTextOutlined(bshields.lang[bshields.config.language].sec, "bshields.HUD", ScrW()/2-ScrH()/32, ScrH()/2-ScrH()/28+ScrH()/3+ScrH()/48, Color(255, 255, 255, 25), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, 1, Color(20,20,20,255)) 
	else
		draw.SimpleTextOutlined(bshields.lang[bshields.config.language].sec, "bshields.HUD", ScrW()/2-ScrH()/32, ScrH()/2-ScrH()/28+ScrH()/3+ScrH()/48, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, 1, Color(20,20,20,255)) 
	end
end

function SWEP:BuildShield()
	local owner = self:GetOwner()
	local holdtype = 0
	bshield_remove(owner)
	local owner_tb = owner:GetTable()
	owner_tb.bs_type = "deployable_shield"
	owner_tb.bs_shield = ents.Create("bs_shield")
	if !IsValid(owner_tb.bs_shield) then return end
	owner_tb.bs_shield.Model = "models/bshields/dshield.mdl"
	owner_tb.bs_shield.Mass = 100
	owner_tb.bs_shield:SetCollisionGroup(COLLISION_GROUP_WORLD)
	owner_tb.bs_shield:SetMoveType(MOVETYPE_NONE)
	owner_tb.bs_shield:SetPos(owner:GetPos())
	local att = owner:LookupAttachment("anim_attachment_RH")
	if (att == 0) then
		holdtype = 1
	end
	if (holdtype == 0) then	
		owner_tb.bs_shield:SetParent(owner, att)
		owner_tb.bs_shield:SetLocalAngles(bshields.shields[1][2].angles)
		owner_tb.bs_shield:SetLocalPos(bshields.shields[1][2].position)
	else
		att = owner:LookupAttachment("forward") != 0 and owner:LookupAttachment("forward") or owner:LookupAttachment("eyes") != 0 and owner:LookupAttachment("eyes")
		if (att == 0) then
			owner_tb.bs_shield:Remove()
			owner_tb.bs_shield = nil
			return
		end
		owner_tb.bs_shield:SetParent(owner, att)
		owner_tb.bs_shield:SetLocalAngles(bshields.shields[2][2].angles)
		owner_tb.bs_shield:SetLocalPos(bshields.shields[2][2].position)
	end
	owner_tb.bs_shield.holdtype = holdtype
	owner_tb.bs_shield.pos = {owner_tb.bs_shield:GetLocalAngles(), owner_tb.bs_shield:GetLocalPos()}
	owner_tb.bs_shield.model = owner:GetModel()
	owner_tb.bs_shield:Spawn()
	self.HP = self.HP or bshields.config.shieldhps["dshield"]
	owner_tb.bs_shield:SetHealth(self.HP)
	owner_tb.bs_shield.MaxHP = self.MaxHP
	owner_tb.bs_shield:ColorShield()
	net.Start("bs_shield_info")
		net.WriteUInt(owner_tb.bs_shield:EntIndex(), 16) 
	net.Send(owner)
end

function SWEP:Deploy() 
	self.CanVisToggle = 0
	self.VisToggle = false
	self.HP = self.HP or bshields.config.shieldhps["dshield"]
	self.MaxHP = bshields.config.shieldhps["dshield"]
	if SERVER then
		timer.Simple(0, function()
			if IsValid(self) and IsValid(self.Owner) and self.Owner:GetActiveWeapon() == self then
				self:BuildShield()
			end
		end)
	end
	return true
end

function SWEP:Think()
	local owner = self:GetOwner()
	if owner:IsValid() then
		if owner.bs_shield and owner:GetModel() != owner.bs_shield.model then
			self:BuildShield()
		end
	end
end

local function IsTouchingEntity(ent, ent2, mask)
	local pos = ent2:GetPos()
	local trace = {
		start = pos,
		endpos = pos,
		filter = function(hit)
			if hit == ent then
				return true
			end
		end
	}
	local tr = util.TraceEntity(trace, ent2)
	if tr.Hit then
		return true
	end
	return false
end

local function CheckForStuckingPlayers(ent)
	local center, radius, forbidden = ent:LocalToWorld(ent:OBBCenter()), ent:BoundingRadius(), false
	for _,v in ipairs(ents.FindInSphere(center, radius)) do
		if v:IsPlayer() and v:Alive() or v:IsNPC() then
			if IsTouchingEntity(ent, v) then
				forbidden = true
			end
		end
		if forbidden then break end
	end
	return forbidden
end

local function TryCollision(ent)
	ent:SetCollisionGroup(COLLISION_GROUP_WEAPON)
	if CheckForStuckingPlayers(ent) then
		timer.Simple(1, function()
			if !IsValid(ent) then return end
			TryCollision(ent)
		end)
	else
		ent:SetCollisionGroup(COLLISION_GROUP_NONE)
	end
end

SWEP.DoorRadius = 100
function SWEP:CheckForDoors(pos)
	if self.DoorRadius > 0 then
		for _,v in ipairs(ents.FindInSphere(pos, self.DoorRadius)) do
			if v:isDoor() or v.isFadingDoor then
				return true
			end
		end
	end
	return false
end

function SWEP:PrimaryAttack()
	if SERVER then
		local owner = self.Owner
		if !IsValid(owner) or !IsValid(owner.bs_shield) then return end
		local aim = owner:EyeAngles():Forward()
		local tr = util.TraceLine({
			start  = owner:GetShootPos() ,
			endpos = owner:GetShootPos() + aim * 100,
			filter = {owner, owner.bs_shield}
		})
		if (tr.Hit and tr.HitPos:DistToSqr(owner:GetPos()) > 1000 and tr.HitPos.z <= (owner:GetPos().z + 30) and !self:CheckForDoors(tr.HitPos)) then
			local flat = tr.HitNormal.z > 0.75 and true or tr.HitNormal.z < -0.75 and true or false
			if !flat then return end
			local shield = ents.Create("bs_dshield")
			if !IsValid(shield) then return end
			shield:SetPos(tr.HitPos + tr.HitNormal * 32)
			shield:SetAngles(Angle(0, aim:Angle().y, 0))
			shield:Spawn()
			shield:EmitSound("npc/combine_soldier/gear1.wav")
			shield.Owner = owner
			shield:Setowning_ent(owner)
			shield:SetHealth(owner.bs_shield:Health())
			shield.MaxHP = bshields.config.shieldhps["dshield"]
			shield:ColorShield()
			bshield_remove(owner)
			TryCollision(shield)
			owner:StripWeapon("deployable_shield")
			table.insert(owner.bs_shields, shield)
			if table.Count(owner.bs_shields) > bshields.config.maxshields then
				if IsValid(owner.bs_shields[1]) then
					owner.bs_shields[1]:Remove()
				end
				table.remove(owner.bs_shields, 1) 
			end
		end
	end
	self:SetNextPrimaryFire(CurTime() + 0.5)
end

function SWEP:SecondaryAttack()
	if CLIENT then
		if self.CanVisToggle > CurTime() then return end
		surface.PlaySound("weapons/smg1/switch_single.wav")
		if !self.VisToggle then
			self.VisToggle = true
		else
			self.VisToggle = false
		end
		self.CanVisToggle = CurTime() + 0.2
	end
end

function SWEP:ShouldDrawViewModel()
	local ply = LocalPlayer()
	local shield = ply.bs_shieldIndex and Entity(ply.bs_shieldIndex)
	if !IsValid(shield) then return end
	local col = shield:GetColor()
	col.a = self.VisToggle and 125 or 255
	shield:SetColor(col)
end

if CLIENT then return end

function SWEP:Holster()
	bshield_remove(self.Owner, function(hp)
		self.HP = hp
	end)
	return true
end

function SWEP:OnRemove()
	bshield_remove(self.Owner, function(hp)
		self.HP = hp
	end)
end

function SWEP:OnDrop()
	bshield_remove(self.Owner, function(hp)
		self.HP = hp
	end)
end