using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProjectBus.CollectionGenericObject;

/// <summary>
/// Параметризованный набор объектов
/// </summary>
/// <typeparam name="T">Параметр: ограничение - ссылочный тип</typeparam>
    public class MassiveGenericObjects<T> : ICollectionGenericObjects<T>
    where T : class

    {
        /// <summary>
        /// Массив объектов, которые храним
        /// </summary>
        private T?[] _collection;

        public int Count => _collection.Length;

        public int SetMaxCount
        {
            set
            {
                if (value > 0)
                {
                    if (_collection.Length > 0)
                    {
                        Array.Resize(ref _collection, value);
                    }
                    else
                    {
                        _collection = new T?[value];
                    }
                }
            }
        }

        /// <summary>
        /// Конструктор
        /// </summary>
        public MassiveGenericObjects()
        {
            _collection = Array.Empty<T?>();
        }

        public T? Get(int position)
        {
            if (position >= 0 && position < Count)
            {
                return _collection[position];
            }

            return null;
        }

        public int Insert(T obj)
        {
            // вставка в свободное место набора
            for (int i = 0; i < Count; i++)
            {
                if (_collection[i] == null)
                {
                    _collection[i] = obj;
                    return i;
                }
            }

            return -1;
        }

        public int Insert(T obj, int position)
        {
            // проверка позиции
            if (position < 0 || position >= Count)
            {
                return -1;
            }

            // проверка, что элемент массива по этой позиции пустой, если нет, то ищется свободное место после этой позиции и идет вставка туда если нет после, ищем до
            if (_collection[position] != null)
            {
                bool pushed = false;
                for (int index = position + 1; index < Count; index++)
                {
                    if (_collection[index] == null)
                    {
                        position = index;
                        pushed = true;
                        break;
                    }
                }

                if (!pushed)
                {
                    for (int index = position - 1; index >= 0; index--)
                    {
                        if (_collection[index] == null)
                        {
                            position = index;
                            pushed = true;
                            break;
                        }
                    }
                }

                if (!pushed)
                {
                    return position;
                }
            }

            // вставка
            _collection[position] = obj;
            return position;
        }

        public T? Remove(int position)
        {
            //  проверка позиции
            if (position < 0 || position >= Count)
            {
                return null;
            }

            if (_collection[position] == null) return null;

            T? temp = _collection[position];
            _collection[position] = null;
            return temp;
        }
    }