local U={}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 c,I in pairs(U)do I:disconnect()U[c]=nil end end function ClearConnection(c)local I=U[c]if U[c]then I:disconnect()U[c]=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 U=MoveTool.UI.AxesOption U.Global.Button.MouseButton1Down:connect(function()SetAxes("\071\108\111\098\097\108")end)U.Local.Button.MouseButton1Down:connect(function()SetAxes("\076\111\099\097\108")end)U.Last.Button.MouseButton1Down:connect(function()SetAxes("\076\097\115\116")end)local c=MoveTool.UI.IncrementOption.Increment.TextBox c.FocusLost:connect(function(U)MoveTool.Increment=tonumber(c.Text)or MoveTool.Increment c.Text=Support.Round(MoveTool.Increment,4)end)local I=MoveTool.UI.Info.Center.X.TextBox local G=MoveTool.UI.Info.Center.Y.TextBox local j=MoveTool.UI.Info.Center.Z.TextBox I.FocusLost:connect(function(U)local c=tonumber(I.Text)if c then SetAxisPosition("\088",c)end end)G.FocusLost:connect(function(U)local c=tonumber(G.Text)if c then SetAxisPosition("\089",c)end end)j.FocusLost:connect(function(U)local c=tonumber(j.Text)if c then SetAxisPosition("\090",c)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 U,c,I={},{},{}for G,j in pairs(Selection.Items)do table.insert(U,Support.Round(j.Position.X,3))table.insert(c,Support.Round(j.Position.Y,3))table.insert(I,Support.Round(j.Position.Z,3))end local G=Support.IdentifyCommonItem(U)local j=Support.IdentifyCommonItem(c)local Q=Support.IdentifyCommonItem(I)local N=MoveTool.UI.Info.Center.X.TextBox local L=MoveTool.UI.Info.Center.Y.TextBox local e=MoveTool.UI.Info.Center.Z.TextBox if not N:IsFocused()then N.Text=G or"\042"end if not L:IsFocused()then L.Text=j or"\042"end if not e:IsFocused()then e.Text=Q or"\042"end end function SetAxes(U)MoveTool.Axes=U if MoveTool.UI then Core.ToggleSwitch(U,MoveTool.UI.AxesOption)end BoundingBox.ClearBoundingBox()if U=="\071\108\111\098\097\108"then BoundingBox.StartBoundingBox(AttachHandles)elseif U=="\076\111\099\097\108"then AttachHandles(Selection.Focus,true)elseif U=="\076\097\115\116"then AttachHandles(Selection.Focus,true)end end

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;
