//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// 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>
/// General operations
/// </summary>
public static partial class ops {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="ArgumentException" />
public static int VerifyArgListIndexOf( int idx ) =>
   idx >= 0 ? idx : throw new ArgumentException(
      "Value was not found among the arguments." );

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

public static void NOP() {}
public static bool True => true;
public static bool False => false;

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

/// <exception cref="ArgumentException" />
[u.failure_as_minus_1]
public static int IndexOf( int val, params int[] values )
{
   u.array_argcheck.ZeroBased( values, nameof(values) );
   for ( int i=0; i<values.Length; i++ )
      if ( val == values[i] )
         return i;
   return -1;
}
/// <exception cref="ArgumentException" />
[u.strict_result]
public static int StrictIndexOf( int val, params int[] values ) =>
   VerifyArgListIndexOf( IndexOf( val, values ) );

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

public static bool IsBetween( int value, int lowerBound, int upperBound ) =>
   value >= lowerBound && value <= upperBound;

public static bool IsExBetween<T>( int value, int lowerBound, int upperBound ) =>
   value > lowerBound && value < upperBound;

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

/// <exception cref="ArgumentException" />
[u.failure_as_minus_1]
public static int IndexOf_O( object? val, params object?[] values )
{
   u.array_argcheck.ZeroBased( values, nameof(values) );
   for ( int i=0; i<values.Length; i++ )
      if ( object.Equals( val, values[i] ) )
         return i;
   return -1;
}
/// <exception cref="ArgumentException" />
[u.strict_result]
public static int StrictIndexOf_O( object? val, params object?[] values ) =>
   VerifyArgListIndexOf( IndexOf_O( val, values ) );

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

/// <exception cref="ArgumentException" />
public static bool IsOneOf_O( object? val, params object?[] values ) =>
   IndexOf_O( val, values ) >= 0;

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

public static bool HasNN( params object?[] values )
{
   foreach ( var v in values )
      if ( v != null )
         return true;
   return false;
}

public static bool HasNull( params object?[] values )
{
   foreach ( var v in values )
      if ( v == null )
         return true;
   return false;
}

public static bool NotNulls( params object?[] values ) =>
   values.Length > 0 && !HasNull( values );
public static bool AllNulls( params object?[] values ) =>
   values.Length > 0 && !HasNN( values );

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

public static bool? IntToNBool( int value )
{
   switch ( value )
   {
   case 0: return false;
   case 1: return true;
   default: return null;
   } // switch
}

public static bool? IntToNBool( int value, bool liberalVersion ) =>
   liberalVersion ?
      value < 0 ? (bool?)null : value > 0 :
      IntToNBool( value );

public static int NBoolToInt( bool? value ) =>
   value.HasValue ? value.Value ? 1 : 0 : -1;

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

public static bool IsTrueNV( bool? value ) =>
   value.HasValue && value.Value;

public static bool SetBoolNV( out bool? location ) =>
   u.nval.SetValue( out location, true );
public static bool SetBoolNV( out bool? location, bool value ) =>
   u.nval.SetValue( out location, value );

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // ops

} // user_rtx (.wasm)
