using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
namespace RhythmBase.Components.RichText
{
///
/// Represents a rich text string with various styling options.
///
/// The text content of the rich string.
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
public struct RDPhrase(string text)
: IEqualityOperators, RDPhrase, bool>,
IEquatable>
where TStyle : IRDRichStringStyle, new()
{
///
/// Gets the text content of the rich string.
///
public string Text { get; internal set; } = text;
///
/// Gets or sets the events associated with the rich string.
///
public RDDialogueTone[] Events { get; init; } = [];
///
/// Gets the length of the text content.
///
/// The number of characters in the text content.
public readonly int Length => Text.Length;
///
/// Gets the rich string at the specified index.
///
/// The index of the character.
/// A new with the character at the specified index.
public RDPhrase this[Index index]
{
get
{
return new RDPhrase
{
Text = Text[index].ToString(),
Style = Style,
Events = GetEvents(index.GetOffset(Length), 1)
};
}
}
///
/// Gets the rich string within the specified range.
///
/// The range of characters.
/// A new with the characters within the specified range.
public RDPhrase this[Range range]
{
get
{
RDPhrase style = new()
{
Text = Text[range],
Style = Style,
Events = GetEvents(range.Start.GetOffset(Length), range.End.GetOffset(Length) - range.Start.GetOffset(Length))
};
return style;
}
}
private readonly RDDialogueTone[] GetEvents(int start, int length) => Events
.Where(e => e.Index >= start && e.Index < start + length)
.Select(e => new RDDialogueTone(e.Type, e.Index - start))
.ToArray();
///
/// Gets a new with the same style as the current instance.
///
public TStyle Style { get; init; } = new();
///
/// Initializes a new instance of the struct with an empty text.
///
public RDPhrase() : this("") { }
///
/// Implicitly converts a string to an .
///
/// The text to convert.
/// A new instance with the specified text.
public static implicit operator RDPhrase(string text) => new() { Text = text };
///
public static bool operator ==(RDPhrase left, RDPhrase right) => left.Text == right.Text && left.Style == right.Style;
///
public static bool operator !=(RDPhrase left, RDPhrase right) => !(left == right);
///
public readonly bool Equals(RDPhrase other) => this == other;
///
public override readonly bool Equals([NotNullWhen(true)] object? obj) => obj is RDPhrase && base.Equals(obj);
///
public override readonly int GetHashCode() => Text.GetHashCode();
///
public override readonly string ToString() => Text;
///
private readonly string GetDebuggerDisplay() => ToString();
}
}