/// <summary>
        /// Handles a change in target building from the WorldInfoPanel.
        /// Sets the panel button state according to whether or not this building is 'levellable' and communicates changes to the ABLC panel.
        /// </summary>
        internal static void TargetChanged()
        {
            // Get current WorldInfoPanel building instance and determine maximum building level.
            if (LevelUtils.GetMaxLevel(WorldInfoPanel.GetCurrentInstanceID().Building) == 1)
            {
                // Only one building level - not a 'levellable' building, so disable the ABLC button and update the tooltip accordingly.
                panelButton.Disable();
                panelButton.tooltip = Translations.Translate("ABLC_BUT_DIS");
            }
            else
            {
                // Multiple levels available - enable the ABLC button and update the tooltip accordingly.
                panelButton.Enable();
                panelButton.tooltip = Translations.Translate("ABLC_NAME");
            }

            // Communicate target change to the panel (if it's currently instantiated).
            Panel?.BuildingChanged();
        }
        /// <summary>
        /// Updates the panel according to building's current level settings.
        /// </summary>
        internal void UpdatePanel()
        {
            // Make sure we have a valid builidng first.
            if (targetID == 0 || (Singleton <BuildingManager> .instance.m_buildings.m_buffer[targetID].m_flags == Building.Flags.None))
            {
                // Invalid target - disable buttons.
                upgradeButton.Disable();
                downgradeButton.Disable();
                return;
            }

            // Get building level.
            byte level = (Singleton <BuildingManager> .instance.m_buildings.m_buffer[targetID].m_level);

            // Check to see if the building can be upgraded one level.
            upgradeLevel = (byte)(level + 1);
            if (LevelUtils.GetTargetInfo(targetID, upgradeLevel) == null)

            {
                // Nope - disable upgrade button.
                upgradeButton.Disable();
            }
            else
            {
                // Yep - enable upgrade button.
                upgradeButton.Enable();
            }

            // Check to see if the building can be downgraded one level.
            downgradeLevel = (byte)(level - 1);
            if (LevelUtils.GetTargetInfo(targetID, downgradeLevel) == null)
            {
                // Nope - disable downgrade button.
                downgradeButton.Disable();
            }
            else
            {
                // Yep - enable downgrade button.
                downgradeButton.Enable();
            }
        }
 /// <summary>
 /// Updates the buildng's maximum level.
 /// </summary>
 /// <param name="buildingID">Building to set</param>
 /// <param name="maxLevel">New maximum level</param>
 internal static void UpdateMaxLevel(ushort buildingID, byte maxLevel)
 {
     // See if we've already got a dictionary entry for this building.
     if (levelRanges.ContainsKey(buildingID))
     {
         // We do - if this new maximum level is the maximum for this building and the minimum is zero, delete this entry.
         if (maxLevel == LevelUtils.GetMaxLevel(buildingID) && BuildingsABLC.levelRanges[buildingID].minLevel == 0)
         {
             levelRanges.Remove(buildingID);
         }
         else
         {
             // Otherwise, just update our entry's maximum target level.
             levelRanges[buildingID].maxLevel = maxLevel;
         }
     }
     else if (maxLevel < LevelUtils.GetMaxLevel(buildingID))
     {
         // If the new maximum level isn't the absolute maximum for this building, create a new dictionary entry with this maximum and default minimum levels.
         levelRanges.Add(buildingID, new LevelRange {
             minLevel = 0, maxLevel = maxLevel
         });
     }
 }
        /// <summary>
        /// Called when the selected building has changed.
        /// </summary>
        internal void BuildingChanged()
        {
            // Update selected building ID.
            targetID = WorldInfoPanel.GetCurrentInstanceID().Building;

            // Check maximum level for this building type.
            int maxLevel = LevelUtils.GetMaxLevel(targetID);

            // If building doesn't have more than one level, then we don't have any business to do here.
            if (maxLevel == 1)
            {
                BuildingPanelManager.panelButton.Disable();
                Hide();
                return;
            }
            else
            {
                // Enable info panel button.
                BuildingPanelManager.panelButton.Enable();

                // Make sure we're visible if we're not already.
                if (!isVisible)
                {
                    Show();
                }
            }

            // Disable events while we make changes to avoid triggering event handler.
            disableEvents = true;

            // Set name.
            nameLabel.text = Singleton <BuildingManager> .instance.GetBuildingName(targetID, InstanceID.Empty);

            // Build level dropdown ranges.
            minLevelDropDown.items = new string[maxLevel];
            maxLevelDropDown.items = new string[maxLevel];
            for (int i = 0; i < maxLevel; i++)
            {
                minLevelDropDown.items[i] = (i + 1).ToString();
                maxLevelDropDown.items[i] = (i + 1).ToString();
            }


            // Check to see if we have custom settings for this building.
            if (BuildingsABLC.levelRanges.ContainsKey(targetID))
            {
                // Update dropdown selection to match building's settings.
                minLevelDropDown.selectedIndex = BuildingsABLC.levelRanges[targetID].minLevel;
                maxLevelDropDown.selectedIndex = BuildingsABLC.levelRanges[targetID].maxLevel;
            }
            else
            {
                // Set min and max to default.
                minLevelDropDown.selectedIndex = 0;
                maxLevelDropDown.selectedIndex = maxLevelDropDown.items.Length - 1;
            }

            // Initialise panel with correct level settings.
            UpdatePanel();

            // All done: re-enable events.
            disableEvents = false;
        }
        /// <summary>
        /// Performs initial setup for the panel; we don't use Start() as that's not sufficiently reliable (race conditions), and is not needed with the dynamic create/destroy process.
        /// </summary>
        /// <param name="parentTransform">Transform to attach to</param>
        internal override void Setup(Transform parentTransform)
        {
            try
            {
                base.Setup(parentTransform);

                // Set initial building.
                BuildingChanged();

                // Add event handlers.
                minLevelDropDown.eventSelectedIndexChanged += (control, index) =>
                {
                    // Don't do anything if events are disabled.
                    if (!disableEvents)
                    {
                        // Set minimum level of building in dictionary.
                        UpdateMinLevel((byte)index);

                        // If the minimum level is now greater than the maximum level, increase the maximum to match the minimum.
                        if (index > maxLevelDropDown.selectedIndex)
                        {
                            maxLevelDropDown.selectedIndex = index;
                        }
                    }
                };

                maxLevelDropDown.eventSelectedIndexChanged += (control, index) =>
                {
                    // Don't do anything if events are disabled.
                    if (!disableEvents)
                    {
                        // Update maximum level.
                        UpdateMaxLevel((byte)index);

                        // If the maximum level is now less than the minimum level, reduce the minimum to match the maximum.
                        if (index < minLevelDropDown.selectedIndex)
                        {
                            minLevelDropDown.selectedIndex = index;
                        }
                    }
                };

                upgradeButton.eventClick += (control, clickEvent) =>
                {
                    LevelUtils.ForceLevel(targetID, upgradeLevel);

                    // Check to see if we should increase this buildings maximum level.
                    byte newLevel = Singleton <BuildingManager> .instance.m_buildings.m_buffer[targetID].m_level;
                    if (BuildingsABLC.levelRanges.ContainsKey(targetID) && BuildingsABLC.levelRanges[targetID].maxLevel < newLevel)
                    {
                        //BuildingsABLC.levelRanges[targetID].maxLevel = newLevel;
                        maxLevelDropDown.selectedIndex = newLevel;
                    }

                    // Update the panel once done.
                    UpdatePanel();
                };

                downgradeButton.eventClick += (control, clickEvent) =>
                {
                    LevelUtils.ForceLevel(targetID, downgradeLevel);

                    // Check to see if we should increase this buildings maximum level.
                    byte newLevel = Singleton <BuildingManager> .instance.m_buildings.m_buffer[targetID].m_level;
                    if (BuildingsABLC.levelRanges.ContainsKey(targetID) && BuildingsABLC.levelRanges[targetID].minLevel > newLevel)
                    {
                        //BuildingsABLC.levelRanges[targetID].minLevel = newLevel;
                        minLevelDropDown.selectedIndex = newLevel;
                    }

                    // Update the panel once done.
                    UpdatePanel();
                };

                // Close button.
                UIButton closeButton = AddUIComponent <UIButton>();
                closeButton.relativePosition = new Vector3(width - 35, 2);
                closeButton.normalBgSprite   = "buttonclose";
                closeButton.hoveredBgSprite  = "buttonclosehover";
                closeButton.pressedBgSprite  = "buttonclosepressed";

                // Close button event handler.
                closeButton.eventClick += (component, clickEvent) =>
                {
                    BuildingPanelManager.Close();
                };
            }
            catch (Exception e)
            {
                Logging.LogException(e, "exception setting up building panel");
            }
        }