using System.Collections;
using System.Collections.Generic;
using System.Text;
using System;

namespace Rokojori
{
  public class Arrays
  {
    public static T[] Concat<T>( T[] a, T[] b )
    {
      var o = new T[ a.Length + b.Length ];
      
      a.CopyTo( o, 0 );
      b.CopyTo( o, a.Length );
      
      return o;
    }

    public static int IndexOf<T>( T[] values, T other  )
    {
      return Array.IndexOf( values, other );
    }

    public static U[] Map<T,U>( T[] values, Func<T,U> mapper  )
    {
      var u = new U[ values.Length ];

      for ( int i = 0; i < values.Length; i++ )
      {
        u[ i ] = mapper( values[ i ] );
      }

      return u;
    }


    public static int FindIndex<T>( T[] values, Func<T,bool> predicate  )
    {
      for ( int i = 0; i < values.Length; i++ )
      {
        if ( predicate( values[ i ] ) )
        {
          return i;
        }
      }

      return -1;
    }

    public static bool Contains <T>( T[] values, T other )
    {
      return Array.IndexOf( values, other ) != -1;
    }

    public static T[] Add<T>( T[] values, T other )
    {
      var newValues = new T[ values.Length + 1 ];

      Array.Copy( values, newValues, values.Length );
      newValues[ values.Length ] = other;

      return newValues;
    }

    public static void ForEach<T>( T[] values, Action<T> callback )
    {
      foreach ( var it in values )
      {
        callback( it );
      }
    }

    public static bool AreArraysAndEntriesEqual( object objA, object objB )
    {
      if ( ! ( objA.GetType().IsArray && objB.GetType().IsArray ) )
      {
        return false;
      }

      return Lists.AreEntriesEqual( 
        Lists.FromEnumerable<object>( objA as IEnumerable ),  
        Lists.FromEnumerable<object>( objA as IEnumerable ) 
      );
    }

    public static bool AreEntriesEqual<T>( T[] a, T[] b )
    {
      if ( a.Length != b.Length )
      {
        return false;
      }

      for ( int i = 0; i < a.Length; i++ )
      {
        var isEqual = EqualityComparer<T>.Default.Equals( a[ i ], b[ i ]);

        if ( ! isEqual )
        {
          return false;
        }
      }

      return true;
    }
  }
}