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

#if !WASM
namespace CommonHelpers {
#else
namespace CommonHelpers.WASM {
#endif

//**************************************************************************************************
/// <summary>
/// </summary>
public static partial class HArray2D {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static bool IsNullOrEmpty<T>(T[,] array)
{
   return array==null || array.Length==0;
}

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

public static bool IsIndexInValidBounds<T>(T[,] array,int dimension,int index)
{
   HArgChecking.VerifyNotNull( array );
   HArrayArgChecking.VerifyDimension( array, dimension );
   return HOps.IsBetween( index,
      array.GetLowerBound( dimension ),
      array.GetUpperBound( dimension ) );
}

public static bool IsValidDimension<T>(T[,] array,int dimension)
{
   HArgChecking.VerifyNotNull( array );
   return HOps.IsOneOf(dimension,0,1);
}

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

public static T[,] CreateInit<T>(int lengthA,int lengthB,T uniformValue)
{
   return SetUniformValue( new T[ lengthA, lengthB ], uniformValue );
}

public static T[,] Duplicate<T>(T[,] array)
{
   return (T[,])array.Clone();
}

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

[HOptionalResult]
public static T[,] SetUniformValue<T>([HOptional] T[,] array,T value)
{
   if ( array == null )
      return null;
   for (int i=array.GetLowerBound(0); i<=array.GetUpperBound(0); i++)
      for (int j=array.GetLowerBound(1); j<=array.GetUpperBound(1); j++)
         array[ i, j ] = value;
   return array;
}

[HOptionalResult]
public static T[,] SetDefaultValueForAll<T>([HOptional] T[,] array)
{
   return SetUniformValue( array, default(T) );
}

[HOptionalResult]
public static T[,] SetNullForAll<T>([HOptional] T[,] array) where T: class
{
   return SetDefaultValueForAll( array );
}

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

public static T[,] Copy<T>(T[,] source,T[,] destination)
{
   HArgChecking.VerifyNotNulls( source, destination );
   for (int dimension=0; dimension<=1; dimension++)
      if ( source.GetLength(dimension) != destination.GetLength(dimension) )
         throw new ArgumentException();
   int
      length_0 = source.GetLength(0),
      length_1 = source.GetLength(1),
      sourceLowerBound_0 = source.GetLowerBound(0),
      sourceLowerBound_1 = source.GetLowerBound(1),
      destLowerBound_0 = destination.GetLowerBound(0),
      destLowerBound_1 = destination.GetLowerBound(1);
   for (int i=0; i<length_0; i++)
      for (int j=0; j<length_1; j++)
         destination[ destLowerBound_0   + i, destLowerBound_1   + j ] =
         source     [ sourceLowerBound_0 + i, sourceLowerBound_1 + j ];
   return destination;
}

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

static HArray2D()
{
   CommonHelpers_Core.Access();
}

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

static T GetValue<T>(T[,] array,int dimension,int subarrayIdx,int elementIdx)
{
   return dimension==0 ?
      array[ subarrayIdx, elementIdx ] :
      array[ elementIdx, subarrayIdx ];
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HArray2D
//**************************************************************************************************

} // CommonHelpers (.WASM)
