<commit_before>﻿namespace ControlzEx.Theming
{
#nullable enable
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows;
    using System.Windows.Markup;
    using System.Windows.Media;

    public class RuntimeThemeGenerator
    {
        public static RuntimeThemeGenerator Current { get; set; }

        static RuntimeThemeGenerator()
        {
            Current = new RuntimeThemeGenerator();
        }

        public RuntimeThemeColorOptions ColorOptions { get; } = new RuntimeThemeColorOptions();

        public Theme? GenerateRuntimeThemeFromWindowsSettings(string baseColor, params LibraryThemeProvider[] libraryThemeProviders)
        {
            return GenerateRuntimeThemeFromWindowsSettings(baseColor, libraryThemeProviders.ToList());
        }

        public virtual Theme? GenerateRuntimeThemeFromWindowsSettings(string baseColor, IEnumerable<LibraryThemeProvider> libraryThemeProviders)
        {
            var windowsAccentColor = WindowsThemeHelper.GetWindowsAccentColor();

            if (windowsAccentColor is null)
            {
                return null;
            }

            var accentColor = windowsAccentColor.Value;

            return GenerateRuntimeTheme(baseColor, accentColor, libraryThemeProviders);
        }

        public virtual Theme? GenerateRuntimeTheme(string baseColor, Color accentColor)
        {
            return GenerateRuntimeTheme(baseColor, accentColor, ThemeManager.LibraryThemeProviders.ToList());
        }

        public Theme? GenerateRuntimeTheme(string baseColor, Color accentColor, params LibraryThemeProvider[] libraryThemeProviders)
        {
            return GenerateRuntimeTheme(baseColor, accentColor, libraryThemeProviders.ToList());
        }

        public virtual Theme? GenerateRuntimeTheme(string baseColor, Color accentColor, IEnumerable<LibraryThemeProvider> libraryThemeProviders)
        {
            Theme? theme = null;

            foreach (var libraryThemeProvider in libraryThemeProviders)
            {
                var libraryTheme = GenerateRuntimeLibraryTheme(baseColor, accentColor, libraryThemeProvider);

                if (libraryTheme == null)
                {
                    continue;
                }

                if (theme == null)
                {
                    theme = new Theme(libraryTheme);
                }
                else
                {
                    theme.AddLibraryTheme(libraryTheme);
                }
            }

            return theme;
        }

        public virtual LibraryTheme? GenerateRuntimeLibraryTheme(string baseColor, Color accentColor, LibraryThemeProvider libraryThemeProvider)
        {
            var themeGeneratorParametersContent = libraryThemeProvider.GetThemeGeneratorParametersContent();

            if (string.IsNullOrEmpty(themeGeneratorParametersContent))
            {
                return null;
            }

            var generatorParameters = ThemeGenerator.GetParametersFromString(themeGeneratorParametersContent);

            var baseColorScheme = generatorParameters.BaseColorSchemes.First(x => x.Name == baseColor);

            var colorScheme = new ThemeGenerator.ThemeGeneratorColorScheme
            {
                Name = accentColor.ToString()
            };
            var values = colorScheme.Values;

            var runtimeThemeColorValues = this.GetColors(accentColor, this.ColorOptions);

            values.Add("ThemeGenerator.Colors.PrimaryAccentColor", runtimeThemeColorValues.PrimaryAccentColor.ToString());
            values.Add("ThemeGenerator.Colors.AccentBaseColor", runtimeThemeColorValues.AccentBaseColor.ToString());
            values.Add("ThemeGenerator.Colors.AccentColor80", runtimeThemeColorValues.AccentColor80.ToString());
            values.Add("ThemeGenerator.Colors.AccentColor60", runtimeThemeColorValues.AccentColor60.ToString());
            values.Add("ThemeGenerator.Colors.AccentColor40", runtimeThemeColorValues.AccentColor40.ToString());
            values.Add("ThemeGenerator.Colors.AccentColor20", runtimeThemeColorValues.AccentColor20.ToString());

            values.Add("ThemeGenerator.Colors.HighlightColor", runtimeThemeColorValues.HighlightColor.ToString());
            values.Add("ThemeGenerator.Colors.IdealForegroundColor", runtimeThemeColorValues.IdealForegroundColor.ToString());

            libraryThemeProvider.FillColorSchemeValues(values, runtimeThemeColorValues);

            var themeFileContent = ThemeGenerator.GenerateColorSchemeFileContent(generatorParameters, baseColorScheme, colorScheme, libraryThemeProvider.GetThemeTemplateContent(), $"{baseColor}.Runtime_{accentColor}", $"Runtime {accentColor} ({baseColor})");
            var resourceDictionary = (ResourceDictionary)XamlReader.Parse(themeFileContent);

            return new LibraryTheme(resourceDictionary, libraryThemeProvider, true);
        }

        public virtual RuntimeThemeColorValues GetColors(Color accentColor, RuntimeThemeColorOptions options)
        {
            if (options.UseHSL)
            {
                return new RuntimeThemeColorValues
                {
                    Options = options,

                    AccentColor = accentColor,
                    AccentBaseColor = accentColor,
                    PrimaryAccentColor = accentColor,

                    AccentColor80 = HSLColor.GetTintedColor(accentColor, -0.2),
                    AccentColor60 = HSLColor.GetTintedColor(accentColor, -0.4),
                    AccentColor40 = HSLColor.GetTintedColor(accentColor, -0.6),
                    AccentColor20 = HSLColor.GetTintedColor(accentColor, -0.8),

                    HighlightColor = GetHighlightColor(accentColor),

                    IdealForegroundColor = GetIdealTextColor(accentColor),
                };
            }
            else
            {
                return new RuntimeThemeColorValues
                {
                    Options = options,

                    AccentColor = accentColor,
                    AccentBaseColor = accentColor,
                    PrimaryAccentColor = accentColor,

                    AccentColor80 = Color.FromArgb(204, accentColor.R, accentColor.G, accentColor.B),
                    AccentColor60 = Color.FromArgb(153, accentColor.R, accentColor.G, accentColor.B),
                    AccentColor40 = Color.FromArgb(102, accentColor.R, accentColor.G, accentColor.B),
                    AccentColor20 = Color.FromArgb(51, accentColor.R, accentColor.G, accentColor.B),

                    HighlightColor = GetHighlightColor(accentColor),

                    IdealForegroundColor = GetIdealTextColor(accentColor),
                };
            }
        }<commit_msg>Improving HSL colors<commit_after>namespace ControlzEx.Theming
{
#nullable enable
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows;
    using System.Windows.Markup;
    using System.Windows.Media;

    public class RuntimeThemeGenerator
    {
        public static RuntimeThemeGenerator Current { get; set; }

        static RuntimeThemeGenerator()
        {
            Current = new RuntimeThemeGenerator();
        }

        public RuntimeThemeColorOptions ColorOptions { get; } = new RuntimeThemeColorOptions();

        public Theme? GenerateRuntimeThemeFromWindowsSettings(string baseColor, params LibraryThemeProvider[] libraryThemeProviders)
        {
            return GenerateRuntimeThemeFromWindowsSettings(baseColor, libraryThemeProviders.ToList());
        }

        public virtual Theme? GenerateRuntimeThemeFromWindowsSettings(string baseColor, IEnumerable<LibraryThemeProvider> libraryThemeProviders)
        {
            var windowsAccentColor = WindowsThemeHelper.GetWindowsAccentColor();

            if (windowsAccentColor is null)
            {
                return null;
            }

            var accentColor = windowsAccentColor.Value;

            return GenerateRuntimeTheme(baseColor, accentColor, libraryThemeProviders);
        }

        public virtual Theme? GenerateRuntimeTheme(string baseColor, Color accentColor)
        {
            return GenerateRuntimeTheme(baseColor, accentColor, ThemeManager.LibraryThemeProviders.ToList());
        }

        public Theme? GenerateRuntimeTheme(string baseColor, Color accentColor, params LibraryThemeProvider[] libraryThemeProviders)
        {
            return GenerateRuntimeTheme(baseColor, accentColor, libraryThemeProviders.ToList());
        }

        public virtual Theme? GenerateRuntimeTheme(string baseColor, Color accentColor, IEnumerable<LibraryThemeProvider> libraryThemeProviders)
        {
            Theme? theme = null;

            foreach (var libraryThemeProvider in libraryThemeProviders)
            {
                var libraryTheme = GenerateRuntimeLibraryTheme(baseColor, accentColor, libraryThemeProvider);

                if (libraryTheme == null)
                {
                    continue;
                }

                if (theme == null)
                {
                    theme = new Theme(libraryTheme);
                }
                else
                {
                    theme.AddLibraryTheme(libraryTheme);
                }
            }

            return theme;
        }

        public virtual LibraryTheme? GenerateRuntimeLibraryTheme(string baseColor, Color accentColor, LibraryThemeProvider libraryThemeProvider)
        {
            var themeGeneratorParametersContent = libraryThemeProvider.GetThemeGeneratorParametersContent();

            if (string.IsNullOrEmpty(themeGeneratorParametersContent))
            {
                return null;
            }

            var generatorParameters = ThemeGenerator.GetParametersFromString(themeGeneratorParametersContent);

            var baseColorScheme = generatorParameters.BaseColorSchemes.First(x => x.Name == baseColor);

            var colorScheme = new ThemeGenerator.ThemeGeneratorColorScheme
            {
                Name = accentColor.ToString()
            };
            var values = colorScheme.Values;

            var runtimeThemeColorValues = this.GetColors(accentColor, this.ColorOptions);

            values.Add("ThemeGenerator.Colors.PrimaryAccentColor", runtimeThemeColorValues.PrimaryAccentColor.ToString());
            values.Add("ThemeGenerator.Colors.AccentBaseColor", runtimeThemeColorValues.AccentBaseColor.ToString());
            values.Add("ThemeGenerator.Colors.AccentColor80", runtimeThemeColorValues.AccentColor80.ToString());
            values.Add("ThemeGenerator.Colors.AccentColor60", runtimeThemeColorValues.AccentColor60.ToString());
            values.Add("ThemeGenerator.Colors.AccentColor40", runtimeThemeColorValues.AccentColor40.ToString());
            values.Add("ThemeGenerator.Colors.AccentColor20", runtimeThemeColorValues.AccentColor20.ToString());

            values.Add("ThemeGenerator.Colors.HighlightColor", runtimeThemeColorValues.HighlightColor.ToString());
            values.Add("ThemeGenerator.Colors.IdealForegroundColor", runtimeThemeColorValues.IdealForegroundColor.ToString());

            libraryThemeProvider.FillColorSchemeValues(values, runtimeThemeColorValues);

            var themeFileContent = ThemeGenerator.GenerateColorSchemeFileContent(generatorParameters, baseColorScheme, colorScheme, libraryThemeProvider.GetThemeTemplateContent(), $"{baseColor}.Runtime_{accentColor}", $"Runtime {accentColor} ({baseColor})");
            var resourceDictionary = (ResourceDictionary)XamlReader.Parse(themeFileContent);

            return new LibraryTheme(resourceDictionary, libraryThemeProvider, true);
        }

        public virtual RuntimeThemeColorValues GetColors(Color accentColor, RuntimeThemeColorOptions options)
        {
            if (options.UseHSL)
            {
                var accentColorWithoutTransparency = Color.FromRgb(accentColor.R, accentColor.G, accentColor.B);

                return new RuntimeThemeColorValues
                {
                    Options = options,

                    AccentColor = accentColor,
                    AccentBaseColor = accentColor,
                    PrimaryAccentColor = accentColor,

                    AccentColor80 = HSLColor.GetTintedColor(accentColorWithoutTransparency, 0.2),
                    AccentColor60 = HSLColor.GetTintedColor(accentColorWithoutTransparency, 0.4),
                    AccentColor40 = HSLColor.GetTintedColor(accentColorWithoutTransparency, 0.6),
                    AccentColor20 = HSLColor.GetTintedColor(accentColorWithoutTransparency, 0.8),

                    HighlightColor = GetHighlightColor(accentColorWithoutTransparency),

                    IdealForegroundColor = GetIdealTextColor(accentColorWithoutTransparency),
                };
            }
            else
            {
                return new RuntimeThemeColorValues
                {
                    Options = options,

                    AccentColor = accentColor,
                    AccentBaseColor = accentColor,
                    PrimaryAccentColor = accentColor,

                    AccentColor80 = Color.FromArgb(204, accentColor.R, accentColor.G, accentColor.B),
                    AccentColor60 = Color.FromArgb(153, accentColor.R, accentColor.G, accentColor.B),
                    AccentColor40 = Color.FromArgb(102, accentColor.R, accentColor.G, accentColor.B),
                    AccentColor20 = Color.FromArgb(51, accentColor.R, accentColor.G, accentColor.B),

                    HighlightColor = GetHighlightColor(accentColor),

                    IdealForegroundColor = GetIdealTextColor(accentColor),
                };
            }
        }
{'fraction_non_alphanumeric': 0.07190635451505016, 'fraction_numerical': 0.007416024429256944, 'mean_word_length': 2.374631992149166, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, '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': '4661906', 'n_tokens_mistral': 3276, 'n_tokens_neox': 3071, 'n_words': 555}