AddCSLuaFile()

if SERVER then
	AddCSLuaFile("cl_menu.lua")
end

if CLIENT then
	SWEP.Slot = 1
	SWEP.SlotPos = 1
	SWEP.DrawAmmo = false
	SWEP.DrawCrosshair = false

	include("cl_menu.lua")
end

SWEP.PrintName = "Keys"
SWEP.Author = "DarkRP Developers"
SWEP.Instructions = "Left click to lock\nRight click to unlock\nReload for door settings or animation menu"
SWEP.Contact = ""
SWEP.Purpose = ""
SWEP.IsDarkRPKeys = true

SWEP.ViewModel = Model("models/craphead_scripts/adv_keys/weapons/c_key.mdl")
SWEP.WorldModel = Model("models/craphead_scripts/adv_keys/weapons/w_key.mdl")

SWEP.UseHands = true
SWEP.ViewModelFOV = 65
SWEP.ViewModelFlip = false

SWEP.UseHands = true

SWEP.Spawnable = true
SWEP.AdminOnly = true
SWEP.Category = "DarkRP (Utility)"
SWEP.UseDelay = 1

SWEP.Primary.Delay = 0.3
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = 0
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = ""

SWEP.Secondary.Delay = 0.3
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = 0
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = ""

function SWEP:SetupDataTables()
	self:NetworkVar("Float", 0, "NextUse")
end

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

function SWEP:Deploy()
	self:SetHoldType("normal")
	self:SendWeaponAnim(ACT_VM_DRAW)
	local vm = self:GetOwner():IsValid() and self:GetOwner():GetViewModel()
	if vm:IsValid() then
		vm:SetPlaybackRate(1.5)
	end
	self:SetNextPrimaryFire(CurTime() + 0.85)
	self:SetNextSecondaryFire(CurTime() + 0.85)
	self:SetNextUse(CurTime() + 0.85)
	return true
end

function SWEP:Holster()
	return true
end

function SWEP:lookingAtLockable(ply, ent, hitpos)
	local eyepos = ply:EyePos()
	return IsValid(ent)
		and ent:isKeysOwnable()
		and (
			ent:isDoor() and eyepos:DistToSqr(hitpos) < 10000
			or
			ent:IsVehicle() and eyepos:DistToSqr(hitpos) < 62500
		)
end

function SWEP:Think()
	local ply = self:GetOwner()
	if !ply:IsValid() then return end

	local ply_tb = ply:GetTable()

	if (ply_tb.NextKeysCheck or 0) >= CurTime() then return end
	ply_tb.NextKeysCheck = CurTime() + 0.1

	local trace = ply:GetEyeTrace()

	ply_tb.KeysCheck = true

	if self:lookingAtLockable(ply, trace.Entity, trace.HitPos) and ply:canKeysLock(trace.Entity) then
		if self:GetHoldType() != "slam" then
			self:SetHoldType("slam")
		end
	else
		if self:GetHoldType() != "normal" then
			self:SetHoldType("normal")
		end
	end

	ply_tb.KeysCheck = nil
end

local function lockUnlockAnimation(ply)
	umsg.Start("anim_keys")
		umsg.Entity(ply)
		umsg.String("usekeys")
	umsg.End()

	ply:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_GMOD_GESTURE_ITEM_PLACE, true)
end

local function doKnock(ply, sound)
	ply:EmitSound(sound, 100, math.random(90, 110))

	umsg.Start("anim_keys")
		umsg.Entity(ply)
		umsg.String("knocking")
	umsg.End()

	ply:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_HL2MP_GESTURE_RANGE_ATTACK_FIST, true)
end

local LockSound = Sound("doors/door_latch1.wav")
local UnLockSound = Sound("doors/door_latch3.wav")
local CarBeep = Sound("craphead_scripts/adv_keys/carlock.wav")
function SWEP:PrimaryAttack()
	if self:GetNextUse() > CurTime() then return end

	local Owner = self:GetOwner()

	if !IsValid(Owner) then return end

	local trace = Owner:GetEyeTrace()
	local ent = trace.Entity

	if !self:lookingAtLockable(Owner, ent, trace.HitPos) then return end

	self:SetNextPrimaryFire(CurTime() + self.Primary.Delay)

	if Owner:canKeysLock(ent) then

		if ent:IsVehicle() then
			self:SendWeaponAnim(ACT_VM_HITCENTER)

			if SERVER then
				timer.Simple(0.2, function()
					if IsValid(self) then
						Owner:EmitSound(CarBeep)

						ent:keysLock()
						
						if ent.VC_setHazardLights then
							ent:VC_setHazardLights(true)
						end

						if ent.VehicleAlarmSound then
							ent.VehicleAlarmSound:Stop()
							ent.VehicleAlarmSound = nil
						end

						timer.Simple(0.4, function()
							if IsValid(self) then
								if ent.VC_setHazardLights then
									ent:VC_setHazardLights(false)
								end
							end
						end)
					end
				end)
			end
		else
			self:SendWeaponAnim(ACT_VM_PRIMARYATTACK)

			if SERVER then
				Owner:EmitSound("npc/metropolice/gear"..math.random(1, 6)..".wav")

				timer.Simple(0.4, function()
					if IsValid(self) then
						if !self:lookingAtLockable(Owner, ent, trace.HitPos) then 
							return 
						end

						Owner:EmitSound(LockSound)

						ent:keysLock()

						if ent.DoorAlarmSound then
							ent.DoorAlarmSound:Stop()
							ent.DoorAlarmSound = nil
						end
					end
				end)

				lockUnlockAnimation(Owner)
			end
		end

		local vm = Owner:GetViewModel()
		if IsValid(vm) then
			vm:SetPlaybackRate(2)
		end

		self:SetNextUse(CurTime() + self.UseDelay)
	elseif ent:IsVehicle() then
		if SERVER then
			DarkRP.notify(Owner, 1, 3, DarkRP.getPhrase("do_not_own_ent"))
		end
	elseif SERVER then
		doKnock(Owner, "physics/wood/wood_crate_impact_hard"..math.random(2, 3)..".wav")
	end
end

function SWEP:SecondaryAttack()
	if self:GetNextUse() > CurTime() then return end

	local Owner = self:GetOwner()

	if !IsValid(Owner) then return end

	local trace = Owner:GetEyeTrace()
	local ent = trace.Entity

	if !self:lookingAtLockable(Owner, ent, trace.HitPos) then return end

	self:SetNextSecondaryFire(CurTime() + self.Secondary.Delay)

	if Owner:canKeysUnlock(ent) then

		if ent:IsVehicle() then
			self:SendWeaponAnim(ACT_VM_HITCENTER)

			if SERVER then
				timer.Simple(0.2, function()
					if IsValid(self) then
						if !self:lookingAtLockable(Owner, ent, trace.HitPos) then 
							return 
						end

						Owner:EmitSound(CarBeep)

						ent:keysUnLock()
						
						if ent.VC_setHazardLights then
							ent:VC_setHazardLights(true)
						end

						if ent.VehicleAlarmSound then
							ent.VehicleAlarmSound:Stop()
							ent.VehicleAlarmSound = nil
						end

						timer.Simple(0.4, function()
							if IsValid(self) then
								if ent.VC_setHazardLights then
									ent:VC_setHazardLights(false)
								end
							end
						end)
					end
				end)
			end
		else
			self:SendWeaponAnim(ACT_VM_PRIMARYATTACK)

			if SERVER then
				Owner:EmitSound("npc/metropolice/gear"..math.random(1, 6)..".wav")

				timer.Simple(0.4, function()
					if IsValid(self) then
						if !self:lookingAtLockable(Owner, ent, trace.HitPos) then 
							return 
						end

						Owner:EmitSound(UnLockSound)

						ent:keysUnLock()

						if ent.DoorAlarmSound then
							ent.DoorAlarmSound:Stop()
							ent.DoorAlarmSound = nil
						end
					end
				end)
				
				lockUnlockAnimation(Owner)
			end
		end

		local vm = Owner:GetViewModel()
		if IsValid(vm) then
			vm:SetPlaybackRate(2)
		end

		self:SetNextUse(CurTime() + self.UseDelay)
	elseif ent:IsVehicle() then
		if SERVER then
			DarkRP.notify(Owner, 1, 3, DarkRP.getPhrase("do_not_own_ent"))
		end
	elseif SERVER then
		doKnock(Owner, "physics/wood/wood_crate_impact_hard"..math.random(2, 3)..".wav")
	end
end

function SWEP:Reload()
	local trace = self:GetOwner():GetEyeTrace()
	if !IsValid(trace.Entity) or ((!trace.Entity:isDoor() and !trace.Entity:IsVehicle()) or self.Owner:EyePos():DistToSqr(trace.HitPos) > 40000) then
		if CLIENT and !DarkRP.disabledDefaults["modules"]["animations"] then RunConsoleCommand("_DarkRP_AnimationMenu") end
		return
	end
	if SERVER then
		umsg.Start("KeysMenu", self:GetOwner())
		umsg.End()
	end
end