<commit_before>// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using JetBrains.Annotations;

namespace MahApps.Metro.Controls
{
    [DefaultEvent("SelectedColorChanged")]
    public class ColorPickerBase : Control
    {
        protected bool ColorIsUpdating;
        protected bool UpdateHsvValues = true;

        /// <summary>Identifies the <see cref="SelectedColor"/> dependency property.</summary>
        public static readonly DependencyProperty SelectedColorProperty
            = DependencyProperty.Register(nameof(SelectedColor),
                                          typeof(Color?),
                                          typeof(ColorPickerBase),
                                          new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedColorPropertyChanged, CoerceSelectedColorProperty));

        private static void OnSelectedColorPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            if (dependencyObject is ColorPickerBase colorPicker && e.OldValue != e.NewValue && !colorPicker.ColorIsUpdating)
            {
                colorPicker.ColorIsUpdating = true;
                try
                {
                    colorPicker.OnSelectedColorChanged(e.OldValue as Color?, e.NewValue as Color? ?? colorPicker.DefaultColor);
                }
                finally
                {
                    colorPicker.ColorIsUpdating = false;
                }
            }
        }

        [MustUseReturnValue]
        private static object? CoerceSelectedColorProperty(DependencyObject dependencyObject, object? basevalue)
        {
            if (dependencyObject is ColorPickerBase colorPicker)
            {
                basevalue ??= colorPicker.DefaultColor;
            }

            return basevalue;
        }

        /// <summary>
        /// Gets or sets the selected <see cref="Color"/>.
        /// </summary>
        public Color? SelectedColor
        {
            get => (Color?)this.GetValue(SelectedColorProperty);
            set => this.SetValue(SelectedColorProperty, value);
        }

        /// <summary>Identifies the <see cref="DefaultColor"/> dependency property.</summary>
        public static readonly DependencyProperty DefaultColorProperty
            = DependencyProperty.Register(nameof(DefaultColor),
                                          typeof(Color?),
                                          typeof(ColorPickerBase),
                                          new FrameworkPropertyMetadata(null, OnDefaultColorPropertyChanged));

        private static void OnDefaultColorPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            if (dependencyObject is ColorPickerBase colorPicker && e.OldValue != e.NewValue)
            {
                colorPicker.SetCurrentValue(SelectedColorProperty, e.NewValue ?? colorPicker.SelectedColor);
            }
        }

        /// <summary>
        /// Gets or sets a default selected <see cref="Color"/>
        /// </summary>
        public Color? DefaultColor
        {
            get => (Color?)this.GetValue(DefaultColorProperty);
            set => this.SetValue(DefaultColorProperty, value);
        }

        private static readonly DependencyPropertyKey SelectedHSVColorPropertyKey
            = DependencyProperty.RegisterReadOnly(nameof(SelectedHSVColor),
                                                  typeof(HSVColor),
                                                  typeof(ColorPickerBase),
                                                  new PropertyMetadata(new HSVColor(Colors.Black)));

        /// <summary>Identifies the <see cref="SelectedHSVColor"/> dependency property.</summary>
        public static readonly DependencyProperty SelectedHSVColorProperty = SelectedHSVColorPropertyKey.DependencyProperty;

        /// <summary>
        /// Gets the <see cref="SelectedColor"/> as <see cref="HSVColor"/>. This property is read only.
        /// </summary>
        public HSVColor SelectedHSVColor => (HSVColor)this.GetValue(SelectedHSVColorProperty);

        /// <summary>Identifies the <see cref="ColorName"/> dependency property.</summary>
        public static readonly DependencyProperty ColorNameProperty
            = DependencyProperty.Register(nameof(ColorName),
                                          typeof(string),
                                          typeof(ColorPickerBase),
                                          new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnColorNamePropertyChanged));

        private static void OnColorNamePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            if (dependencyObject is ColorPickerBase colorPicker)
            {
                if (!colorPicker.ColorIsUpdating)
                {
                    if (string.IsNullOrEmpty(e.NewValue?.ToString()))
                    {
                        colorPicker.SetCurrentValue(SelectedColorProperty, null);
                    }
                    else if (ColorHelper.ColorFromString(e.NewValue?.ToString(), colorPicker.ColorNamesDictionary) is { } color)
                    {
                        colorPicker.SetCurrentValue(SelectedColorProperty, color);
                    }
                    else
                    {
                        throw new InvalidCastException("Cannot convert the given input to a valid color");
                    }
                }
            }
        }

        /// <summary>
        /// Gets or sets the name of the <see cref="SelectedColor"/>.
        /// </summary>
        public string? ColorName
        {
            get => (string?)this.GetValue(ColorNameProperty);
            set => this.SetValue(ColorNameProperty, value);<commit_msg>Fixing color name not being updated if color stayed the same<commit_after>﻿// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using JetBrains.Annotations;

namespace MahApps.Metro.Controls
{
    [DefaultEvent("SelectedColorChanged")]
    public class ColorPickerBase : Control
    {
        protected bool ColorIsUpdating;
        protected bool UpdateHsvValues = true;

        /// <summary>Identifies the <see cref="SelectedColor"/> dependency property.</summary>
        public static readonly DependencyProperty SelectedColorProperty
            = DependencyProperty.Register(nameof(SelectedColor),
                                          typeof(Color?),
                                          typeof(ColorPickerBase),
                                          new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedColorPropertyChanged, CoerceSelectedColorProperty));

        private static void OnSelectedColorPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            if (dependencyObject is ColorPickerBase colorPicker && e.OldValue != e.NewValue && !colorPicker.ColorIsUpdating)
            {
                colorPicker.ColorIsUpdating = true;
                try
                {
                    colorPicker.OnSelectedColorChanged(e.OldValue as Color?, e.NewValue as Color? ?? colorPicker.DefaultColor);
                }
                finally
                {
                    colorPicker.ColorIsUpdating = false;
                }
            }
        }

        [MustUseReturnValue]
        private static object? CoerceSelectedColorProperty(DependencyObject dependencyObject, object? basevalue)
        {
            if (dependencyObject is ColorPickerBase colorPicker)
            {
                basevalue ??= colorPicker.DefaultColor;
            }

            return basevalue;
        }

        /// <summary>
        /// Gets or sets the selected <see cref="Color"/>.
        /// </summary>
        public Color? SelectedColor
        {
            get => (Color?)this.GetValue(SelectedColorProperty);
            set => this.SetValue(SelectedColorProperty, value);
        }

        /// <summary>Identifies the <see cref="DefaultColor"/> dependency property.</summary>
        public static readonly DependencyProperty DefaultColorProperty
            = DependencyProperty.Register(nameof(DefaultColor),
                                          typeof(Color?),
                                          typeof(ColorPickerBase),
                                          new FrameworkPropertyMetadata(null, OnDefaultColorPropertyChanged));

        private static void OnDefaultColorPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            if (dependencyObject is ColorPickerBase colorPicker && e.OldValue != e.NewValue)
            {
                colorPicker.SetCurrentValue(SelectedColorProperty, e.NewValue ?? colorPicker.SelectedColor);
            }
        }

        /// <summary>
        /// Gets or sets a default selected <see cref="Color"/>
        /// </summary>
        public Color? DefaultColor
        {
            get => (Color?)this.GetValue(DefaultColorProperty);
            set => this.SetValue(DefaultColorProperty, value);
        }

        private static readonly DependencyPropertyKey SelectedHSVColorPropertyKey
            = DependencyProperty.RegisterReadOnly(nameof(SelectedHSVColor),
                                                  typeof(HSVColor),
                                                  typeof(ColorPickerBase),
                                                  new PropertyMetadata(new HSVColor(Colors.Black)));

        /// <summary>Identifies the <see cref="SelectedHSVColor"/> dependency property.</summary>
        public static readonly DependencyProperty SelectedHSVColorProperty = SelectedHSVColorPropertyKey.DependencyProperty;

        /// <summary>
        /// Gets the <see cref="SelectedColor"/> as <see cref="HSVColor"/>. This property is read only.
        /// </summary>
        public HSVColor SelectedHSVColor => (HSVColor)this.GetValue(SelectedHSVColorProperty);

        /// <summary>Identifies the <see cref="ColorName"/> dependency property.</summary>
        public static readonly DependencyProperty ColorNameProperty
            = DependencyProperty.Register(nameof(ColorName),
                                          typeof(string),
                                          typeof(ColorPickerBase),
                                          new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnColorNamePropertyChanged));

        private static void OnColorNamePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            if (dependencyObject is ColorPickerBase colorPicker)
            {
                if (!colorPicker.ColorIsUpdating)
                {
                    if (string.IsNullOrEmpty(e.NewValue?.ToString()))
                    {
                        colorPicker.SetCurrentValue(SelectedColorProperty, null);
                    }
                    else if (ColorHelper.ColorFromString(e.NewValue?.ToString(), colorPicker.ColorNamesDictionary) is { } color)
                    {
                        if (colorPicker.SelectedColor != color)
                        {
                            colorPicker.SetCurrentValue(SelectedColorProperty, color);
                        }
                        else // if the color stayed the same we still have to update the displayed name
                        {
                            colorPicker.ColorIsUpdating = true;
                            try
                            {
                                colorPicker.SetCurrentValue(ColorNameProperty, ColorHelper.GetColorName(color, colorPicker.ColorNamesDictionary));
                            }
                            finally
                            {
                                colorPicker.ColorIsUpdating = false;
                            }
                        }
                    }
                    else
                    {
                        throw new InvalidCastException("Cannot convert the given input to a valid color");
                    }
                }
            }
        }

        /// <summary>
        /// Gets or sets the name of the <see cref="SelectedColor"/>.
        /// </summary>
        public string? ColorName
        {
            get => (string?)this.GetValue(ColorNameProperty);
            set => this.SetValue(ColorNameProperty, value);
{'fraction_non_alphanumeric': 0.07509047044632086, 'fraction_numerical': 0.0, 'mean_word_length': 1.726058364159474, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 48, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7056642', 'n_tokens_mistral': 2831, 'n_tokens_neox': 2686, 'n_words': 658}