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

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

//**************************************************************************************************
partial class HArray2D {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static T[] Extract<T>(T[,] array,int dimension,int subarrayIdx)
{
   return Extract( array, dimension, subarrayIdx, null, null, false );
}

public static T[] Extract<T>(T[,] array,int dimension,int subarrayIdx,int? startIdx)
{
   return Extract( array, dimension, subarrayIdx, startIdx, null, false );
}

public static T[] Extract<T>(T[,] array,int dimension,int subarrayIdx,int? startIdx,int? count)
{
   return Extract( array, dimension, subarrayIdx, startIdx, count, false );
}

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

public static T[] BackwardExtract<T>(T[,] array,int dimension,int subarrayIdx)
{
   return Extract( array, dimension, subarrayIdx, null, null, true );
}

public static T[] BackwardExtract<T>(T[,] array,int dimension,int subarrayIdx,int? startIdx)
{
   return Extract( array, dimension, subarrayIdx, startIdx, null, true );
}

public static T[] BackwardExtract<T>( T[,] array, int dimension, int subarrayIdx,
                                      int? startIdx, int? count )
{
   return Extract( array, dimension, subarrayIdx, startIdx, count, true );
}

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

static T[] Extract<T>( T[,] array, int dimension, int subarrayIdx,
                       int? startIdx, int? count, bool backwardScan )
{
   HArrayArgChecking.VerifyIndex( array, dimension, subarrayIdx );

   int
      lowerBound = array.GetLowerBound( 1-dimension ),
      upperBound = array.GetUpperBound( 1-dimension ),
      fromIdx    = startIdx ?? (backwardScan ? upperBound : lowerBound),
      length     = count ?? (backwardScan ? fromIdx-lowerBound+1 : upperBound-fromIdx+1);

   T[] arr = null; int idx = 0;

   ForEachEx
   (
      array, dimension, subarrayIdx,
      (HContinueEnumerationWithIndexCallback<T>)delegate (T element,int index)
      {
         if ( arr == null ) arr = new T[ length ];
         arr[ idx ++ ] = GetValue( array, dimension, subarrayIdx, index );
         return true;
      },
      startIdx, count, backwardScan
   );

   return arr ?? new T[0];
}

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

} // CommonHelpers (.WASM)
