using System.Collections.Frozen;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
namespace Terminal.Gui.Drawing;
///
/// Color name resolver prioritizing Standard (W3C+) colors with fallback to ANSI 4-bit (16) colors.
///
public class MultiStandardColorNameResolver : IColorNameResolver
{
private static readonly AnsiColorNameResolver _ansi = new ();
private static readonly StandardColorsNameResolver _standard = new ();
private static readonly ImmutableArray _combinedColorNames;
private static readonly FrozenDictionary _nameToColorMap;
private static readonly FrozenDictionary _colorToNameMap;
static MultiStandardColorNameResolver ()
{
Dictionary nameToColor = new (StringComparer.OrdinalIgnoreCase);
Dictionary colorToName = new ();
foreach (string name in _standard.GetColorNames ())
{
if (_standard.TryParseColor (name, out Color color))
{
if (nameToColor.TryAdd (name, color))
{
_ = colorToName.TryAdd (color.Argb, name);
}
}
}
foreach (string name in _ansi.GetColorNames ())
{
if (_ansi.TryParseColor (name, out Color color))
{
nameToColor.TryAdd (name, color);
colorToName.TryAdd (color.Argb, name);
}
}
_nameToColorMap = nameToColor.ToFrozenDictionary ();
_colorToNameMap = colorToName.ToFrozenDictionary ();
_combinedColorNames = nameToColor.Keys.Order ().ToImmutableArray ();
}
///
public IEnumerable GetColorNames () => _combinedColorNames;
///
public bool TryParseColor (ReadOnlySpan name, out Color color)
{
if (name.StartsWith ("#") || name.StartsWith ("0x", StringComparison.OrdinalIgnoreCase))
{
try
{
color = Color.Parse (name.ToString (), CultureInfo.InvariantCulture);
return true;
}
catch
{
color = default;
return false;
}
}
if (_ansi.TryParseColor (name, out color)) return true;
if (_standard.TryParseColor (name, out color)) return true;
color = default;
return false;
}
///
public bool TryNameColor (Color color, [NotNullWhen (true)] out string? name)
{
return _colorToNameMap.TryGetValue (color.Argb, out name);
}
}