local J={}function MoveTool.Equip()SetAxes(MoveTool.Axes)ShowUI()BindShortcutKeys()EnableDragging()end function MoveTool.Unequip()if Dragging then FinishDragging()end HideUI()HideHandles()ClearConnections()BoundingBox.ClearBoundingBox()SnapTracking.StopTracking()end function ClearConnections()for p,w in pairs(J)do w:disconnect()J[p]=nil end end function ClearConnection(p)local w=J[p]if J[p]then w:disconnect()J[p]=nil end end function ShowUI()if MoveTool.UI then MoveTool.UI.Visible=true UIUpdater=Support.ScheduleRecurringTask(UpdateUI,.1)return end MoveTool.UI=Core.Tool.Interfaces.BTMoveToolGUI:Clone()MoveTool.UI.Parent=Core.UI MoveTool.UI.Visible=true local J=MoveTool.UI.AxesOption J.Global.Button.MouseButton1Down:connect(function()SetAxes("\071\108\111\098\097\108")end)J.Local.Button.MouseButton1Down:connect(function()SetAxes("\076\111\099\097\108")end)J.Last.Button.MouseButton1Down:connect(function()SetAxes("\076\097\115\116")end)local p=MoveTool.UI.IncrementOption.Increment.TextBox p.FocusLost:connect(function(J)MoveTool.Increment=tonumber(p.Text)or MoveTool.Increment p.Text=Support.Round(MoveTool.Increment,4)end)local w=MoveTool.UI.Info.Center.X.TextBox local P=MoveTool.UI.Info.Center.Y.TextBox local W=MoveTool.UI.Info.Center.Z.TextBox w.FocusLost:connect(function(J)local p=tonumber(w.Text)if p then SetAxisPosition("\088",p)end end)P.FocusLost:connect(function(J)local p=tonumber(P.Text)if p then SetAxisPosition("\089",p)end end)W.FocusLost:connect(function(J)local p=tonumber(W.Text)if p then SetAxisPosition("\090",p)end end)UIUpdater=Support.ScheduleRecurringTask(UpdateUI,.1)end function HideUI()if not MoveTool.UI then return end MoveTool.UI.Visible=false UIUpdater:Stop()end function UpdateUI()if not MoveTool.UI then return end if#Selection.Items==0 then MoveTool.UI.Info.Visible=false MoveTool.UI.Size=UDim2.new(0,245,0,90)return else MoveTool.UI.Info.Visible=true MoveTool.UI.Size=UDim2.new(0,245,0,150)end local J,p,w={},{},{}for P,W in pairs(Selection.Items)do table.insert(J,Support.Round(W.Position.X,3))table.insert(p,Support.Round(W.Position.Y,3))table.insert(w,Support.Round(W.Position.Z,3))end local P=Support.IdentifyCommonItem(J)local W=Support.IdentifyCommonItem(p)local B=Support.IdentifyCommonItem(w)local T=MoveTool.UI.Info.Center.X.TextBox local L=MoveTool.UI.Info.Center.Y.TextBox local t=MoveTool.UI.Info.Center.Z.TextBox if not T:IsFocused()then T.Text=P or"\042"end if not L:IsFocused()then L.Text=W or"\042"end if not t:IsFocused()then t.Text=B or"\042"end end function SetAxes(J)MoveTool.Axes=J if MoveTool.UI then Core.ToggleSwitch(J,MoveTool.UI.AxesOption)end BoundingBox.ClearBoundingBox()if J=="\071\108\111\098\097\108"then BoundingBox.StartBoundingBox(AttachHandles)elseif J=="\076\111\099\097\108"then AttachHandles(Selection.Focus,true)elseif J=="\076\097\115\116"then AttachHandles(Selection.Focus,true)end end
-- Container for temporary connections (disconnected automatically)
local Connections = {}

function MoveTool.Equip()
	-- Enables the tool's equipped functionality

	-- Set our current axis mode
	SetAxes(MoveTool.Axes)

	-- Start up our interface
	ShowUI()
	BindShortcutKeys()
	EnableDragging()
end

function MoveTool.Unequip()
	-- Disables the tool's equipped functionality

	-- If dragging, finish dragging
	if Dragging then
		FinishDragging()
	end

	-- Clear unnecessary resources
	HideUI()
	HideHandles()
	ClearConnections()
	BoundingBox.ClearBoundingBox()
	SnapTracking.StopTracking()
end

function ClearConnections()
	-- Clears out temporary connections

	for ConnectionKey, Connection in pairs(Connections) do
		Connection:disconnect()
		Connections[ConnectionKey] = nil
	end
end

function ClearConnection(ConnectionKey)
	-- Clears the given specific connection

	local Connection = Connections[ConnectionKey]

	-- Disconnect the connection if it exists
	if Connections[ConnectionKey] then
		Connection:disconnect()
		Connections[ConnectionKey] = nil
	end
end

function ShowUI()
	-- Creates and reveals the UI

	-- Reveal UI if already created
	if MoveTool.UI then
		-- Reveal the UI
		MoveTool.UI.Visible = true

		-- Update the UI every 0.1 seconds
		UIUpdater = Support.ScheduleRecurringTask(UpdateUI, 0.1)

		-- Skip UI creation
		return
	end

	-- Create the UI
	MoveTool.UI = Core.Tool.Interfaces.BTMoveToolGUI:Clone()
	MoveTool.UI.Parent = Core.UI
	MoveTool.UI.Visible = true

	-- Add functionality to the axes option switch
	local AxesSwitch = MoveTool.UI.AxesOption
	AxesSwitch.Global.Button.MouseButton1Down:connect(function()
		SetAxes("Global")
	end)
	AxesSwitch.Local.Button.MouseButton1Down:connect(function()
		SetAxes("Local")
	end)
	AxesSwitch.Last.Button.MouseButton1Down:connect(function()
		SetAxes("Last")
	end)

	-- Add functionality to the increment input
	local IncrementInput = MoveTool.UI.IncrementOption.Increment.TextBox
	IncrementInput.FocusLost:connect(function(EnterPressed)
		MoveTool.Increment = tonumber(IncrementInput.Text) or MoveTool.Increment
		IncrementInput.Text = Support.Round(MoveTool.Increment, 4)
	end)

	-- Add functionality to the position inputs
	local XInput = MoveTool.UI.Info.Center.X.TextBox
	local YInput = MoveTool.UI.Info.Center.Y.TextBox
	local ZInput = MoveTool.UI.Info.Center.Z.TextBox
	XInput.FocusLost:connect(function(EnterPressed)
		local NewPosition = tonumber(XInput.Text)
		if NewPosition then
			SetAxisPosition("X", NewPosition)
		end
	end)
	YInput.FocusLost:connect(function(EnterPressed)
		local NewPosition = tonumber(YInput.Text)
		if NewPosition then
			SetAxisPosition("Y", NewPosition)
		end
	end)
	ZInput.FocusLost:connect(function(EnterPressed)
		local NewPosition = tonumber(ZInput.Text)
		if NewPosition then
			SetAxisPosition("Z", NewPosition)
		end
	end)

	-- Update the UI every 0.1 seconds
	UIUpdater = Support.ScheduleRecurringTask(UpdateUI, 0.1)
end

function HideUI()
	-- Hides the tool UI

	-- Make sure there's a UI
	if not MoveTool.UI then
		return
	end

	-- Hide the UI
	MoveTool.UI.Visible = false

	-- Stop updating the UI
	UIUpdater:Stop()
end

function UpdateUI()
	-- Updates information on the UI

	-- Make sure the UI's on
	if not MoveTool.UI then
		return
	end

	-- Only show and calculate selection info if it's not empty
	if #Selection.Items == 0 then
		MoveTool.UI.Info.Visible = false
		MoveTool.UI.Size = UDim2.new(0, 245, 0, 90)
		return
	else
		MoveTool.UI.Info.Visible = true
		MoveTool.UI.Size = UDim2.new(0, 245, 0, 150)
	end

	---------------------------------------------
	-- Update the position information indicators
	---------------------------------------------

	-- Identify common positions across axes
	local XVariations, YVariations, ZVariations = {}, {}, {}
	for _, Part in pairs(Selection.Items) do
		table.insert(XVariations, Support.Round(Part.Position.X, 3))
		table.insert(YVariations, Support.Round(Part.Position.Y, 3))
		table.insert(ZVariations, Support.Round(Part.Position.Z, 3))
	end
	local CommonX = Support.IdentifyCommonItem(XVariations)
	local CommonY = Support.IdentifyCommonItem(YVariations)
	local CommonZ = Support.IdentifyCommonItem(ZVariations)

	-- Shortcuts to indicators
	local XIndicator = MoveTool.UI.Info.Center.X.TextBox
	local YIndicator = MoveTool.UI.Info.Center.Y.TextBox
	local ZIndicator = MoveTool.UI.Info.Center.Z.TextBox

	-- Update each indicator if it's not currently being edited
	if not XIndicator:IsFocused() then
		XIndicator.Text = CommonX or "*"
	end
	if not YIndicator:IsFocused() then
		YIndicator.Text = CommonY or "*"
	end
	if not ZIndicator:IsFocused() then
		ZIndicator.Text = CommonZ or "*"
	end
end

function SetAxes(AxisMode)
	-- Sets the given axis mode

	-- Update setting
	MoveTool.Axes = AxisMode

	-- Update the UI switch
	if MoveTool.UI then
		Core.ToggleSwitch(AxisMode, MoveTool.UI.AxesOption)
	end

	-- Disable any unnecessary bounding boxes
	BoundingBox.ClearBoundingBox()

	-- For global mode, use bounding box handles
	if AxisMode == "Global" then
		BoundingBox.StartBoundingBox(AttachHandles)

	-- For local mode, use focused part handles
	elseif AxisMode == "Local" then
		AttachHandles(Selection.Focus, true)

	-- For last mode, use focused part handles
	elseif AxisMode == "Last" then
		AttachHandles(Selection.Focus, true)
	end
end
