local L={}L.__index=L function L.new(W)local f={Tool=W,UI=nil,Maid=Maid.new()}return setmetatable(f,L)end function L.ShowUI(L)if L.UI then L.UI.Visible=true L.Maid.UIUpdater=Support.Loop(.1,L.UpdateUI,L)L:AttachDragListener()L:AttachAxesListener()return end L.UI=Core.Tool.Interfaces.BTMoveToolGUI:Clone()L.UI.Parent=Core.UI L.UI.Visible=true local W=L.UI.AxesOption W.Global.Button.MouseButton1Down:Connect(function()L.Tool:SetAxes("\071\108\111\098\097\108")end)W.Local.Button.MouseButton1Down:Connect(function()L.Tool:SetAxes("\076\111\099\097\108")end)W.Last.Button.MouseButton1Down:Connect(function()L.Tool:SetAxes("\076\097\115\116")end)local f=L.UI.IncrementOption.Increment.TextBox f.FocusLost:Connect(function(W)L.Tool.Increment=tonumber(f.Text)or L.Tool.Increment f.Text=Support.Round(L.Tool.Increment,4)end)local w=L.UI.Info.Center.X.TextBox local g=L.UI.Info.Center.Y.TextBox local y=L.UI.Info.Center.Z.TextBox w.FocusLost:Connect(function(W)local f=tonumber(w.Text)if f then L.Tool:SetAxisPosition("\088",f)end end)g.FocusLost:Connect(function(W)local f=tonumber(g.Text)if f then L.Tool:SetAxisPosition("\089",f)end end)y.FocusLost:Connect(function(W)local f=tonumber(y.Text)if f then L.Tool:SetAxisPosition("\090",f)end end)local O=(L.UI:WaitForChild("\084\105\116\108\101")):WaitForChild("\083\105\103\110\097\116\117\114\101")ListenForManualWindowTrigger(L.Tool.ManualText,L.Tool.Color.Color,O)L.Maid.UIUpdater=Support.Loop(.1,L.UpdateUI,L)L:AttachDragListener()L:AttachAxesListener()end function L.AttachDragListener(L)L.Maid.DragListener=L.Tool.DragChanged:Connect(function(W)L.UI.Changes.Text.Text="\109\111\118\101\100 "..(math.abs(W).." \115\116\117\100\115")end)end function L.AttachAxesListener(L)L.Maid.AxesListener=L.Tool.AxesChanged:Connect(function(W)Core.ToggleSwitch(W,L.UI.AxesOption)end)end function L.HideUI(L)if not L.UI then return end L.UI.Visible=false L.Maid:Destroy()end function L.UpdateUI(L)if not L.UI then return end if#Selection.Parts==0 then L.UI.Info.Visible=false L.UI.Size=UDim2.new(0,245,0,90)return else L.UI.Info.Visible=true L.UI.Size=UDim2.new(0,245,0,150)end local W,f,w={},{},{}for L,g in pairs(Selection.Parts)do table.insert(W,Support.Round(g.Position.X,3))table.insert(f,Support.Round(g.Position.Y,3))table.insert(w,Support.Round(g.Position.Z,3))end local g=Support.IdentifyCommonItem(W)local y=Support.IdentifyCommonItem(f)local O=Support.IdentifyCommonItem(w)local T=L.UI.Info.Center.X.TextBox local Y=L.UI.Info.Center.Y.TextBox local l=L.UI.Info.Center.Z.TextBox if not T:IsFocused()then T.Text=g or"\042"end if not Y:IsFocused()then Y.Text=y or"\042"end if not l:IsFocused()then l.Text=O or"\042"end end function L.FocusIncrementInput(L)L.UI.IncrementOption.Increment.TextBox:CaptureFocus()end return L

local UIController = {}
UIController.__index = UIController

function UIController.new(Tool)
    local self = {
        Tool = Tool;

        -- State
        UI = nil;
        Maid = Maid.new()
    }

    return setmetatable(self, UIController)
end

function UIController:ShowUI()
	-- Creates and reveals the UI

	-- Reveal UI if already created
	if self.UI then
		self.UI.Visible = true
        self.Maid.UIUpdater = Support.Loop(0.1, self.UpdateUI, self)
        self:AttachDragListener()
        self:AttachAxesListener()
		return
	end

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

	-- Add functionality to the axes option switch
	local AxesSwitch = self.UI.AxesOption
	AxesSwitch.Global.Button.MouseButton1Down:Connect(function ()
		self.Tool:SetAxes('Global')
	end)
	AxesSwitch.Local.Button.MouseButton1Down:Connect(function ()
		self.Tool:SetAxes('Local')
	end)
	AxesSwitch.Last.Button.MouseButton1Down:Connect(function ()
		self.Tool:SetAxes('Last')
	end)

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

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

	-- Hook up manual triggering
	local SignatureButton = self.UI:WaitForChild('Title'):WaitForChild('Signature')
	ListenForManualWindowTrigger(self.Tool.ManualText, self.Tool.Color.Color, SignatureButton)

	-- Update the UI every 0.1 seconds
    self.Maid.UIUpdater = Support.Loop(0.1, self.UpdateUI, self)

    -- Attach state listeners
    self:AttachDragListener()
    self:AttachAxesListener()

end

function UIController:AttachDragListener()
    self.Maid.DragListener = self.Tool.DragChanged:Connect(function (Distance)

        -- Update the "distance moved" indicator
        self.UI.Changes.Text.Text = 'moved ' .. math.abs(Distance) .. ' studs'

    end)
end

function UIController:AttachAxesListener()
    self.Maid.AxesListener = self.Tool.AxesChanged:Connect(function (AxesMode)

        -- Update the UI switch
        Core.ToggleSwitch(AxesMode, self.UI.AxesOption)

    end)
end

function UIController:HideUI()
	-- Hides the tool UI

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

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

	-- Stop updating the UI
    self.Maid:Destroy()

end

function UIController:UpdateUI()
	-- Updates information on the UI

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

	-- Only show and calculate selection info if it's not empty
	if #Selection.Parts == 0 then
		self.UI.Info.Visible = false
		self.UI.Size = UDim2.new(0, 245, 0, 90)
		return
	else
		self.UI.Info.Visible = true
		self.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.Parts) 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 = self.UI.Info.Center.X.TextBox
	local YIndicator = self.UI.Info.Center.Y.TextBox
	local ZIndicator = self.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 UIController:FocusIncrementInput()
    self.UI.IncrementOption.Increment.TextBox:CaptureFocus()
end

return UIController
