local r=(require(script.Parent.loader)).load(script)local Q=game:GetService("\085\115\101\114\073\110\112\117\116\083\101\114\118\105\099\101")local t=game:GetService("\087\111\114\107\115\112\097\099\101")local x=r("\083\105\103\110\097\108")local w=r("\066\097\115\101\079\098\106\101\099\116")local E=r("\082\097\121\099\097\115\116\101\114")local k=r("\073\110\112\117\116\079\098\106\101\099\116\082\097\121\085\116\105\108\115")local I=r("\068\114\097\119")local Y=false local v=setmetatable({},w)v.__index=v v.ClassName="\083\101\108\101\099\116\105\111\110\070\097\099\097\100\101"function v.new(r)local t=setmetatable(w.new(),v)t._plugin=assert(r,"\078\111 \112\108\117\103\105\110")t._selectedItems={}t.SelectionChanged=t._maid:Add(x.new())t._raycaster=E.new()t._raycaster.Filter=function(r)return false end t._maid:GiveTask(Q.InputBegan:connect(function(r)if r.UserInputType==Enum.UserInputType.MouseButton1 then local x={}local w=t:_findTarget(r)if w and w:IsA("\066\097\115\101\080\097\114\116")then if Q:IsKeyDown(Enum.KeyCode.LeftControl)then for r,Q in pairs(t:Get())do table.insert(x,Q)end end if not w.Locked then table.insert(x,w)end end t:Set(x)end end))return t end function v._findTarget(Q,r)local t=k.cameraRayFromInputObject(r,1000)if Y then I.ray(t)end local x=Q._raycaster:FindPartOnRay(t)if x then return x.Part end end function v.Get(r)return r._selectedItems end function v.Set(Q,r)assert(type(r)=="\116\097\098\108\101","\066\097\100 \105\116\101\109\115")Q._selectedItems=r Q.SelectionChanged:Fire()end return v
--[=[
	Selection facade
	@class SelectionFacade
]=]

local require = require(script.Parent.loader).load(script)

local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")

local Signal = require("Signal")
local BaseObject = require("BaseObject")
local Raycaster = require("Raycaster")
local InputObjectRayUtils = require("InputObjectRayUtils")
local Draw = require("Draw")

local DEBUG_VISUALIZE = false

local SelectionFacade = setmetatable({}, BaseObject)
SelectionFacade.__index = SelectionFacade
SelectionFacade.ClassName = "SelectionFacade"

function SelectionFacade.new(plugin)
	local self = setmetatable(BaseObject.new(), SelectionFacade)

	self._plugin = assert(plugin, "No plugin")
	self._selectedItems = {}
	self.SelectionChanged = self._maid:Add(Signal.new())

	self._raycaster = Raycaster.new()
	self._raycaster.Filter = function(hitData)
		return false
	end

	-- Fake selection
	self._maid:GiveTask(UserInputService.InputBegan:connect(function(inputObject)
		if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
			local new = {}
			local target = self:_findTarget(inputObject)
			if target and target:IsA("BasePart") then
				if UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then
					for _, item in pairs(self:Get()) do
						table.insert(new, item)
					end
				end
				if not target.Locked then
					table.insert(new, target)
				end
			end

			self:Set(new)
		end
	end))

	return self
end

function SelectionFacade:_findTarget(inputObject)
	local mouseRay = InputObjectRayUtils.cameraRayFromInputObject(inputObject, 1000)

	if DEBUG_VISUALIZE then
		Draw.ray(mouseRay)
	end

	local hitData = self._raycaster:FindPartOnRay(mouseRay)
	if hitData then
		return hitData.Part
	end
end


function SelectionFacade:Get()
	return self._selectedItems
end

function SelectionFacade:Set(items)
	assert(type(items) == "table", "Bad items")

	self._selectedItems = items
	self.SelectionChanged:Fire()
end

return SelectionFacade