if SERVER then
	AddCSLuaFile()
	util.AddNetworkString("DarkRP_TowVehicles")
end

if CLIENT then
	SWEP.Slot = 3
	SWEP.SlotPos = 3
	SWEP.DrawAmmo = false
	SWEP.DrawCrosshair = true
end

local TowSpeed = 600

SWEP.Range = 20000
SWEP.ReportSpeed = 4

SWEP.PrintName = "Abschleppradio"
SWEP.Author = "Modern Gaming"
SWEP.Instructions = "Linksklick, um Fahrzeuge zur Abschleppung zu melden.\nRechtsklick, um Abschleppung von Fahrzeugen abzusagen.\n"
SWEP.Purpose = "Meldet Autos zum Abschleppen.\n\nAutos, die gemeldet wurden, werden innerhalb "..(TowSpeed / 60).." Minuten abgeschleppt."
SWEP.Spawnable = true
SWEP.UseHands = true
SWEP.HoldType = "slam"
SWEP.ViewModel = Model("models/danradio/c_radio.mdl")
SWEP.WorldModel = Model("models/danradio/w_radio.mdl")

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

function SWEP:SetupDataTables()
	self:NetworkVar("Bool", 0, "Reporting")
	self:NetworkVar("Bool", 1, "ReportType")
	self:NetworkVar("Float", 0, "ReportTime")
	self:NetworkVar("Entity", 0, "ReportEntity")
end

function SWEP:Initialize()
	self:SetDeploySpeed(2)
	self:SetHoldType(self.HoldType)
end

function SWEP:Deploy()
	self:SetReporting(false)
	self:SetReportTime(0)
	self:SetReportEntity(NULL)
	return true
end

function SWEP:Holster()
	self:SetReporting(false)
	self:SetReportTime(0)
	self:SetReportEntity(NULL)
	return true
end

local col1 = Color(255, 100, 255, 255)
local col2 = Color(150, 0, 0, 255)
function SWEP:DoDrawCrosshair()
	if self:GetReporting() then return true end
	local w, h = ScrW(), ScrH()
	local w2, h2 = w / 2, h / 2
	local ply = LocalPlayer()
	if !self.Vehicle or self.next_tr < CurTime() then
		self.Vehicle = util.TraceLine(util.GetPlayerTrace(ply))
		self.next_tr = CurTime() + 0.05
	end
	local ent = self.Vehicle.Entity
	local hit = self.Vehicle.HitPos:DistToSqr(ply:GetShootPos()) <= self.Range and IsValid(ent) and ent:IsVehicle() and ent:GetClass() != "prop_vehicle_prisoner_pod"
	surface.SetDrawColor(hit and col1 or col2)
	local gap = (hit and 0 or 10) + 5
	local length = 10
	surface.DrawLine(w2 - length, h2, w2 - gap, h2)
	surface.DrawLine(w2 + length, h2, w2 + gap, h2)
	surface.DrawLine(w2, h2 - length, w2, h2 - gap)
	surface.DrawLine(w2, h2 + length, w2, h2 + gap)
	return true
end

function SWEP:StopReporting()
	self:SetReporting(false)
	self:SetReportTime(0)
	self:SetReportEntity(NULL)
end

function SWEP:PrimaryAttack()
	if self:GetReporting() then return end
	self:SetNextPrimaryFire(CurTime() + 0.1)
	self.Owner:LagCompensation(true)
	local mg = self.Owner:GetEyeTrace()
	self.Owner:LagCompensation(false)
	local ent = mg.Entity
	if !IsValid(ent) then return end
	local class = ent:GetClass()
	if !ent:IsVehicle() or class == "prop_vehicle_prisoner_pod" then return end
	local distance = self.Owner:GetShootPos():DistToSqr(mg.HitPos)
	if (distance > self.Range) then return end
	self:SetNextPrimaryFire(CurTime() + 1)
	if ent:GetNW2Float("Towed") > 0 then
		if SERVER then
			DarkRP.notify(self.Owner, 1, 4, "Dieses Auto wurde bereits gemeldet!")
		end
		return
	end
	if IsValid(ent:GetDriver()) then
		if SERVER then
			DarkRP.notify(self.Owner, 1, 4, "In diesem Auto befindet sich eine Person!")
		end
		return
	end
	self:EmitSound("radio/radio_on.wav")
	self:SetReporting(true)
	self:SetReportTime(CurTime() + self.ReportSpeed)
	self:SetReportEntity(ent)
	hook.Run("onPlayerBeginRequestVehicleTow", self.Owner, ent)
end

function SWEP:SecondaryAttack()
	if self:GetReporting() then return end
	self.Owner:LagCompensation(true)
	local mg = self.Owner:GetEyeTrace()
	self.Owner:LagCompensation(false)
	local ent = mg.Entity
	if !IsValid(ent) then return end
	if !ent:IsVehicle() or ent:GetClass() == "prop_vehicle_prisoner_pod" then return end
	local distance = self.Owner:GetShootPos():DistToSqr(mg.HitPos)
	if (distance > self.Range) then return end
	self:SetNextSecondaryFire(CurTime() + 1)
	if ent:GetNW2Float("Towed") <= 0 then
		if SERVER then
			DarkRP.notify(self.Owner, 1, 4, "Dieses Auto wurde nicht gemeldet!")
		end
		return
	end
	self:EmitSound("radio/radio_on.wav")
	if SERVER then
		ent:SetNW2Float("Towed", 0)
		ent:SetNW2Bool("TowAccess", false)
		ent.TowingInitiator = nil
		net.Start("DarkRP_TowVehicles")
			net.WriteBool(false)
			net.WriteEntity(ent)
		net.Send(team.GetPlayers(TEAM_REPAIR))
		timer.Remove("DarkRP_TowVehicle_"..ent:EntIndex())
		DarkRP.notify(self.Owner, 0, 3, "Abschleppung abgemeldet.")
		hook.Run("onPlayerUntowVehicle", self.Owner, ent)
	end
end

function MG_AutoTowVehicle(veh, ply)
	if !IsValid(veh.IsTowed) then
		veh:SetNW2Float("Towed", CurTime() + TowSpeed)
	else
		veh:SetNW2Float("Towed", 0)
	end
	veh:SetNW2Bool("TowAccess", true)
	if IsValid(ply) then
		veh.TowingInitiator = ply
	end
	net.Start("DarkRP_TowVehicles")
		net.WriteBool(true)
		net.WriteEntity(veh)
	net.Send(team.GetPlayers(TEAM_REPAIR))
	if IsValid(ply) then
		hook.Run("onPlayerRequestedVehicleTow", ply, veh)
	end
	timer.Create("DarkRP_TowVehicle_"..veh:EntIndex(), math.max(1, TowSpeed - 1), 1, function()
		if IsValid(veh) and veh:GetNW2Float("Towed") > 0 then
			veh:SetModelScale(0.1, 1)
			SafeRemoveEntityDelayed(veh, 1)
			hook.Run("onVehicleAutoTowed", veh)
		end
	end)
end

function SWEP:Think()
	if !IsValid(self.Owner) then return end
	if (self.Owner:KeyPressed(IN_ATTACK2) or self.Owner:KeyPressed(IN_RELOAD)) and self:GetReporting() then
		self:SetNextSecondaryFire(CurTime() + 0.5)
		self:StopReporting()
		if SERVER then
			DarkRP.notify(self.Owner, 0, 3, "Abschleppung abgemeldet.")
		end
	end
	local mg = self.Owner:GetEyeTrace()
	local ent = mg.Entity
	if self:GetReporting() then
		local veh = self:GetReportEntity()
		local distance = self.Owner:GetShootPos():DistToSqr(mg.HitPos)
		if !IsValid(veh) or veh != ent or distance > self.Range then
			self:StopReporting()
			return
		end
		local players = player.GetAll()
		for _, v in ipairs(players) do
			if v:GetVehicle() == ent then
				if SERVER then
					sound.Play("radio/radio_on.wav", v:GetPos())
					DarkRP.notify(self.Owner, 1, 4, "Eine Person sitzt in diesem Auto!")
				end
				self:StopReporting()
				return
			end
		end
		if self:GetReportTime() < CurTime() then
			if SERVER and IsValid(veh) then
				MG_AutoTowVehicle(veh, self.Owner)
			end
			self:EmitSound("radio/radio_off.wav")
			self:StopReporting()
		end
	end
end

if SERVER then
	hook.Add("PlayerEnteredVehicle", "DarkRP_ResetTow", function(ply, veh)
		if veh:GetNW2Float("Towed") > 0 then
			veh:SetNW2Float("Towed", 0)
			veh:SetNW2Bool("TowAccess", false)
			veh.TowingInitiator = nil
			net.Start("DarkRP_TowVehicles")
				net.WriteBool(false)
				net.WriteEntity(veh)
			net.Send(team.GetPlayers(TEAM_REPAIR))
			timer.Remove("DarkRP_TowVehicle_"..veh:EntIndex())
			sound.Play("radio/radio_on.wav", veh:GetPos())
			DarkRP.notify(ply, 0, 3, "Abschleppung verhindert.")
		end
	end)
end

if !CLIENT then return end

local gradientup = Material("gui/gradient_up")
local gradientdown = Material("gui/gradient_down")

function SWEP:DrawProgressBar(label, color, filled)
	filled = math.Clamp(filled, 0, 1)
	local w, h = 300, 20
	local centerx, centery = ScrW() / 2, ScrH() / 2 - 20
	local x, y = centerx - w / 2, centery - h / 2
	surface.SetDrawColor(color_white)
	surface.DrawOutlinedRect(x, y, w, h)
	surface.SetDrawColor(color)
	surface.SetMaterial(gradientdown)
	surface.DrawTexturedRect(x + 2, y + 2, (w - 4) * filled, h - 4)
	surface.SetDrawColor(Color(color.r / 2, color.g / 2, color.b/ 2))
	surface.SetMaterial(gradientup)
	surface.DrawTexturedRect(x + 2, y + 2, (w - 4) * filled, h - 4)
	draw.SimpleTextOutlined(label, "DermaDefaultBold", centerx, centery - 1, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1, Color(0, 0, 0))
end

function SWEP:DrawHUD()
	if self:GetReporting() then
		local text = "Zum Abschleppen melden..."
		local color = Color(255, 100, 255)
		local time = (CurTime() - (self:GetReportTime() - self.ReportSpeed)) / self.ReportSpeed
		self:DrawProgressBar(text, color, time)
	end
end