using System.Globalization;
using System.IO;
using Vellum;
namespace Amphora.Vellum
{
///
/// Saves a Duration as its tick count, with the length in words beside it for people reading the save.
///
///
/// The two ends of the tick count are Forever and -Forever. A finite length saves as the same number a TimeSpan of
/// that length does, so a saved TimeSpan loads as a Duration.
///
public sealed class DurationConverter : SaveConverter
{
public const long ForeverTicks = long.MaxValue;
public const long NegativeForeverTicks = long.MinValue;
// The one count in from -Forever that no Duration is ever saved as.
private const long UnusedTicks = long.MinValue + 1L;
public override SaveNode Write(Duration value, SaveSession session)
{
long ticks;
if (value == Duration.Forever)
{
ticks = ForeverTicks;
}
else if (value == -Duration.Forever)
{
ticks = NegativeForeverTicks;
}
else
{
ticks = value.Ticks;
}
return SaveNode.OfText(ticks.ToString(CultureInfo.InvariantCulture),
comment: value.ToString("c", CultureInfo.InvariantCulture));
}
public override Duration Read(SaveNode node, SaveSession session)
{
long ticks = (long)session.FromNode(node, typeof(long));
if (ticks == ForeverTicks)
{
return Duration.Forever;
}
if (ticks == NegativeForeverTicks)
{
return -Duration.Forever;
}
if (ticks == UnusedTicks)
{
throw new InvalidDataException("A saved duration of " + ticks + " ticks isn't a length of time.");
}
return Duration.FromTicks(ticks);
}
}
}