-- Libraries

local Libraries = Tool:WaitForChild 'Libraries'
local Support = require(Libraries:WaitForChild 'SupportLibrary')
local Signal = require(Libraries:WaitForChild 'Signal')
local Make = require(Libraries:WaitForChild 'Make')
local InstancePool = require(Libraries:WaitForChild 'InstancePool')

TargetingModule = {};
TargetingModule.TargetingMode = 'Scoped'
TargetingModule.TargetingModeChanged = Signal.new()
TargetingModule.Scope = Workspace
TargetingModule.IsScopeLocked = true
TargetingModule.TargetChanged = Signal.new()
TargetingModule.ScopeChanged = Signal.new()
TargetingModule.ScopeTargetChanged = Signal.new()
TargetingModule.ScopeLockChanged = Signal.new()

function TargetingModule:EnableTargeting()
	-- 	Begin targeting parts from the mouse

	-- Get core API
	local Core = GetCore();
	local Connections = Core.Connections;

	-- Create reference to mouse
	Mouse = Core.Mouse;

	-- Listen for target changes
	Connections.Targeting = Mouse.Move:Connect(function ()
		self:UpdateTarget(self.Scope)
	end)

	-- Listen for target clicks
	Connections.Selecting = Mouse.Button1Up:Connect(self.SelectTarget)

	-- Listen for sibling selection middle clicks
	Connections.SiblingSelecting = Support.AddUserInputListener('Began', 'MouseButton3', true, function ()
		self.SelectSiblings(Mouse.Target, not Selection.Multiselecting)
	end);

	-- Listen for 2D selection
	Connections.RectSelectionStarted = Mouse.Button1Down:Connect(self.StartRectangleSelecting);
	Connections.RectSelectionFinished = Support.AddUserInputListener('Ended', 'MouseButton1', true, self.FinishRectangleSelecting);

	-- Hide target box when tool is unequipped
	Connections.HideTargetBoxOnDisable = Core.Disabling:Connect(self.HighlightTarget);

	-- Cancel any ongoing selection when tool is unequipped
	Connections.CancelSelectionOnDisable = Core.Disabling:Connect(self.CancelRectangleSelecting);

	-- Enable scope selection
	self:EnableScopeSelection()

	-- Enable automatic scope resetting
	self:EnableScopeAutoReset()

	-- Enable targeting mode hotkeys
	self:BindTargetingModeHotkeys()

end;

function TargetingModule:SetScope(Scope)
	if self.Scope ~= Scope then
		self.Scope = Scope
		self.ScopeChanged:Fire(Scope)
	end
end

local function IsVisible(Item)
	return Item:IsA 'Model' or Item:IsA 'BasePart'
end

local function IsTargetable(Item)
	return Item:IsA 'Model' or
		Item:IsA 'BasePart' or
		Item:IsA 'Tool' or
		Item:IsA 'Accessory' or
		Item:IsA 'Accoutrement'
end
