public bool TryNavigate(NavigationDirection Direction, NavigationWrappingMode HorizontalWrapping, NavigationWrappingMode VerticalWrapping)
        {
            Rectangle?HoveredSlot = GetHoveredSlot(false);

            if (IsGamepadFocused && HoveredSlot == null)
            {
                HoveredBundleItem       = ItemSlotPositions.First().Key;
                IsNavigatingWithGamepad = HoveredBundleItem != null;
                return(HoveredBundleItem != null);
            }
            else if (TryGetSlotNeighbor(HoveredSlot, Direction, HorizontalWrapping, VerticalWrapping, out Rectangle? Neighbor))
            {
                foreach (KeyValuePair <BundleItem, Rectangle> KVP in ItemSlotPositions)
                {
                    if (KVP.Value == Neighbor.Value)
                    {
                        HoveredBundleItem       = KVP.Key;
                        HoveredBundleTask       = null;
                        IsNavigatingWithGamepad = true;
                        return(true);
                    }
                }

                foreach (KeyValuePair <BundleTask, Rectangle> KVP in TaskHeaderPositions)
                {
                    if (KVP.Value == Neighbor.Value)
                    {
                        HoveredBundleTask       = KVP.Key;
                        HoveredBundleItem       = null;
                        IsNavigatingWithGamepad = true;
                        return(true);
                    }
                }

                HoveredBundleItem = null;
                HoveredBundleTask = null;

                return(false);
            }
            else
            {
                return(false);
            }
        }
        public void InitializeLayout(int ResizeIteration)
        {
            if (BundleBag == null)
            {
                return;
            }

            if (ResizeIteration > 1)
            {
                this.SlotSize = Math.Min(OriginalSlotSize, Math.Max(24, OriginalSlotSize - (ResizeIteration - 1) * 8));
            }

            if (IsJojaMember)
            {
                this.RelativeBounds = new Rectangle(0, 0, 640 + Padding * 2, 288 + Padding * 2);
            }
            else
            {
                HoveredBundleTask = null;
                HoveredBundleItem = null;
                SecondaryActionButtonPressedTime = null;
                SecondaryActionButtonPressedItem = null;

                int RoomBottomMargin = 12;
                int RoomRightMargin  = 8;

                int StartX = Padding;
                int StartY = Padding;

                CommunityCenterBundles CC = CommunityCenterBundles.Instance;

                this.RoomHeaderPositions = new Dictionary <BundleRoom, Rectangle>();
                this.RoomSlotPositions   = new Dictionary <BundleRoom, List <Rectangle> >();
                this.TaskHeaderPositions = new Dictionary <BundleTask, Rectangle>();
                this.TaskSlotPositions   = new Dictionary <BundleTask, List <Rectangle> >();
                this.ItemSlotPositions   = new OrderedDictionary <BundleItem, Rectangle>();
                this.LockedSlotPositions = new List <Rectangle>();

                int RoomNameWidth = CC.Rooms.Select(x => (int)(RoomHeaderFont.MeasureString(x.DisplayName).X *RoomHeaderScale)).DefaultIfEmpty(100).Max() + 32;

                int CurrentRow    = 0;
                int CurrentColumn = 0;
                int RoomIndex     = 0;
                foreach (BundleRoom Room in CC.Rooms)
                {
                    if (BundleBag.InvalidRooms[BundleBag.Size].Contains(Room.Name))
                    {
                        continue;
                    }

                    Rectangle RoomHeader = new Rectangle(StartX, StartY + CurrentRow * SlotSize + RoomIndex * RoomBottomMargin, RoomNameWidth, SlotSize);
                    RoomHeaderPositions.Add(Room, RoomHeader);

                    List <Rectangle> CurrentRoomSlotPositions = new List <Rectangle>();
                    RoomSlotPositions.Add(Room, CurrentRoomSlotPositions);

                    foreach (BundleTask Task in Room.Tasks)
                    {
                        if (CurrentColumn == ColumnCount)
                        {
                            CurrentColumn = 0;
                            CurrentRow++;
                        }

                        Rectangle TaskHeader = new Rectangle(StartX + RoomNameWidth + RoomRightMargin + CurrentColumn * SlotSize, StartY + CurrentRow * SlotSize + RoomIndex * RoomBottomMargin, SlotSize, SlotSize);
                        TaskHeaderPositions.Add(Task, TaskHeader);
                        CurrentRoomSlotPositions.Add(TaskHeader);

                        List <Rectangle> CurrentTaskSlotPositions = new List <Rectangle>();
                        TaskSlotPositions.Add(Task, CurrentTaskSlotPositions);

                        CurrentColumn++;

                        foreach (BundleItem Item in Task.Items)
                        {
                            if (!BundleTask.IsValidItemId(Item.Id))
                            {
                                continue;
                            }

                            if (CurrentColumn == ColumnCount)
                            {
                                CurrentColumn = 0;
                                CurrentRow++;
                            }

                            Rectangle Slot = new Rectangle(StartX + RoomNameWidth + RoomRightMargin + CurrentColumn * SlotSize, StartY + CurrentRow * SlotSize + RoomIndex * RoomBottomMargin, SlotSize, SlotSize);
                            CurrentRoomSlotPositions.Add(Slot);
                            CurrentTaskSlotPositions.Add(Slot);
                            ItemSlotPositions.Add(Item, Slot);

                            CurrentColumn++;
                        }
                    }

                    if (ShowLockedSlots)
                    {
                        while (CurrentColumn < ColumnCount)
                        {
                            Rectangle LockedSlot = new Rectangle(StartX + RoomNameWidth + RoomRightMargin + CurrentColumn * SlotSize, StartY + CurrentRow * SlotSize + RoomIndex * RoomBottomMargin, SlotSize, SlotSize);
                            LockedSlotPositions.Add(LockedSlot);
                            CurrentColumn++;
                        }
                    }

                    CurrentColumn = 0;
                    CurrentRow++;
                    RoomIndex++;
                }

                this.RelativeBounds = new Rectangle(0, 0, Padding + RoomNameWidth + RoomRightMargin + ColumnCount * SlotSize + Padding,
                                                    Padding + CurrentRow * SlotSize + Padding + (RoomIndex - 1) * RoomBottomMargin);
            }
        }
        public bool TryNavigateEnter(NavigationDirection StartingSide, Rectangle?ClosestTo)
        {
            IsGamepadFocused        = true;
            IsNavigatingWithGamepad = true;

            if (ClosestTo.HasValue)
            {
                List <Rectangle> AllSlots = TaskHeaderPositions.Select(x => x.Value).Union(ItemSlotPositions.Select(x => x.Value)).ToList();
                Rectangle        ToSelect = AllSlots.OrderBy(x => x.GetOffseted(TopLeftScreenPosition).SquaredDistanceBetweenCenters(ClosestTo.Value)).First();

                foreach (KeyValuePair <BundleItem, Rectangle> KVP in ItemSlotPositions)
                {
                    if (KVP.Value == ToSelect)
                    {
                        HoveredBundleItem = KVP.Key;
                        HoveredBundleTask = null;
                        return(true);
                    }
                }

                foreach (KeyValuePair <BundleTask, Rectangle> KVP in TaskHeaderPositions)
                {
                    if (KVP.Value == ToSelect)
                    {
                        HoveredBundleTask = KVP.Key;
                        HoveredBundleItem = null;
                        return(true);
                    }
                }
            }

            if (StartingSide == NavigationDirection.Right)
            {
                while (TryNavigate(NavigationDirection.Right, NavigationWrappingMode.NoWrap, NavigationWrappingMode.NoWrap))
                {
                }
            }
            if (StartingSide == NavigationDirection.Down)
            {
                while (TryNavigate(NavigationDirection.Down, NavigationWrappingMode.NoWrap, NavigationWrappingMode.NoWrap))
                {
                }
            }

            return(true);
        }
        public bool TryGetSlotNeighbor(Rectangle?ItemSlot, NavigationDirection Direction, NavigationWrappingMode HorizontalWrapping, NavigationWrappingMode VerticalWrapping, out Rectangle?Neighbor)
        {
            List <Rectangle> AllSlots = TaskHeaderPositions.Select(x => x.Value).Union(ItemSlotPositions.Select(x => x.Value)).Union(LockedSlotPositions)
                                        .OrderBy(x => x.Top).ThenBy(x => x.Left).ToList();

            return(GamepadControls.TryGetSlotNeighbor(AllSlots, ItemSlot, ColumnCount, Direction, HorizontalWrapping, VerticalWrapping, out Neighbor));
        }