/// <summary>
        /// Render and show a preview of a building.
        /// </summary>
        /// <param name="building">The building to render</param>
        public void Show(BuildingInfo building)
        {
            // Update current selection to the new building.
            currentSelection = building;

            // Generate render if there's a selection with a mesh.
            if (currentSelection != null && currentSelection.m_mesh != null)
            {
                // Set default values.
                previewRender.CameraRotation = 210f;
                previewRender.Zoom           = 4f;

                // Set mesh and material for render.
                previewRender.SetTarget(currentSelection);

                // Set background.
                previewSprite.texture     = previewRender.Texture;
                noPreviewSprite.isVisible = false;

                // Render at next update.
                RenderPreview();
            }
            else
            {
                // No valid current selection with a mesh; reset background.
                previewSprite.texture     = null;
                noPreviewSprite.isVisible = true;
            }

            // Hide any empty building names.
            if (building == null)
            {
                buildingName.isVisible  = false;
                buildingLevel.isVisible = false;
                buildingSize.isVisible  = false;
            }
            else
            {
                // Set and show building name.
                buildingName.isVisible = true;
                buildingName.text      = UIBuildingDetails.GetDisplayName(currentSelection.name);
                UIUtils.TruncateLabel(buildingName, width - 45);
                buildingName.autoHeight = true;

                // Set and show building level.
                buildingLevel.isVisible = true;
                buildingLevel.text      = Translations.Translate("RPR_OPT_LVL") + " " + Mathf.Min((int)currentSelection.GetClassLevel() + 1, MaxLevelOf(currentSelection.GetSubService()));
                UIUtils.TruncateLabel(buildingLevel, width - 45);
                buildingLevel.autoHeight = true;

                // Set and show building size.
                buildingSize.isVisible = true;
                buildingSize.text      = currentSelection.GetWidth() + "x" + currentSelection.GetLength();
                UIUtils.TruncateLabel(buildingSize, width - 45);
                buildingSize.autoHeight = true;
            }
        }
        /// <summary>
        /// Generates and displays a building row.
        /// </summary>
        /// <param name="data">Object to list</param>
        /// <param name="isRowOdd">If the row is an odd-numbered row (for background banding)</param>
        public void Display(object data, bool isRowOdd)
        {
            // Perform initial setup for new rows.
            if (buildingName == null)
            {
                isVisible     = true;
                canFocus      = true;
                isInteractive = true;
                width         = parent.width;
                height        = rowHeight;

                buildingName                  = AddUIComponent <UILabel>();
                buildingName.anchor           = UIAnchorStyle.Left | UIAnchorStyle.CenterVertical;
                buildingName.relativePosition = new Vector2(rowHeight / 2f, 5f);
                buildingName.width            = 200;

                // Checkboxes to indicate which items have custom settings.
                hasOverride   = AddSettingsCheck(UIBuildingFilter.HasOverrideX, "RPR_FTR_OVR");
                hasNonDefault = AddSettingsCheck(UIBuildingFilter.HasNonDefaultX, "RPR_FTR_NDC");
            }

            // Set selected building.
            thisBuilding = data as BuildingInfo;
            string thisBuildingName = thisBuilding.name;

            buildingName.text = UIBuildingDetails.GetDisplayName(thisBuildingName);

            // Update 'has override' check to correct state.
            if (PopData.instance.GetOverride(thisBuildingName) != 0 || FloorData.instance.HasOverride(thisBuildingName) != null)
            {
                // Override found.
                hasOverride.spriteName = "AchievementCheckedTrue";
            }
            else
            {
                // No override.
                hasOverride.spriteName = "AchievementCheckedFalse";
            }


            // Update 'has non-default calculation pack' check to correct state.
            if (PopData.instance.HasPackOverride(thisBuildingName) != null || FloorData.instance.HasPackOverride(thisBuildingName) != null || SchoolData.instance.HasPackOverride(thisBuildingName) != null || Multipliers.instance.HasOverride(thisBuildingName))
            {
                // Non-default calculation found.
                hasNonDefault.spriteName = "AchievementCheckedTrue";
            }
            else
            {
                // No non-default packs.
                hasNonDefault.spriteName = "AchievementCheckedFalse";
            }

            // Set initial background as deselected state.
            Deselect(isRowOdd);
        }
        /// <summary>
        /// Closes the panel by destroying the object (removing any ongoing UI overhead).
        /// </summary>
        internal static void Close()
        {
            // Save current selection for next time.
            lastSelection = Panel?.currentSelection;
            lastFilter    = Panel?.GetFilter();
            Panel?.GetListPosition(out lastIndex, out lastPostion);

            // Destroy objects and nullify for GC.
            GameObject.Destroy(_panel);
            GameObject.Destroy(uiGameObject);
            _panel       = null;
            uiGameObject = null;
        }
        /// <summary>
        /// Creates the panel object in-game and displays it.
        /// </summary>
        internal static void Open(BuildingInfo selected = null)
        {
            try
            {
                // If no instance already set, create one.
                if (uiGameObject == null)
                {
                    // Give it a unique name for easy finding with ModTools.
                    uiGameObject = new GameObject("RealPopBuildingDetails");
                    uiGameObject.transform.parent = UIView.GetAView().transform;

                    _panel = uiGameObject.AddComponent <UIBuildingDetails>();

                    // Set up panel.
                    Panel.Setup();
                }

                // Select appropriate building if there's a preselection.
                if (selected != null)
                {
                    Panel.SelectBuilding(selected);
                }
                else if (lastSelection != null)
                {
                    // Restore previous filter state.
                    if (lastFilter != null)
                    {
                        Panel.SetFilter(lastFilter);
                    }

                    // Restore previous building selection list postion and selected item (specifically in that order to ensure correct item is selected).
                    Panel.SetListPosition(lastIndex, lastPostion);
                    Panel.SelectBuilding(lastSelection);
                }


                Panel.Show();
            }
            catch (Exception e)
            {
                Logging.LogException(e, "exception opening building panel");
                return;
            }
        }