//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// UserRTX.NET satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;

#if !WASM
namespace user_rtx { using u = user_rtx;
#else
namespace user_rtx.wasm { using u = user_rtx.wasm;
#endif

/// <summary>
/// System ticks
/// </summary>
public static class ticks {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public const long MaxValue = UInt32.MaxValue;

//--------------------------------------------------------------------------------------------------

public static long Current =>
   u.platform.IsWin32 ?
      w32_core.GetTickCount() :
      DateTime.Now.Ticks;

public static int SystemInaccuracy => 15;

//==================================================================================================

public static long ToMilliseconds( long ticks ) =>
   ticks / 10000;

public static long FromMilliseconds( long milliseconds ) =>
   milliseconds * 10000;

//==================================================================================================

public static long ElapsedMilliseconds( long sinceTicks ) =>
   ElapsedMilliseconds( sinceTicks, Current );

public static long ElapsedMilliseconds( long fromTicks, long toTicks ) =>
   ToMilliseconds( fromTicks <= toTicks ?
      toTicks - fromTicks :
      MaxValue - fromTicks + toTicks );

//--------------------------------------------------------------------------------------------------

public static long ElapsedMilliseconds( DateTime since ) =>
   ElapsedMilliseconds( since, DateTime.Now );

public static long ElapsedMilliseconds( DateTime from, DateTime to ) =>
   ToMilliseconds( (to-from).Ticks );

//==================================================================================================

public static bool IsPeriodEspired( long sinceTicks, long timeoutInMilliseconds ) =>
   IsPeriodEspired( sinceTicks, timeoutInMilliseconds, SystemInaccuracy );

public static bool IsPeriodEspired( DateTime since, long timeoutInMilliseconds ) =>
   IsPeriodEspired( since, timeoutInMilliseconds, SystemInaccuracy );

//--------------------------------------------------------------------------------------------------

public static bool IsPeriodEspired( long sinceTicks,
                                    long timeoutInMilliseconds,
                                    int ticksInaccuracy ) =>
   ElapsedMilliseconds( sinceTicks ) > timeoutInMilliseconds + ticksInaccuracy;

public static bool IsPeriodEspired( DateTime since,
                                    long timeoutInMilliseconds,
                                    int ticksInaccuracy ) =>
   ElapsedMilliseconds( since ) > timeoutInMilliseconds + ticksInaccuracy;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // ticks

} // user_rtx (.wasm)
