// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics.Contracts;
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml.Media.Animation;
using Windows.Foundation.Metadata;
#pragma warning disable CS0419
namespace CommunityToolkit.WinUI.UI.Animations
{
///
/// A type describing the repeat behavior for a custom animation.
///
[CreateFromString(MethodName = "CommunityToolkit.WinUI.UI.Animations.RepeatOption.Parse")]
public readonly struct RepeatOption
{
///
/// The number of iterations for the animation.
///
private readonly int value;
///
/// Initializes a new instance of the struct.
///
/// The number of iterations for the animation.
private RepeatOption(int value)
{
this.value = value;
}
///
/// Gets a value representing a single iteration.
///
public static RepeatOption Once => new(1);
///
/// Gets a value indicating an animation that repeats forever.
///
public static RepeatOption Forever => new(-1);
///
/// Creates a value with the specified number of iterations.
///
/// The number of iterations for the animation.
/// A value with the specified number of iterations.
/// Thrown when is negative.
[Pure]
public static RepeatOption Count(int count)
{
if (count < 0)
{
ThrowArgumentOutOfRangeForCount();
}
return new(count);
}
///
/// Parses a value from a .
/// The allowed values are either non-negative integers, or "Forever".
///
/// The input text to parse.
/// The parsed value.
[Pure]
public static RepeatOption Parse(string text)
{
if (int.TryParse(text, out int count))
{
return Count(count);
}
if (text.Trim().Equals("Forever", StringComparison.InvariantCultureIgnoreCase))
{
return Forever;
}
return ThrowArgumentExceptionForText();
}
///
/// Gets a value corresponding to the current value.
///
/// A value matching the current value.
[Pure]
public RepeatBehavior ToRepeatBehavior()
{
if (this.value < 0)
{
return RepeatBehavior.Forever;
}
return new(this.value);
}
///
/// Gets the and count values matching the current value.
/// If the current value represents an infinitely repeating animation, the returned count will be set to 1.
///
/// The and count values matching the current value.
[Pure]
public (AnimationIterationBehavior Behavior, int Count) ToBehaviorAndCount()
{
if (this.value < 0)
{
return (AnimationIterationBehavior.Forever, 1);
}
return (AnimationIterationBehavior.Count, this.value);
}
///
/// Throws a new when the constructor is invoked with an incorrect parameter.
///
private static void ThrowArgumentOutOfRangeForCount()
{
throw new ArgumentOutOfRangeException("The parameter \"count\" must be greater than or equal to 0.");
}
///
/// Throws a new when the constructor is invoked with an incorrect parameter.
///
private static RepeatOption ThrowArgumentExceptionForText()
{
throw new ArgumentException("The input text is not valid to parse a new RepeatOption instance. It must be either a natural number or \"Forever\".");
}
}
}