/// <summary>Displays given message in top left corner of the screen.</summary>
        /// <param name="messageText">The message to display.</param>
        private static void AddMessageInternal(string messageText)
        {
            if (string.IsNullOrEmpty(messageText) || _mainErrorMessage == null)
            {
                return;
            }
            ErrorMessage main = (ErrorMessage)_mainErrorMessage.GetValue(null);

            if (main == null || _getExistingMessageMethod == null || _getEntryMethod == null || _messageType == null ||
                _messageEntryField == null || _messageMessageTextField == null || _messageNumField == null || _messageTimeEndField == null ||
                _timeDelayField == null || _timeFadeOutField == null || _timeInvisibleField == null || _messagesField == null)
            {
                return;
            }
            MenuMessageHelper.CleanMessages();
            float  timeDelay     = (float)_timeDelayField.GetValue(main);
            float  timeFadeOut   = (float)_timeFadeOutField.GetValue(main);
            float  timeInvisible = (float)_timeInvisibleField.GetValue(main);
            object message       = _getExistingMessageMethod.Invoke(main, new object[] { messageText });

            if (message == null)
            {
#if SUBNAUTICA
                Text entry = (Text)_getEntryMethod.Invoke(main, null);
#else
                TextMeshProUGUI entry = (TextMeshProUGUI)_getEntryMethod.Invoke(main, null);
#endif
                entry.gameObject.SetActive(true);
                entry.text = messageText;
                message    = Activator.CreateInstance(_messageType, true);
                _messageEntryField.SetValue(message, entry);
                _messageMessageTextField.SetValue(message, messageText);
                _messageNumField.SetValue(message, 1);
                _messageTimeEndField.SetValue(message, Time.time + timeDelay + timeFadeOut + timeInvisible);
                if (_messagesField.GetValue(main) is IList messages)
                {
                    messages.Add(message);
                }
                MenuMessageHelper.UpdateErrorMessages();
                return;
            }
#if SUBNAUTICA
            Text entry2 = (Text)_messageEntryField.GetValue(message);
#else
            TMP_Text entry2 = (TMP_Text)_messageEntryField.GetValue(message);
#endif
            _messageTimeEndField.SetValue(message, Time.time + timeDelay + timeFadeOut + timeInvisible);
            int messageNum = ((int)_messageNumField.GetValue(message)) + 1;
            _messageNumField.SetValue(message, messageNum);
            entry2.text = string.Format("{0} (x{1})", messageText, messageNum.ToString());
            MenuMessageHelper.UpdateErrorMessages();
        }
        /// <summary>This method gets called when a toggle value changes.</summary>
        /// <param name="sender">The object that raised the event.</param>
        /// <param name="e">The toggle change event properties (contains ID and value of the toggle).</param>
        private void ConfigOptions_ToggleChanged(object sender, ToggleChangedEventArgs e)
        {
            if (!string.IsNullOrEmpty(e?.Id))
            {
                switch (e.Id)
                {
                case "OpenDecorationsModConfigurator":
                    break;

                case "UseCompactTooltips":
                    if (e.Value != ConfigSwitcher.UseCompactTooltips)
                    {
                        ConfigSwitcher.UseCompactTooltips = e.Value;
                        ConfigSwitcher.UpdateConfigFile(Environment.NewLine + "useCompactTooltips=" + (e.Value ? "false" : "true") + Environment.NewLine, Environment.NewLine + "useCompactTooltips=" + (e.Value ? "true" : "false") + Environment.NewLine);
                        MenuMessageHelper.AddMessage("Compact tooltips " + (e.Value ? "enabled" : "disabled") + ".", e.Value ? "green" : "orange");
                    }
                    break;

                case "LockQuickslotsWhenPlacingItem":
                    if (e.Value != ConfigSwitcher.LockQuickslotsWhenPlacingItem)
                    {
                        ConfigSwitcher.LockQuickslotsWhenPlacingItem = e.Value;
                        ConfigSwitcher.UpdateConfigFile(Environment.NewLine + "lockQuickslotsWhenPlacingItem=" + (e.Value ? "false" : "true") + Environment.NewLine, Environment.NewLine + "lockQuickslotsWhenPlacingItem=" + (e.Value ? "true" : "false") + Environment.NewLine);
                        MenuMessageHelper.AddMessage("Lock quickslots when placing item " + (e.Value ? "enabled" : "disabled") + ".", e.Value ? "green" : "orange");
                    }
                    break;

                case "HideDeepGrandReefDegasiBase":
                    if (e.Value != ConfigSwitcher.HideDeepGrandReefDegasiBase)
                    {
                        ConfigSwitcher.HideDeepGrandReefDegasiBase = e.Value;
                        ConfigSwitcher.UpdateConfigFile(Environment.NewLine + "hideDeepGrandReefDegasiBase=" + (e.Value ? "false" : "true") + Environment.NewLine, Environment.NewLine + "hideDeepGrandReefDegasiBase=" + (e.Value ? "true" : "false") + Environment.NewLine);
                        PrefabsHelper.HideDegasiBase();
                        MenuMessageHelper.AddMessage("Hide Degasi base (500m) structure " + (e.Value ? "enabled" : "disabled") + ".", e.Value ? "green" : "orange");
                    }
                    break;

                default:
                    break;
                }
            }
        }
 private void ConfigOptions_ButtonClicked(object sender, ButtonClickedEventArgs e)
 {
     if (e.Id == "OpenDecorationsModConfigurator")
     {
         ConfigSwitcher.OpenDecorationsModConfigurator = !ConfigSwitcher.OpenDecorationsModConfigurator;
         // If button state changed
         if (ConfigSwitcher.OpenConfiguratorLastState != ConfigSwitcher.OpenDecorationsModConfigurator)
         {
             // Update button state
             ConfigSwitcher.OpenConfiguratorLastState = ConfigSwitcher.OpenDecorationsModConfigurator;
             // Open configurator
             string configuratorPath = ConfiguratorPath();
             if (File.Exists(configuratorPath))
             {
                 // Try launch configurator
                 try { Configurator = Process.Start(new ProcessStartInfo {
                         Arguments = "/C \"" + configuratorPath + "\"", FileName = "cmd", WindowStyle = ProcessWindowStyle.Hidden
                     }); }
                 catch (Exception ex)
                 {
                     // Cleanup any running instance on failure
                     if (Configurator != null)
                     {
                         if (!Configurator.HasExited)
                         {
                             try { Configurator.CloseMainWindow(); }
                             catch { }
                         }
                         try { Configurator.Close(); }
                         catch { }
                     }
                     // Log error
                     Logger.Log("ERROR: Unable to open configurator. Exception=[" + ex.ToString() + "]");
                     MenuMessageHelper.AddMessage("Could not open configurator. Try to open it from DecorationsMod folder or edit Config text file manually.", "orange", 22);
                 }
             }
         }
     }
 }