using System.Diagnostics.CodeAnalysis;
namespace MultiversalDiplomacy.Model;
///
/// A timeline of a game. Essentially a wrapper around for tracking the multiversal dimension.
///
public struct Timeline
{
public readonly int number;
///
/// Timeline designations for differentiating timelines. Shortenable to the first character.
///
private static readonly string[] primaryDesignations = new string[]
{
"alfa",
"bravo",
"charlie",
"delta",
"echo",
"foxtrot",
"golf",
"hotel",
"india",
"juliett",
"kilo",
"lima",
"mike",
"november",
"oscar",
"papa",
"quebec",
"romeo",
"sierra",
"tango",
"uniform",
"victor",
"whiskey",
"xray",
"yankee",
"zulu"
};
///
/// Disambiguators used once all primary timeline designations have been used.
///
private static readonly string[] secondaryDesignations = new string[]
{
"",
"-prime",
"-second",
"-third",
"-fourth",
"-fifth",
"-sixth",
"-seventh",
"-eighth",
"-ninth",
};
///
/// Short versions of the secondary timeline disambiguators.
///
private static readonly string[] secondaryDesignationsShort = new string[]
{
"",
"'",
"\"",
"\x2073",
"\x2074",
"\x2075",
"\x2076",
"\x2077",
"\x2078",
"\x2079",
};
public Timeline(int number)
{
if (number < FIRST_TIMELINE)
{
throw new ArgumentException($"Invalid timeline number: {number}", nameof(number));
}
if (number >= primaryDesignations.Length * secondaryDesignations.Length)
{
throw new ArgumentException($"Timeline number too high: {number}", nameof(number));
}
this.number = number;
}
///
/// The first timeline number.
///
public const int FIRST_TIMELINE = 0;
///
/// Which primary designation the timeline has.
///
private int primaryIndex => number % primaryDesignations.Length;
///
/// Which secondary designation the timeline has.
///
private int secondaryIndex => number / primaryDesignations.Length;
///
/// Returns the timeline's full string representation.
///
/// The timeline designation as a string, such as "bravo" or "delta-prime".
public override string ToString()
=> primaryDesignations[primaryIndex] + secondaryDesignations[secondaryIndex];
///
/// Returns a shorter string representation of the timeline.
///
/// The timeline's designation as a string, such as "b" or "d'".
public string ToShort()
=> primaryDesignations[primaryIndex][0] + secondaryDesignationsShort[secondaryIndex];
///
/// Returns a value indicating whether this instance is equal to a specified value.
///
/// true if obj has the same value as this instance; otherwise, false.
public override bool Equals([NotNullWhen(true)] object? obj)
=> obj is Timeline other
? number.Equals(other.number)
: false;
///
/// Returns the hash code for this instance.
///
/// A 32-bit signed integer hash code.
public override int GetHashCode()
=> number.GetHashCode();
public static int operator -(Timeline first, Timeline second)
=> Math.Abs(first.number - second.number);
}