-- Weld holster model to the player
function HolsterWeapon(player,weaponName,toolSettings,tool)
	if player.Character:FindFirstChild(toolSettings.HolsterPoint) then
		local holsterPoint = toolSettings.HolsterPoint
		local holsterModel = GunModels:FindFirstChild(weaponName):Clone()
		holsterModel.Name = "S_"..weaponName
		holsterModel.Parent = player.Character

		if holsterModel:FindFirstChild("Nodes") then
			holsterModel.Nodes:Destroy()
		end
		
		local config = tool:FindFirstChild("RepValues")
		
		for _, part in pairs(holsterModel:GetChildren()) do
			if part:IsA("BasePart") and part.Name ~= "Handle" then
				if part.Name == "SightMark" or (part.Name == "Warhead" and config and config.Mag.Value < 1) then
					part:Destroy()
				else
					local newWeld = Ultil.WeldComplex(holsterModel.Handle,part,part.Name)
					newWeld.Parent = holsterModel.Handle
					part.Anchored = false
					part.CanCollide = false
				end
			end
		end

		local holsterWeld = Ultil.Weld(player.Character[holsterPoint],holsterModel.Handle,toolSettings.HolsterCFrame)
		holsterWeld.Parent = holsterModel
		holsterWeld.Name = "HolsterWeld"
		holsterModel.Handle.Anchored = false
	end
end

function SpawnGun(gunName,gunPosition,tool,player,config)

	local dropModel = GunModels:FindFirstChild(gunName):Clone()
	dropModel.Handle.Anchored = false
	dropModel.Handle.CanTouch = true
	--dropModel.Handle.CFrame = CFrame.new(dropModel["Origin Position"])

	dropModel.PrimaryPart = dropModel.Handle
	dropModel.Handle.Size = dropModel:GetExtentsSize()

	if dropModel:FindFirstChild("Nodes") then dropModel.Nodes:Destroy() end
	
	if #dropModel:GetChildren() < 2 then
		dropModel.Handle.CanCollide = true
	else
		dropModel.Handle.CanCollide = false
	end

	for _, part in pairs(dropModel:GetChildren()) do
		if part.Name == "Warhead" and config and config.IsLauncher and tool:FindFirstChild("RepValues") and tool.RepValues.Mag.Value < 1 then
			part:Destroy()
		elseif part:IsA("BasePart") and part.Name ~= "Handle" then
			local newWeld = Ultil.WeldComplex(dropModel.Handle,part,part.Name)
			newWeld.Parent = dropModel.Handle
			part.Anchored = false
			part.CanCollide = true
			part.CanTouch = false
			PhysService:SetPartCollisionGroup(part,"Guns")
		end
	end

	if not tool then
		tool = Engine.ToolStorage:FindFirstChild(gunName):Clone()
	end
	tool.Parent = dropModel

	local clickDetector = Instance.new("ClickDetector")
	clickDetector.MaxActivationDistance = gameRules.PickupDistance
	clickDetector.Parent = dropModel
	clickDetector.MouseClick:Connect(function(clicker)

		tool.Parent = clicker.Backpack
		dropModel:Destroy()

		local NewSound = Engine.FX.WeaponPickup:Clone()
		NewSound.Parent = clicker.Character.Torso
		--NewSound.PlaybackSpeed = math.random(30,50)/40
		NewSound:Play()
		NewSound.PlayOnRemove = true
		NewSound:Destroy()
	end)

	dropModel.Parent = ACS_Workspace.DroppedGuns

	dropModel.Handle.Touched:Connect(function()
		if dropModel.Handle.AssemblyLinearVelocity.Magnitude > 7 then
			local DropSounds = Engine.FX.GunDrop
			local NewSound = DropSounds["GunDrop"..math.random(#DropSounds:GetChildren())]:Clone()
			NewSound.Parent = dropModel.Handle
			NewSound.PlaybackSpeed = math.random(30,50)/40
			NewSound:Play()
			NewSound.PlayOnRemove = true
			NewSound:Destroy()
		end
	end)

	if player then dropModel.Handle:SetNetworkOwner(player) end

	dropModel:SetPrimaryPartCFrame(gunPosition)

	if #ACS_Workspace.DroppedGuns:GetChildren() > gameRules.MaxDroppedWeapons then
		ACS_Workspace.DroppedGuns:GetChildren()[1]:Destroy()
	end

	if gameRules.TimeDespawn then
		Debris:AddItem(dropModel,gameRules.WeaponDespawnTime)
	end

	return dropModel
end

Evt.Shell.OnServerEvent:Connect(function(Player,Shell,Origin)
	Evt.Shell:FireAllClients(Shell,Origin)
end)

Evt.DropWeapon.OnServerEvent:Connect(function(player,tool,toolConfig)
	local tool = player.Backpack:FindFirstChild(tool.Name)
	--print(player.Name.. " dropped a " ..tool.Name)
	--tool:Destroy()
	local NewSound = Engine.FX.WeaponDrop:Clone()
	NewSound.Parent = player.Character.Torso
	--NewSound.PlaybackSpeed = math.random(30,50)/40
	NewSound:Play()
	NewSound.PlayOnRemove = true
	NewSound:Destroy()
	SpawnGun(tool.Name,player.Character.Torso.CFrame * CFrame.new(0,1,-3),tool,player,toolConfig)
end)

Evt.RepAmmo.OnServerEvent:Connect(function(Player,tool,mag,ammo,chambered)
	local config = tool.RepValues
	config.StoredAmmo.Value = ammo
	config.Mag.Value = mag
	config.Chambered.Value = chambered
	
	if tool.Parent:FindFirstChild("Humanoid") and tool.Parent:FindFirstChild("S"..tool.Name) then
		-- Tool is equipped
		for _, part in pairs(tool.Parent["S"..tool.Name]:GetChildren()) do
			if part.Name == "Warhead" then
				if mag > 0 then
					part.Transparency = 0
				else
					part.Transparency = 1
				end
			end
		end
	end
end)

Evt.DropAmmo.OnServerEvent:Connect(function(Player,tool,action)
	if action == "Weld" then
		local canModel = Engine.AmmoModels.AmmoBox:Clone()
		local handle = tool.Handle
		for _, part in pairs(canModel:GetChildren()) do
			if part:IsA("BasePart") and part.Name ~= "Main" then
				local newWeld = Ultil.WeldComplex(canModel.Main,part,part.Name)
				newWeld.Parent = canModel.Main
				part.Anchored = false
				part.CanCollide = true
				part.CanTouch = false
			end

			PhysService:SetPartCollisionGroup(part,"Guns")

			if part.Name == "Main" then
				for _, child in pairs(part:GetChildren()) do
					if child:FindFirstChildWhichIsA("TextLabel") then
						child:FindFirstChildWhichIsA("TextLabel").Text = tool.AmmoType.Value
					end
				end
			end
		end
		local newWeld = Ultil.Weld(handle,canModel.Main,CFrame.new(0,-0.2,0),CFrame.new())
		newWeld.Name = "ToolWeld"
		newWeld.Parent = handle
		canModel.Main.Anchored = false
		handle.Anchored = false
		canModel.Parent = tool
	elseif action == "Destroy" then
		if tool:FindFirstChildWhichIsA("Model") then
			tool:FindFirstChildWhichIsA("Model"):Destroy()
			tool.Handle.ToolWeld:Destroy()
		end
	elseif action == "Drop" then
		local canModel = tool:FindFirstChildWhichIsA("Model")
		local handle = tool.Handle
		handle.ToolWeld:Destroy()
		canModel.Parent = ACS_Workspace.DroppedGuns
		canModel.Main.Touched:Connect(function(hitPart)
			if plr:GetPlayerFromCharacter(hitPart.Parent) then

				local player = plr:GetPlayerFromCharacter(hitPart.Parent)
				local f = player.Backpack:GetChildren()
				for i = 1, #f do

					if f[i]:IsA("Tool") and f[i]:FindFirstChild("ACS_Settings") then
						if tool.AmmoType.Value == "Universal" then
							Evt.Refil:FireClient(player, f[i], tool.Inf.Value, tool.Stored)
							if not canModel.Main.Sound.Playing then
								canModel.Main.Sound:Play()
							end
						elseif require(f[i].ACS_Settings).BulletType == tool.AmmoType.Value then
							Evt.Refil:FireClient(player, f[i], tool.Inf.Value, tool.Stored)
							if not canModel.Main.Sound.Playing then
								canModel.Main.Sound:Play()
							end
						end
					end
				end

				-- No more ammo
				if tool.Stored.Value <= 0 and not tool.Inf.Value then
					canModel:Destroy()
					tool:Destroy()
					return
				end
			end
		end)
		tool.Parent = nil

		local clicker = Instance.new("ClickDetector",canModel)
		clicker.MaxActivationDistance = gameRules.PickupDistance
		clicker.MouseClick:Connect(function(Player)
			--print("Give")
			tool.Parent = Player:WaitForChild("Backpack")
			canModel:Destroy()
		end)

		Debris:AddItem(canModel, gameRules.AmmoBoxDespawn)
	end
end)


for _, spawner in pairs(ACS_Workspace.WeaponSpawners:GetChildren()) do
	local constrainedValue = Instance.new("DoubleConstrainedValue")
	local maxTime = spawner.Config.WaitTime

	constrainedValue.Name = "WaitTime"
	constrainedValue.MaxValue = maxTime.Value
	constrainedValue.Value = maxTime.Value
	constrainedValue.Parent = spawner.Config

	maxTime:Destroy()
end