//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// 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

static partial class math {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static double ConfinePositiveOrZero( double x ) =>
   Math.Max( x, 0 );
public static double ConfineNegativeOrZero( double x ) =>
   Math.Min( x, 0 );

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

public static decimal ConfinePositiveOrZero( decimal x ) =>
   Math.Max( x, 0 );
public static decimal ConfineNegativeOrZero( decimal x ) =>
   Math.Min( x, 0 );

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

[CLSCompliant(false)]
public static double ConfinePositiveOrZero( ref double x ) =>
   x = ConfinePositiveOrZero( x );
[CLSCompliant(false)]
public static double ConfineNegativeOrZero( ref double x ) =>
   x = ConfineNegativeOrZero( x );

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

[CLSCompliant(false)]
public static decimal ConfinePositiveOrZero( ref decimal x ) =>
   x = ConfinePositiveOrZero( x );
[CLSCompliant(false)]
public static decimal ConfineNegativeOrZero( ref decimal x ) =>
   x = ConfineNegativeOrZero( x );

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

/// <exception cref="ArgumentOutOfRangeException" />
public static double Confine( double x, double min, double max ) =>
   min <= max ?
      Math.Min( Math.Max( x, min ), max ) :
      throw math_argcheck_errors.INCORRECT_MIN_MAX( nameof(min), nameof(max) );
/// <exception cref="ArgumentOutOfRangeException" />
public static decimal Confine( decimal x, decimal min, decimal max ) =>
   min <= max ?
      Math.Min( Math.Max( x, min ), max ) :
      throw math_argcheck_errors.INCORRECT_MIN_MAX( nameof(min), nameof(max) );

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

/// <exception cref="ArgumentOutOfRangeException" />
[CLSCompliant(false)]
public static double Confine( ref double x, double min, double max ) =>
   x = Confine( x, min, max );
/// <exception cref="ArgumentOutOfRangeException" />
[CLSCompliant(false)]
public static decimal Confine( ref decimal x, decimal min, decimal max ) =>
   x = Confine( x, min, max );

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

/// <exception cref="ArgumentOutOfRangeException" />
public static double UpConfine( ref double x, double max ) =>
   x = Math.Min( x, max );
/// <exception cref="ArgumentOutOfRangeException" />
public static double DownConfine( ref double x, double min ) =>
   x = Math.Max( x, min );

/// <exception cref="ArgumentOutOfRangeException" />
public static decimal UpConfine( ref decimal x, decimal max ) =>
   x = Math.Min( x, max );
/// <exception cref="ArgumentOutOfRangeException" />
public static decimal DownConfine( ref decimal x, decimal min ) =>
   x = Math.Max( x, min );

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // math

} // user_rtx (.wasm)
