-- Menus
function Icon:setMenu(arrayOfIcons)
	-- Reset any previous icons
	for i, otherIcon in pairs(self.menuIcons) do
		otherIcon:leave()
	end
	-- Apply new icons
	if type(arrayOfIcons) == "table" then
		for i, otherIcon in pairs(arrayOfIcons) do
			otherIcon:join(self, "menu", true)
		end
	end
	-- Update menu
	self:_updateMenu()
	return self
end

function Icon:_getMenuDirection()
	local direction = (self:get("menuDirection") or "_NIL"):lower()
	local alignment = (self:get("alignment") or "_NIL"):lower()
	if direction ~= "left" and direction ~= "right" then
		direction = (alignment == "left" and "right") or "left" 
	end
	return direction
end

function Icon:_updateMenu()
	local values = {
		maxIconsBeforeScroll = self:get("menuMaxIconsBeforeScroll") or "_NIL",
		direction = self:get("menuDirection") or "_NIL",
		iconAlignment = self:get("alignment") or "_NIL",
		scrollBarThickness = self:get("menuScrollBarThickness") or "_NIL",
	}
	for k, v in pairs(values) do if v == "_NIL" then return end end
	
	local XPadding = IconController[values.iconAlignment.."Gap"]--12
	local menuContainer = self.instances.menuContainer
	local menuFrame = self.instances.menuFrame
	local menuList = self.instances.menuList
	local totalIcons = #self.menuIcons

	local direction = self:_getMenuDirection()
	local lastVisibleIconIndex = (totalIcons > values.maxIconsBeforeScroll and values.maxIconsBeforeScroll) or totalIcons
	local newCanvasSizeX = -XPadding
	local newFrameSizeX = 0
	local newMinHeight = 0
	local sortFunc = (direction == "right" and function(a,b) return a:get("order") < b:get("order") end) or function(a,b) return a:get("order") > b:get("order") end
	table.sort(self.menuIcons, sortFunc)
	for i = 1, totalIcons do
		local otherIcon = self.menuIcons[i]
		local otherIconSize = otherIcon:get("iconSize")
		local increment = otherIconSize.X.Offset + XPadding
		if i <= lastVisibleIconIndex then
			newFrameSizeX = newFrameSizeX + increment
		end
		if i == lastVisibleIconIndex and i ~= totalIcons then
			newFrameSizeX = newFrameSizeX -2--(increment/4)
		end
		newCanvasSizeX = newCanvasSizeX + increment
		local otherIconHeight = otherIconSize.Y.Offset
		if otherIconHeight > newMinHeight then
			newMinHeight = otherIconHeight
		end
		-- This ensures the menu is navigated fully and correctly with a controller
		local prevIcon = self.menuIcons[i-1]
		local nextIcon = self.menuIcons[i+1]
		otherIcon.instances.iconButton.NextSelectionRight = prevIcon and prevIcon.instances.iconButton
		otherIcon.instances.iconButton.NextSelectionLeft = nextIcon and nextIcon.instances.iconButton
	end

	local canvasSize = (lastVisibleIconIndex == totalIcons and 0) or newCanvasSizeX + XPadding
	self:set("menuCanvasSize", UDim2.new(0, canvasSize, 0, 0))
	self:set("menuSize", UDim2.new(0, newFrameSizeX, 0, newMinHeight + values.scrollBarThickness + 3))

	-- Set direction
	local directionDetails = {
		left = {
			containerAnchorPoint = Vector2.new(1, 0),
			containerPosition = UDim2.new(0, -4, 0, 0),
			canvasPosition = Vector2.new(canvasSize, 0)
		},
		right = {
			containerAnchorPoint = Vector2.new(0, 0),
			containerPosition = UDim2.new(1, XPadding-2, 0, 0),
			canvasPosition = Vector2.new(0, 0),
		}
	}
	local directionDetail = directionDetails[direction]
	menuContainer.AnchorPoint = directionDetail.containerAnchorPoint
	menuContainer.Position = directionDetail.containerPosition
	menuFrame.CanvasPosition = directionDetail.canvasPosition
	self._menuCanvasPos = directionDetail.canvasPosition

	menuList.Padding = UDim.new(0, XPadding)
end

function Icon:_menuIgnoreClipping()
	self:_ignoreClipping("menu")
end