using System;
using System.Collections.Generic;
using Unity.VisualScripting;

namespace NBF
{
    public static class DataArrayExtends
    {
        public static T Find<T>(this IList<T> obj, Predicate<T> match)
        {
            if (obj == null)
                throw new ArgumentNullException();
            if (match == null)
                throw new ArgumentNullException();

            for (int i = 0; i < obj.Count; i++)
            {
                if (match(obj[i]))
                {
                    return obj[i];
                }
            }

            return default(T);
        }

        public static int FindIndex<T>(this IList<T> obj, Predicate<T> match)
        {
            return FindIndex(obj, 0, obj.Count, match);
        }

        public static int FindIndex<T>(this IList<T> obj, int startIndex, int count, Predicate<T> match)
        {
            if (obj == null)
                throw new ArgumentNullException();
            if (startIndex < 0 || startIndex > count)
                throw new ArgumentOutOfRangeException();
            if (count < 0 || startIndex > obj.Count - count)
                throw new ArgumentOutOfRangeException();

            int num = startIndex + count;
            for (int i = startIndex; i < num; i++)
            {
                if (match(obj[i]))
                {
                    return i;
                }
            }

            return -1;
        }

        public static void ForEach<T>(this IList<T> obj, Action<T> action)
        {
            if (obj == null)
                throw new ArgumentNullException();
            if (action == null)
                throw new ArgumentNullException();

            for (int i = 0; i < obj.Count; i++)
            {
                action(obj[i]);
            }
        }

        public static List<T> FindAll<T>(this IList<T> obj, Predicate<T> match)
        {
            if (obj == null)
                throw new ArgumentNullException();
            if (match == null)
                throw new ArgumentNullException();

            List<T> list = new List<T>();
            for (int i = 0; i < obj.Count; i++)
            {
                if (match(obj[i]))
                    list.Add(obj[i]);
            }

            return list;
        }

        public static int RemoveAll<T>(this IList<T> obj, Predicate<T> match)
        {
            if (obj == null)
                throw new ArgumentNullException();
            if (match == null)
                throw new ArgumentNullException();

            int originalSize = obj.Count;
            int index = 0;
            while (index < obj.Count)
            {
                if (match(obj[index]))
                {
                    obj.RemoveAt(index);
                }
                else
                {
                    index++;
                }
            }

            return originalSize - obj.Count;
        }

        public static void Sort<T>(this IList<T> obj, Comparison<T> comparison)
        {
            Sort(obj, 0, obj.Count, comparison);
        }

        public static void Sort<T>(this IList<T> obj, int index, int count, Comparison<T> comparison)
        {
            if (obj == null)
                throw new ArgumentNullException();
            if (index < 0 || count < 0)
                throw new ArgumentOutOfRangeException();
            if (obj.Count - index < count)
                throw new ArgumentException();

            AlgorithmUtils.QuickSortRecursive(obj, index, count - 1, comparison);
        }

        public static void RemoveRange<T>(this IList<T> obj, int index, int count)
        {
            var list = new List<T>(obj);
            list.RemoveRange(index, count);
            obj.Clear();
            obj.AddRange(list);
        }

        public static void Overlay<T>(this IList<T> obj, IEnumerable<T> collection)
        {
            if (obj != collection)
            {
                obj.Clear();
                obj.AddRange(collection);
            }
        }
        
    }
}