#nullable enable
using System.Numerics;
using System.Text.Json.Serialization;
namespace Terminal.Gui;
/// Attributes represent how text is styled when displayed in the terminal.
///
/// provides a platform independent representation of colors (and someday other forms of
/// text styling). They encode both the foreground and the background color and are used in the
/// class to define color schemes that can be used in an application.
///
[JsonConverter (typeof (AttributeJsonConverter))]
public readonly record struct Attribute : IEqualityOperators
{
/// Default empty attribute.
[JsonIgnore]
public static Attribute Default => new (Color.White, ColorName.Black);
/// The -specific color value.
[JsonIgnore (Condition = JsonIgnoreCondition.Always)]
internal int PlatformColor { get; init; }
/// The foreground color.
[JsonConverter (typeof (ColorJsonConverter))]
public Color Foreground { get; }
/// The background color.
[JsonConverter (typeof (ColorJsonConverter))]
public Color Background { get; }
/// Initializes a new instance with default values.
public Attribute ()
{
this = Default with { PlatformColor = -1 };
}
/// Initializes a new instance from an existing instance.
public Attribute (in Attribute attr)
{
this = attr with { PlatformColor = -1 };
}
/// Initializes a new instance of the struct.
/// platform-dependent color value.
/// Foreground
/// Background
internal Attribute (int platformColor, Color foreground, Color background)
{
Foreground = foreground;
Background = background;
PlatformColor = platformColor;
}
/// Initializes a new instance of the struct.
/// Foreground
/// Background
public Attribute (in Color foreground, in Color background)
{
Foreground = foreground;
Background = background;
// TODO: Once CursesDriver supports true color all the PlatformColor stuff goes away
PlatformColor = Application.Driver?.MakeColor(in foreground, in background).PlatformColor ?? -1;
}
///
/// Initializes a new instance with a value. Both and
/// will be set to the specified color.
///
/// Value.
internal Attribute (in ColorName colorName) : this (in colorName, in colorName) { }
/// Initializes a new instance of the struct.
/// Foreground
/// Background
public Attribute (in ColorName foregroundName, in ColorName backgroundName)
: this (new Color (in foregroundName), new Color (in backgroundName))
{ }
/// Initializes a new instance of the struct.
/// Foreground
/// Background
public Attribute (in ColorName foregroundName, in Color background) : this (new Color (in foregroundName), in background) { }
/// Initializes a new instance of the struct.
/// Foreground
/// Background
public Attribute (in Color foreground, in ColorName backgroundName) : this (in foreground, new Color (in backgroundName)) { }
///
/// Initializes a new instance of the struct with the same colors for the foreground and
/// background.
///
/// The color.
public Attribute (in Color color) : this (color, color) { }
///
public override int GetHashCode () { return HashCode.Combine (PlatformColor, Foreground, Background); }
///
public override string ToString ()
{
// Note: Unit tests are dependent on this format
return $"[{Foreground},{Background}]";
}
}