protected override Rect Setup()
        {
            formatter = (System.Globalization.NumberFormatInfo)System.Globalization.NumberFormatInfo.CurrentInfo.Clone();
            formatter.CurrencySymbol        = string.Empty;
            formatter.CurrencyDecimalDigits = 2;
            formatter.NumberDecimalDigits   = 2;
            formatter.PercentDecimalDigits  = 2;
            audio = AudioPlayer.Audio;
            if (audio == null)
            {
                Log.Debug("[ScienceAlert]:DraggableOptionsWindow: Failed to find AudioPlayer instance");
            }

            filterList.Add(new GUIContent("Unresearched"));
            filterList.Add(new GUIContent("Not maxed"));
            filterList.Add(new GUIContent("< 50% collected"));
            filterList.Add(new GUIContent("< 90% collected"));

            openButton     = ResourceUtil.GetEmbeddedTexture("Textures.btnOpen.png");
            deleteButton   = ResourceUtil.GetEmbeddedTexture("Textures.btnDelete.png");
            renameButton   = ResourceUtil.GetEmbeddedTexture("Textures.btnRename.png");
            saveButton     = ResourceUtil.GetEmbeddedTexture("Textures.btnSave.png");
            expandButton   = ResourceUtil.GetEmbeddedTexture("Textures.btnExpand.png");
            collapseButton = Instantiate(expandButton);
            ResourceUtil.FlipTexture(collapseButton, true, true);
            collapseButton.Compress(false);
            expandButton.Compress(false);

            blackPixel.SetPixel(0, 0, Color.black);
            blackPixel.Apply();
            blackPixel.filterMode = FilterMode.Bilinear;
            whiteLabel            = Instantiate(Settings.Skin);
            whiteLabel.label.onNormal.textColor  = Color.white;
            whiteLabel.toggle.onNormal.textColor = Color.white;
            whiteLabel.label.onActive.textColor  = Color.white;
            submenu       = OpenPane.None;
            Title         = "ScienceAlert Options";
            miniLabelLeft = new GUIStyle(Skin.label)
            {
                fontSize = 10
            };
            miniLabelLeft.normal.textColor = miniLabelLeft.onNormal.textColor = Color.white;
            miniLabelRight = new GUIStyle(miniLabelLeft)
            {
                alignment = TextAnchor.MiddleRight
            };
            miniLabelCenter = new GUIStyle(miniLabelLeft)
            {
                alignment = TextAnchor.MiddleCenter
            };
            Settings.Instance.OnSave += OnAboutToSave;
            OnVisibilityChange       += OnVisibilityChanged;
            GameEvents.onVesselChange.Add(OnVesselChanged);
            LoadFrom(Settings.Instance.additional.GetNode("OptionsWindow") ?? new ConfigNode());
            return(new Rect(windowRect.x, windowRect.y, 324f, Screen.height / 5 * 3));
        }
 private void LoadTargetProfile()
 {
     DismissPopup();
     if (!ScienceAlertProfileManager.AssignAsActiveProfile(editProfile.Clone()))
     {
         return;
     }
     submenu = OpenPane.None;
     OnVisibilityChanged(Visible);
 }
        private void DrawProfileList()
        {
            profileScrollPos = GUILayout.BeginScrollView(profileScrollPos, Settings.Skin.scrollView);
            bool profilesExist = false;

            if (ScienceAlertProfileManager.Count > 0)
            {
                GUILayout.Label(Localizer.Format("#ScienceAlert_label17"));//"Select a profile to load"
                GUILayout.Box(blackPixel, GUILayout.ExpandWidth(true), GUILayout.MinHeight(1f), GUILayout.MaxHeight(3f));
                GUILayout.Space(4f);
                Dictionary <string, Profile> profiles = ScienceAlertProfileManager.Profiles;
                DrawProfileList_ListItem(ScienceAlertProfileManager.DefaultProfile);

                foreach (var current in profiles.Values)
                {
                    if (current != ScienceAlertProfileManager.DefaultProfile)
                    {
                        DrawProfileList_ListItem(current);
                        profilesExist = true;
                    }
                }

                // Uuugh   ungly GOTO, must get rid of it
#if false
                using (Dictionary <string, Profile> .ValueCollection.Enumerator enumerator = profiles.Values.GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        Profile current = enumerator.Current;
                        if (current != ScienceAlertProfileManager.DefaultProfile)
                        {
                            DrawProfileList_ListItem(current);
                        }
                    }
                    goto IL_F1;
                }
#endif
            }
            if (!profilesExist)
            {
                GUILayout.FlexibleSpace();
                GUILayout.Box(Localizer.Format("#ScienceAlert_label18"), GUILayout.MinHeight(64f));//"No profiles saved"
                GUILayout.FlexibleSpace();
            }
            //IL_F1:
            GUILayout.Space(10f);
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (AudibleButton(new GUIContent(Localizer.Format("#ScienceAlert_button10"), "Cancel load operation")))//"Cancel"
            {
                submenu = OpenPane.None;
            }
            GUILayout.EndHorizontal();
            GUILayout.EndScrollView();
        }
        private void DrawProfileList()
        {
            profileScrollPos = GUILayout.BeginScrollView(profileScrollPos, Settings.Skin.scrollView);
            {
                if (ProfileManager.Count > 0)
                {
                    //DrawProfileList_HorizontalDivider();
                    GUILayout.Label("Select a profile to load");
                    GUILayout.Box(blackPixel, GUILayout.ExpandWidth(true), GUILayout.MinHeight(1f), GUILayout.MaxHeight(3f));
                    GUILayout.Space(4f); // just a bit of space to make the bar we drew stand out more

                    var profileList = ProfileManager.Profiles;

                    // always draw default profile first
                    DrawProfileList_ListItem(ProfileManager.DefaultProfile);

                    foreach (ProfileData.Profile profile in profileList.Values)
                    {
                        if (profile != ProfileManager.DefaultProfile)
                        {
                            DrawProfileList_ListItem(profile);
                        }
                    }
                }
                else // no profiles saved
                {
                    GUILayout.FlexibleSpace();
                    GUILayout.Box("No profiles saved", GUILayout.MinHeight(64f));
                    GUILayout.FlexibleSpace();
                }
            }
            GUILayout.Space(10f);
            GUILayout.BeginHorizontal();
            {
                GUILayout.FlexibleSpace();
                if (AudibleButton(new GUIContent("Cancel", "Cancel load operation")))
                {
                    submenu = OpenPane.None;
                }
            }
            GUILayout.EndHorizontal();
            GUILayout.EndScrollView();
        }
        protected override void DrawUI()
        {
            GUILayout.BeginVertical(GUILayout.ExpandWidth(true), GUILayout.Height(Screen.height / 5 * 3));
            GUILayout.Label(new GUIContent(Localizer.Format("#ScienceAlert_label1")), GUILayout.ExpandWidth(true));//"Global Warp Settings"
            Settings.Instance.GlobalWarp = (Settings.WarpSetting)GUILayout.SelectionGrid((int)Settings.Instance.GlobalWarp, new[]
            {
                new GUIContent(Localizer.Format("#ScienceAlert_button5")),                                          //"By Experiment"
                new GUIContent(Localizer.Format("#ScienceAlert_button6")),                                          //"Globally on"
                new GUIContent(Localizer.Format("#ScienceAlert_button7"))                                           //"Globally off"
            }, 3, GUILayout.ExpandWidth(false));
            GUILayout.Label(new GUIContent(Localizer.Format("#ScienceAlert_label2")), GUILayout.ExpandWidth(true)); //"Global Alert Sound"
            Settings.Instance.SoundNotification = (Settings.SoundNotifySetting)GUILayout.SelectionGrid((int)Settings.Instance.SoundNotification, new[]
            {
                new GUIContent(Localizer.Format("#ScienceAlert_button5")), //"By Experiment"
                new GUIContent(Localizer.Format("#ScienceAlert_button8")), //"Always"
                new GUIContent(Localizer.Format("#ScienceAlert_button9"))  //"Never"
            }, 3, GUILayout.ExpandWidth(false));
            GUILayout.Space(4f);
            GUILayout.BeginHorizontal();
            GUILayout.Label(new GUIContent(Localizer.Format("#ScienceAlert_label3")));//"Additional Options"
            GUILayout.FlexibleSpace();
            if (AudibleButton(new GUIContent(submenu == OpenPane.AdditionalOptions ? collapseButton : expandButton)))
            {
                submenu = submenu == OpenPane.AdditionalOptions ? OpenPane.None : OpenPane.AdditionalOptions;
            }
            GUILayout.EndHorizontal();
            switch (submenu)
            {
            case OpenPane.None:
                DrawProfileSettings();
                break;

            case OpenPane.AdditionalOptions:
                DrawAdditionalOptions();
                break;

            case OpenPane.LoadProfiles:
                DrawProfileList();
                break;
            }
            GUILayout.EndVertical();
        }
        protected override void DrawUI()
        {
            GUILayout.BeginVertical(GUILayout.ExpandWidth(true), GUILayout.Height(Screen.height / 5 * 3));
            {
                GUILayout.Label(new GUIContent("Global Warp Settings"), GUILayout.ExpandWidth(true));
                Settings.Instance.GlobalWarp = (Settings.WarpSetting)GUILayout.SelectionGrid((int)Settings.Instance.GlobalWarp, new GUIContent[] { new GUIContent("By Experiment"), new GUIContent("Globally on"), new GUIContent("Globally off") }, 3, GUILayout.ExpandWidth(false));

                GUILayout.Label(new GUIContent("Global Alert Sound"), GUILayout.ExpandWidth(true));
                Settings.Instance.SoundNotification = (Settings.SoundNotifySetting)GUILayout.SelectionGrid((int)Settings.Instance.SoundNotification, new GUIContent[] { new GUIContent("By Experiment"), new GUIContent("Always"), new GUIContent("Never") }, 3, GUILayout.ExpandWidth(false));

                GUILayout.Space(4f);

                GUILayout.BeginHorizontal();
                GUILayout.Label(new GUIContent("Additional Options"));
                GUILayout.FlexibleSpace();
                //additionalOptions = AudibleButton(new GUIContent(additionalOptions ? collapseButton : expandButton)) ? !additionalOptions : additionalOptions;

                if (AudibleButton(new GUIContent(submenu == OpenPane.AdditionalOptions ? collapseButton : expandButton)))
                {
                    submenu = submenu == OpenPane.AdditionalOptions ? OpenPane.None : OpenPane.AdditionalOptions;
                }

                GUILayout.EndHorizontal();

                switch (submenu)
                {
                case OpenPane.None:
                    DrawProfileSettings();
                    break;

                case OpenPane.AdditionalOptions:
                    DrawAdditionalOptions();
                    break;

                case OpenPane.LoadProfiles:
                    DrawProfileList();
                    break;
                }
            }
            GUILayout.EndVertical();
        }
        private void DrawProfileList()
        {
            profileScrollPos = GUILayout.BeginScrollView(profileScrollPos, Settings.Skin.scrollView);
            if (ScienceAlertProfileManager.Count > 0)
            {
                GUILayout.Label("Select a profile to load");
                GUILayout.Box(blackPixel, GUILayout.ExpandWidth(true), GUILayout.MinHeight(1f), GUILayout.MaxHeight(3f));
                GUILayout.Space(4f);
                Dictionary <string, Profile> profiles = ScienceAlertProfileManager.Profiles;
                DrawProfileList_ListItem(ScienceAlertProfileManager.DefaultProfile);
                using (Dictionary <string, Profile> .ValueCollection.Enumerator enumerator = profiles.Values.GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        Profile current = enumerator.Current;
                        if (current != ScienceAlertProfileManager.DefaultProfile)
                        {
                            DrawProfileList_ListItem(current);
                        }
                    }
                    goto IL_F1;
                }
            }
            GUILayout.FlexibleSpace();
            GUILayout.Box("No profiles saved", GUILayout.MinHeight(64f));
            GUILayout.FlexibleSpace();
IL_F1:
            GUILayout.Space(10f);
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (AudibleButton(new GUIContent("Cancel", "Cancel load operation")))
            {
                submenu = OpenPane.None;
            }
            GUILayout.EndHorizontal();
            GUILayout.EndScrollView();
        }
        private void DrawProfileSettings()
        {
            if (ScienceAlertProfileManager.HasActiveProfile)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Box(Localizer.Format("#ScienceAlert_label11", ScienceAlertProfileManager.ActiveProfile.DisplayName), GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true));//$"Profile: <<1>>{}"
                if (AudibleButton(new GUIContent(renameButton), GUILayout.MaxWidth(24f)))
                {
                    SpawnRenamePopup(ScienceAlertProfileManager.ActiveProfile);
                }
                GUI.enabled = ScienceAlertProfileManager.ActiveProfile.modified;
                if (AudibleButton(new GUIContent(saveButton), GUILayout.MaxWidth(24f)))
                {
                    SpawnSavePopup();
                }
                GUI.enabled = true;
                if (AudibleButton(new GUIContent(openButton), GUILayout.MaxWidth(24f)))
                {
                    submenu = OpenPane.LoadProfiles;
                }
                GUILayout.EndHorizontal();
                scrollPos = GUILayout.BeginScrollView(scrollPos, Settings.Skin.scrollView);
                GUI.skin  = Settings.Skin;
                GUILayout.Space(4f);
                GUI.SetNextControlName("ThresholdHeader");
                GUILayout.Box(Localizer.Format("#ScienceAlert_label12"));//"Alert Threshold"
                GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true), GUILayout.MinHeight(14f));
                if (ScienceAlertProfileManager.ActiveProfile.ScienceThreshold > 0f)
                {
                    GUILayout.Label(Localizer.Format("#ScienceAlert_label13", ScienceAlertProfileManager.ActiveProfile.ScienceThreshold.ToString("F2", formatter)));//$"Alert Threshold: <<1>>"
                }
                else
                {
                    Color color = GUI.color;
                    GUI.color = XKCDColors.Salmon;
                    GUILayout.Label(Localizer.Format("#ScienceAlert_label14"));//"(disabled)"
                    GUI.color = color;
                }
                GUILayout.FlexibleSpace();
                if (string.IsNullOrEmpty(thresholdValue))
                {
                    thresholdValue = ScienceAlertProfileManager.ActiveProfile.scienceThreshold.ToString("F2", formatter);
                }
                GUI.SetNextControlName("ThresholdText");
                string s = GUILayout.TextField(thresholdValue, GUILayout.MinWidth(60f));
                if (Event.current.keyCode == KeyCode.Escape)
                {
                    GUI.FocusControl("ThresholdHeader");
                }
                if (GUI.GetNameOfFocusedControl() == "ThresholdText")
                {
                    try
                    {
                        float scienceThreshold = float.Parse(s, formatter);
                        ScienceAlertProfileManager.ActiveProfile.ScienceThreshold = scienceThreshold;
                        thresholdValue = s;
                    }
                    catch (System.Exception)
                    {
                        // ignored
                    }
                    if (!InputLockManager.IsLocked(ControlTypes.ACTIONS_ALL))
                    {
                        InputLockManager.SetControlLock(ControlTypes.ACTIONS_ALL, "ScienceAlertThreshold");
                    }
                }
                else if (InputLockManager.GetControlLock("ScienceAlertThreshold") != ControlTypes.None)
                {
                    InputLockManager.RemoveControlLock("ScienceAlertThreshold");
                }
                GUILayout.EndHorizontal();
                GUILayout.Space(3f);
                var num = GUILayout.HorizontalSlider(ScienceAlertProfileManager.ActiveProfile.ScienceThreshold, 0f, 100f, GUILayout.ExpandWidth(true), GUILayout.Height(14f));
                if (num != ScienceAlertProfileManager.ActiveProfile.scienceThreshold)
                {
                    ScienceAlertProfileManager.ActiveProfile.ScienceThreshold = num;
                    thresholdValue = num.ToString("F2", formatter);
                }
                GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true), GUILayout.MaxHeight(10f));
                GUILayout.Label("0", miniLabelLeft);
                GUILayout.FlexibleSpace();
                GUILayout.Label(Localizer.Format("#ScienceAlert_label15"), miniLabelCenter);//"Science Amount"
                GUILayout.FlexibleSpace();
                GUILayout.Label("100", miniLabelRight);
                GUILayout.EndHorizontal();
                GUILayout.Space(10f);
                List <string> list = new List <string>(experimentIds.Keys);
                for (int i = list.Count - 1; i >= 0; i--)
                {
                    string current = list[i];

                    GUILayout.Space(4f);
                    ExperimentSettings experimentSettings = ScienceAlertProfileManager.ActiveProfile[current];
                    string             experimentTitle    = ResearchAndDevelopment.GetExperiment(current).experimentTitle;
                    GUILayout.Box(experimentTitle, GUILayout.ExpandWidth(true));
                    experimentSettings.Enabled = AudibleToggle(experimentSettings.Enabled, Localizer.Format("#ScienceAlert_toggle6"));                           //"Enabled"
                    experimentSettings.AnimationOnDiscovery = AudibleToggle(experimentSettings.AnimationOnDiscovery, Localizer.Format("#ScienceAlert_toggle7")); //"Animation on discovery"
                    experimentSettings.SoundOnDiscovery     = AudibleToggle(experimentSettings.SoundOnDiscovery, Localizer.Format("#ScienceAlert_toggle8"));     //"Sound on discovery"
                    experimentSettings.StopWarpOnDiscovery  = AudibleToggle(experimentSettings.StopWarpOnDiscovery, Localizer.Format("#ScienceAlert_toggle9"));  //"Stop warp on discovery"
                    GUILayout.Label(new GUIContent(Localizer.Format("#ScienceAlert_toggle10")), GUILayout.ExpandWidth(true), GUILayout.MinHeight(24f));          //"Filter Method"
                    int num2 = experimentIds[current];
                    experimentIds[current] = AudibleSelectionGrid(num2, ref experimentSettings);
                }
                GUILayout.EndScrollView();
                return;
            }
            GUI.color = Color.red;
            GUILayout.Label(Localizer.Format("#ScienceAlert_label16"));//"No profile active"
        }
        /******************************************************************************
        *                    Implementation Details
        ******************************************************************************/

        protected override Rect Setup()
        {
            // position blocker in front of ApplicationLauncher buttons. The window is going to be drawn on
            // top of them regardless; this will just prevent us from accidentally interacting with them
            backstop.SetZ(ApplicationLauncher.Instance.anchor.transform.position.z - 50f);

            // culture setting
            Log.Normal("Configuring NumberFormatInfo for current locale");
            formatter = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();
            formatter.CurrencySymbol        = string.Empty;
            formatter.CurrencyDecimalDigits = 2;
            formatter.NumberDecimalDigits   = 2;
            formatter.PercentDecimalDigits  = 2;


            audio = AudioPlayer.Audio;

            if (audio == null)
            {
                Log.Error("DraggableOptionsWindow: Failed to find AudioPlayer instance");
            }


            var rawIds    = ResearchAndDevelopment.GetExperimentIDs();
            var sortedIds = rawIds.OrderBy(expid => ResearchAndDevelopment.GetExperiment(expid).experimentTitle);

            Log.Debug("OptionsWindow: sorted {0} experiment IDs", sortedIds.Count());

            foreach (var id in sortedIds)
            {
                experimentIds.Add(id, (int)Convert.ChangeType(ProfileManager.ActiveProfile[id].Filter, ProfileManager.ActiveProfile[id].Filter.GetTypeCode()));
                Log.Debug("Settings: experimentId {0} has filter index {1}", id, experimentIds[id]);
            }

            /*
             *  Unresearched = 0,
             *  NotMaxed = 1,
             *  LessThanFiftyPercent = 2,
             *  LessThanNinetyPercent = 3
             */
            filterList.Add(new GUIContent("Unresearched"));
            filterList.Add(new GUIContent("Not maxed"));
            filterList.Add(new GUIContent("< 50% collected"));
            filterList.Add(new GUIContent("< 90% collected"));


            openButton   = ResourceUtil.GetEmbeddedTexture("ScienceAlert.Resources.btnOpen.png", false);
            saveButton   = ResourceUtil.GetEmbeddedTexture("ScienceAlert.Resources.btnSave.png", false);
            returnButton = ResourceUtil.GetEmbeddedTexture("ScienceAlert.Resources.btnReturn.png", false);
            deleteButton = ResourceUtil.GetEmbeddedTexture("ScienceAlert.Resources.btnDelete.png", false);
            renameButton = ResourceUtil.GetEmbeddedTexture("ScienceAlert.Resources.btnRename.png", false);

            var tex = ResourceUtil.GetEmbeddedTexture("ScienceAlert.Resources.btnExpand.png", false);

            if (tex == null)
            {
                Log.Error("Failed to retrieve expand button texture from stream");
            }
            else
            {
                Log.Debug("Collapse button texture loaded successfully");
                expandButton = tex;

                collapseButton = UnityEngine.Texture.Instantiate(expandButton) as Texture2D;
                ResourceUtil.FlipTexture(collapseButton, true, true);

                collapseButton.Compress(false);
                expandButton.Compress(false);
            }

            blackPixel.SetPixel(0, 0, Color.black); blackPixel.Apply();
            blackPixel.filterMode = FilterMode.Bilinear;

            whiteLabel = (GUISkin)GUISkin.Instantiate(Settings.Skin);
            whiteLabel.label.onNormal.textColor  = Color.white;
            whiteLabel.toggle.onNormal.textColor = Color.white;
            whiteLabel.label.onActive.textColor  = Color.white;

            submenu = OpenPane.None;
            Title   = "ScienceAlert Options";

            // smaller label for less important text hints
            miniLabelLeft                  = new GUIStyle(Skin.label);
            miniLabelLeft.fontSize         = 10;
            miniLabelLeft.normal.textColor = miniLabelLeft.onNormal.textColor = Color.white;

            miniLabelRight           = new GUIStyle(miniLabelLeft);
            miniLabelRight.alignment = TextAnchor.MiddleRight;

            miniLabelCenter           = new GUIStyle(miniLabelLeft);
            miniLabelCenter.alignment = TextAnchor.MiddleCenter;

            Settings.Instance.OnSave += OnAboutToSave;
            base.OnVisibilityChange  += OnVisibilityChanged;
            GameEvents.onVesselChange.Add(OnVesselChanged);

            LoadFrom(Settings.Instance.additional.GetNode("OptionsWindow") ?? new ConfigNode());

            return(new Rect(windowRect.x, windowRect.y, 324, Screen.height / 5 * 3));
        }
        /// <summary>
        /// Draws modifyable settings for the current active profile, assuming one is
        /// active and valid
        /// </summary>
        private void DrawProfileSettings()
        {
            if (ProfileManager.HasActiveProfile)
            {
                //-----------------------------------------------------
                // Active profile header with buttons
                //-----------------------------------------------------
                #region active profile header

                GUILayout.BeginHorizontal();
                {
                    GUILayout.Box(string.Format("Profile: {0}", ProfileManager.ActiveProfile.DisplayName), GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true));

                    // rename profile button
                    if (AudibleButton(new GUIContent(renameButton), GUILayout.MaxWidth(24)))
                    {
                        SpawnRenamePopup(ProfileManager.ActiveProfile);
                    }

                    // Save profile (only enabled if profile was actually modified)
                    GUI.enabled = ProfileManager.ActiveProfile.modified;
                    if (AudibleButton(new GUIContent(saveButton), GUILayout.MaxWidth(24)))
                    {
                        SaveCurrentProfile();
                    }
                    GUI.enabled = true;

                    // Open profile (always available, warn user if profile modified)
                    if (AudibleButton(new GUIContent(openButton), GUILayout.MaxWidth(24)))
                    {
                        submenu = OpenPane.LoadProfiles;
                    }
                }
                GUILayout.EndHorizontal();

                #endregion

                //-----------------------------------------------------
                // scrollview with experiment options
                //-----------------------------------------------------
                #region experiment scrollview

                scrollPos = GUILayout.BeginScrollView(scrollPos, Settings.Skin.scrollView);
                {
                    GUI.skin = Settings.Skin;
                    GUILayout.Space(4f);


                    //-----------------------------------------------------
                    // min threshold slider ui
                    //-----------------------------------------------------
                    #region min threshold slider
                    GUI.SetNextControlName("ThresholdHeader");
                    GUILayout.Box("Alert Threshold");

                    GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true), GUILayout.MinHeight(14f));
                    {
                        if (ProfileManager.ActiveProfile.ScienceThreshold > 0f)
                        {
                            GUILayout.Label(string.Format("Alert Threshold: {0}", ProfileManager.ActiveProfile.ScienceThreshold.ToString("F2", formatter)));
                        }
                        else
                        {
                            var prev = GUI.color;
                            GUI.color = XKCDColors.Salmon;
                            GUILayout.Label("(disabled)");
                            GUI.color = prev;
                        }

                        GUILayout.FlexibleSpace();


                        if (string.IsNullOrEmpty(thresholdValue))
                        {
                            thresholdValue = ProfileManager.ActiveProfile.scienceThreshold.ToString("F2", formatter);
                        }

                        GUI.SetNextControlName("ThresholdText");
                        string result = GUILayout.TextField(thresholdValue, GUILayout.MinWidth(60f));

                        // let the player use escape to cancel focus. Otherwise I'm likely to get a slew of
                        // bug reports about having locked up their GUI since all actions are locked while
                        // the text field has focus
                        if (Event.current.keyCode == KeyCode.Escape)
                        {
                            GUI.FocusControl("ThresholdHeader");              // kinda hacky but it works
                        }
                        if (GUI.GetNameOfFocusedControl() == "ThresholdText") // only use text field value if it's focused; if we don't
                        // do this, then it'll continuously overwrite the slider value
                        {
                            try
                            {
                                float parsed = float.Parse(result, formatter);
                                ProfileManager.ActiveProfile.ScienceThreshold = parsed;

                                thresholdValue = result;
                            }
                            catch (Exception) // just in case
                            {
                            }

                            if (!InputLockManager.IsLocked(ControlTypes.ACTIONS_ALL))
                            {
                                InputLockManager.SetControlLock(ControlTypes.ACTIONS_ALL, "ScienceAlertThreshold");
                            }
                        }
                        else if (InputLockManager.GetControlLock("ScienceAlertThreshold") != ControlTypes.None)
                        {
                            InputLockManager.RemoveControlLock("ScienceAlertThreshold");
                        }
                    }
                    GUILayout.EndHorizontal();


                    GUILayout.Space(3f); // otherwise the TextField will overlap the slider just slightly

                    // threshold slider
                    float newThreshold = GUILayout.HorizontalSlider(ProfileManager.ActiveProfile.ScienceThreshold, 0f, 100f, GUILayout.ExpandWidth(true), GUILayout.Height(14f));
                    if (newThreshold != ProfileManager.ActiveProfile.scienceThreshold)
                    {
                        ProfileManager.ActiveProfile.ScienceThreshold = newThreshold;
                        thresholdValue = newThreshold.ToString("F2", formatter);
                    }


                    // slider min/max value display. Put under slider because I couldn't get it centered on the sides
                    // properly and it just looked strange
                    GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true), GUILayout.MaxHeight(10f));

                    GUILayout.Label("0", miniLabelLeft);
                    GUILayout.FlexibleSpace();
                    GUILayout.Label("Science Amount", miniLabelCenter);
                    GUILayout.FlexibleSpace();
                    GUILayout.Label("100", miniLabelRight);
                    GUILayout.EndHorizontal();

                    #endregion

                    GUILayout.Space(10f);

                    // individual experiment settings
                    var keys = new List <string>(experimentIds.Keys);

                    foreach (var key in keys)
                    {
                        GUILayout.Space(4f);

                        var settings = ProfileManager.ActiveProfile[key];

                        // "asteroidSample" isn't listed in ScienceDefs (has a simple title of "Sample")
                        //   note: band-aided this in ScienceAlert.Start; leaving this note here in case
                        //         just switching an experiment's title causes issues later
                        var title = ResearchAndDevelopment.GetExperiment(key).experimentTitle;
#if DEBUG
                        GUILayout.Box(title + string.Format(" ({0})", ResearchAndDevelopment.GetExperiment(key).id), GUILayout.ExpandWidth(true));
#else
                        GUILayout.Box(title, GUILayout.ExpandWidth(true));
#endif

                        settings.Enabled = AudibleToggle(settings.Enabled, "Enabled");
                        settings.AnimationOnDiscovery = AudibleToggle(settings.AnimationOnDiscovery, "Animation on discovery");
                        settings.SoundOnDiscovery     = AudibleToggle(settings.SoundOnDiscovery, "Sound on discovery");
                        settings.StopWarpOnDiscovery  = AudibleToggle(settings.StopWarpOnDiscovery, "Stop warp on discovery");

                        // only add the Assume Onboard option if the experiment isn't
                        // one of the default types
                        //if (!settings.IsDefault)
                        //settings.AssumeOnboard = AudibleToggle(settings.AssumeOnboard, "Assume onboard");

                        GUILayout.Label(new GUIContent("Filter Method"), GUILayout.ExpandWidth(true), GUILayout.MinHeight(24f));

                        int oldSel = experimentIds[key];
                        experimentIds[key] = AudibleSelectionGrid(oldSel, ref settings);

                        if (oldSel != experimentIds[key])
                        {
                            Log.Debug("Changed filter mode for {0} to {1}", key, settings.Filter);
                        }
                    }
                }
                GUILayout.EndScrollView();

                #endregion
            }
            else
            { // no active profile
                GUI.color = Color.red;
                GUILayout.Label("No profile active");
            }
        }