<commit_before>﻿using Aurora.EffectsEngine;
using Aurora.Profiles;
using CSScriptLibrary;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Linq;
using Aurora.Settings.Layers;
using System.Reflection;
using System.Windows.Media.Imaging;
using System.Runtime.CompilerServices;
using Newtonsoft.Json.Serialization;
using System.Collections.ObjectModel;
using Aurora.Settings;

namespace Aurora.Profiles
{
    public class LightEventConfig : NotifyPropertyChangedEx
    {
        //TODO: Add NotifyPropertyChanged to properties
        public string[] ProcessNames { get; set; }

        public string Name { get; set; }

        public string ID { get; set; }

        public string AppID { get; set; }

        public Type SettingsType { get; set; } = typeof(ApplicationSettings);

        public Type ProfileType { get; set; } = typeof(ApplicationProfile);

        public Type OverviewControlType { get; set; }

        public Type GameStateType { get; set; }

        public LightEvent Event { get; set; }

        public int? UpdateInterval { get; set; } = null;

        public string IconURI { get; set; }

        public HashSet<string> ExtraAvailableLayers { get; set; } = new HashSet<string>();

        protected LightEventType? type = LightEventType.Normal;
        public LightEventType? Type
        {
            get { return type; }
            set
            {
                object old = type;
                object newVal = value;
                type = value;
                InvokePropertyChanged(old, newVal);
            }
        }
    }

    public class Application : ObjectSettings<ApplicationSettings>, IInit, ILightEvent
    {
        #region Public Properties
        public bool Initialized { get; protected set; } = false;
        public ApplicationProfile Profile { get; set; }
        public ObservableCollection<ApplicationProfile> Profiles { get; set; }
        public Dictionary<string, Tuple<Type, Type>> ParameterLookup { get; set; } //Key = variable path, Value = {Return type, Parameter type}
        public bool HasLayers { get; set; }
        public event EventHandler ProfileChanged;
        public bool ScriptsLoaded { get; protected set; }
        public LightEventConfig Config { get; protected set; }
        public string ID { get { return Config.ID; } }
        public Type GameStateType { get { return Config.GameStateType; } }
        public bool IsEnabled { get { return Settings.IsEnabled; } }
        public event PropertyChangedExEventHandler PropertyChanged;
        protected LightEventType type;
        public LightEventType Type
        {
            get { return type; }
            protected set
            {
                object old = type;
                object newVal = value;
                type = value;
                InvokePropertyChanged(old, newVal);
            }
        }
        public ImageSource Icon
        {
            get {
                return GetIcon();
            }
        }
        #endregion

        #region Internal Properties
        internal ImageSource icon { get; set; }
        internal UserControl Control { get; set; }
        internal Dictionary<string, IEffectScript> EffectScripts { get; set; }
        #endregion

        #region Private Fields/Properties
        #endregion

        public Application(LightEventConfig config)
        {
            Config = config;
            SettingsSavePath = Path.Combine(GetProfileFolderPath(), "settings.json");
            config.Event.Application = this;
            Profiles = new ObservableCollection<ApplicationProfile>();
            EffectScripts = new Dictionary<string, IEffectScript>();
            ParameterLookup = Utils.GameStateUtils.ReflectGameStateParameters(config.GameStateType);
        }

        public bool Initialize()
        {
            if (Initialized)
                return Initialized;

            LoadSettings(Config.SettingsType);
            LoadProfiles();
            Initialized = true;
            return Initialized;
        }

        protected void InvokePropertyChanged(object oldValue, object newValue, [CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedExEventArgs(propertyName, oldValue, newValue));
        }

        public virtual UserControl GetUserControl()
        {
            return Control ?? (Control = (UserControl)Activator.CreateInstance(this.Config.OverviewControlType, this));
        }

        public virtual ImageSource GetIcon()
        {
            return icon ?? (icon = new BitmapImage(new Uri(Config.IconURI, UriKind.Relative)));
        }

        public void SwitchToProfile(ApplicationProfile newProfileSettings)
        {
            if (newProfileSettings != null)
            {
                if (Profile != null)
                    Profile.PropertyChanged -= Profile_PropertyChanged;
                Profile = newProfileSettings;
                this.Settings.SelectedProfile = Path.GetFileNameWithoutExtension(Profile.ProfileFilepath);
                Profile.PropertyChanged += Profile_PropertyChanged;

                ProfileChanged?.Invoke(this, new EventArgs());
            }
        }

        protected virtual ApplicationProfile CreateNewProfile(string profileName)
        {
            ApplicationProfile profile = (ApplicationProfile)Activator.CreateInstance(Config.ProfileType);
            profile.ProfileName = profileName;
            profile.ProfileFilepath = Path.Combine(GetProfileFolderPath(), GetValidFilename(profile.ProfileName) + ".json");
            return profile;
        }

        protected void CreateDefaultProfile()
        {
            ApplicationProfile _newProfile = CreateNewProfile("default");

            Profiles.Add(_newProfile);

            SaveProfiles();

            SwitchToProfile(_newProfile);
        }

        public void SaveDefaultProfile()
        {
            ApplicationProfile _newProfile = CreateNewProfile($"Profile {Profiles.Count + 1}");

            Profiles.Add(_newProfile);

            SaveProfiles();

            SwitchToProfile(_newProfile);
        }

        public void DeleteProfile(ApplicationProfile profile)
        {
            if (profile != null && !String.IsNullOrWhiteSpace(profile.ProfileFilepath))
            {
                if (Profile.Equals(profile))
                    SwitchToProfile(Profiles[Math.Max(Profiles.IndexOf(profile) -1, 0)]);

                if (Profiles.Contains(profile))
                    Profiles.Remove(profile);

                if (File.Exists(profile.ProfileFilepath))
                {
                    try
                    {
                        File.Delete(profile.ProfileFilepath);
                    }
                    catch (Exception exc)
                    {
                        Global.logger.LogLine($"Could not delete profile with path \"{profile.ProfileFilepath}\"", Logging_Level.Error);
                        Global.logger.LogLine($"Exception: {exc}", Logging_Level.Error, false);
                    }
                }

                SaveProfiles();
            }
        }

        protected string GetValidFilename(string filename)
        {
            foreach (char c in Path.GetInvalidFileNameChars())
                filename = filename.Replace(c, '_');

            return filename;
        }<commit_msg>Fixed the current profile not changing when the first profile is deleted<commit_after>﻿using Aurora.EffectsEngine;
using Aurora.Profiles;
using CSScriptLibrary;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Linq;
using Aurora.Settings.Layers;
using System.Reflection;
using System.Windows.Media.Imaging;
using System.Runtime.CompilerServices;
using Newtonsoft.Json.Serialization;
using System.Collections.ObjectModel;
using Aurora.Settings;

namespace Aurora.Profiles
{
    public class LightEventConfig : NotifyPropertyChangedEx
    {
        //TODO: Add NotifyPropertyChanged to properties
        public string[] ProcessNames { get; set; }

        public string Name { get; set; }

        public string ID { get; set; }

        public string AppID { get; set; }

        public Type SettingsType { get; set; } = typeof(ApplicationSettings);

        public Type ProfileType { get; set; } = typeof(ApplicationProfile);

        public Type OverviewControlType { get; set; }

        public Type GameStateType { get; set; }

        public LightEvent Event { get; set; }

        public int? UpdateInterval { get; set; } = null;

        public string IconURI { get; set; }

        public HashSet<string> ExtraAvailableLayers { get; set; } = new HashSet<string>();

        protected LightEventType? type = LightEventType.Normal;
        public LightEventType? Type
        {
            get { return type; }
            set
            {
                object old = type;
                object newVal = value;
                type = value;
                InvokePropertyChanged(old, newVal);
            }
        }
    }

    public class Application : ObjectSettings<ApplicationSettings>, IInit, ILightEvent
    {
        #region Public Properties
        public bool Initialized { get; protected set; } = false;
        public ApplicationProfile Profile { get; set; }
        public ObservableCollection<ApplicationProfile> Profiles { get; set; }
        public Dictionary<string, Tuple<Type, Type>> ParameterLookup { get; set; } //Key = variable path, Value = {Return type, Parameter type}
        public bool HasLayers { get; set; }
        public event EventHandler ProfileChanged;
        public bool ScriptsLoaded { get; protected set; }
        public LightEventConfig Config { get; protected set; }
        public string ID { get { return Config.ID; } }
        public Type GameStateType { get { return Config.GameStateType; } }
        public bool IsEnabled { get { return Settings.IsEnabled; } }
        public event PropertyChangedExEventHandler PropertyChanged;
        protected LightEventType type;
        public LightEventType Type
        {
            get { return type; }
            protected set
            {
                object old = type;
                object newVal = value;
                type = value;
                InvokePropertyChanged(old, newVal);
            }
        }
        public ImageSource Icon
        {
            get {
                return GetIcon();
            }
        }
        #endregion

        #region Internal Properties
        internal ImageSource icon { get; set; }
        internal UserControl Control { get; set; }
        internal Dictionary<string, IEffectScript> EffectScripts { get; set; }
        #endregion

        #region Private Fields/Properties
        #endregion

        public Application(LightEventConfig config)
        {
            Config = config;
            SettingsSavePath = Path.Combine(GetProfileFolderPath(), "settings.json");
            config.Event.Application = this;
            Profiles = new ObservableCollection<ApplicationProfile>();
            EffectScripts = new Dictionary<string, IEffectScript>();
            ParameterLookup = Utils.GameStateUtils.ReflectGameStateParameters(config.GameStateType);
        }

        public bool Initialize()
        {
            if (Initialized)
                return Initialized;

            LoadSettings(Config.SettingsType);
            LoadProfiles();
            Initialized = true;
            return Initialized;
        }

        protected void InvokePropertyChanged(object oldValue, object newValue, [CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedExEventArgs(propertyName, oldValue, newValue));
        }

        public virtual UserControl GetUserControl()
        {
            return Control ?? (Control = (UserControl)Activator.CreateInstance(this.Config.OverviewControlType, this));
        }

        public virtual ImageSource GetIcon()
        {
            return icon ?? (icon = new BitmapImage(new Uri(Config.IconURI, UriKind.Relative)));
        }

        public void SwitchToProfile(ApplicationProfile newProfileSettings)
        {
            if (newProfileSettings != null)
            {
                if (Profile != null)
                    Profile.PropertyChanged -= Profile_PropertyChanged;
                Profile = newProfileSettings;
                this.Settings.SelectedProfile = Path.GetFileNameWithoutExtension(Profile.ProfileFilepath);
                Profile.PropertyChanged += Profile_PropertyChanged;

                ProfileChanged?.Invoke(this, new EventArgs());
            }
        }

        protected virtual ApplicationProfile CreateNewProfile(string profileName)
        {
            ApplicationProfile profile = (ApplicationProfile)Activator.CreateInstance(Config.ProfileType);
            profile.ProfileName = profileName;
            profile.ProfileFilepath = Path.Combine(GetProfileFolderPath(), GetValidFilename(profile.ProfileName) + ".json");
            return profile;
        }

        protected void CreateDefaultProfile()
        {
            ApplicationProfile _newProfile = CreateNewProfile("default");

            Profiles.Add(_newProfile);

            SaveProfiles();

            SwitchToProfile(_newProfile);
        }

        public void SaveDefaultProfile()
        {
            ApplicationProfile _newProfile = CreateNewProfile($"Profile {Profiles.Count + 1}");

            Profiles.Add(_newProfile);

            SaveProfiles();

            SwitchToProfile(_newProfile);
        }

        public void DeleteProfile(ApplicationProfile profile)
        {
            if (profile != null && !String.IsNullOrWhiteSpace(profile.ProfileFilepath))
            {
                int profileIndex = Profiles.IndexOf(profile);

                if (Profiles.Contains(profile))
                    Profiles.Remove(profile);

                if (Profile.Equals(profile))
                    SwitchToProfile(Profiles[Math.Max(profileIndex, 0)]);

                if (File.Exists(profile.ProfileFilepath))
                {
                    try
                    {
                        File.Delete(profile.ProfileFilepath);
                    }
                    catch (Exception exc)
                    {
                        Global.logger.LogLine($"Could not delete profile with path \"{profile.ProfileFilepath}\"", Logging_Level.Error);
                        Global.logger.LogLine($"Exception: {exc}", Logging_Level.Error, false);
                    }
                }

                SaveProfiles();
            }
        }

        protected string GetValidFilename(string filename)
        {
            foreach (char c in Path.GetInvalidFileNameChars())
                filename = filename.Replace(c, '_');

            return filename;
        }
{'fraction_non_alphanumeric': 0.08074739205070645, 'fraction_numerical': 0.00033012016373960124, 'mean_word_length': 2.0083416087388284, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3222013', 'n_tokens_mistral': 3606, 'n_tokens_neox': 3444, 'n_words': 901}