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

namespace ENetSharp
{
    public class ENetList
    {
        public List<object> data = new List<object>();
        internal int position;
    }

    public static class ENetListHelper
    {
        /// <summary>
        /// Removes everything from the list
        /// </summary>
        /// <param name="list">The target list</param>
        public static void enet_list_clear(ref ENetList list)
        {
            list.data.Clear();
        }

        public static ENetList enet_list_insert(ref ENetList list, int position, object data)
        {
            list.data.Insert(position, data);

            return list;
        }

        public static ENetList enet_list_insert(ref ENetList list, object data)
        {
            list.data.Add(data);

            return list;
        }

        public static object enet_list_remove(ref ENetList list, int position)
        {
            var data = list.data[position];
            list.data.RemoveAt(position);

            return data;
        }

        public static object enet_list_remove(ref ENetList list)
        {
            var item = list.data[list.position];
            list.data.Remove(item);

            return item;
        }

        public static object enet_list_remove(ref ENetList list, object item)
        {
            list.data.Remove(item);

            return item;
        }

        public static void enet_list_remove(ref ENetList list, Predicate<object> items)
        {
            list.data.RemoveAll(items);
            
        }

        public static ENetList enet_list_move(ref ENetList list, int positionFirst, int positionLast)
        {
            object tmp = list.data[positionFirst];
            list.data[positionFirst] = list.data[positionLast];
            list.data[positionLast] = tmp;

            return list;
        }
        public static int enet_list_size(ref ENetList list)
        {
            return list.data.Count;
        }

        //#define enet_list_begin(list) ((list) -> sentinel.next)
        public static object enet_list_begin(ref ENetList list)
        {
            return list.data.First();
        }
        //#define enet_list_end(list) (& (list) -> sentinel)
        public static object enet_list_end(ref ENetList list)
        {
            return list.data.Last();
        }
        //#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list))
        public static bool enet_list_empty(ref ENetList list)
        {
            return !list.data.Any();
        }

        //#define enet_list_next(iterator) ((iterator) -> next)
        public static object enet_list_next(ref ENetList list)
        {
            var d = list.data[list.position];
            list.position++;
            return d;
        }
        //#define enet_list_previous(iterator) ((iterator) -> previous)
        public static object enet_list_previous(ref ENetList list)
        {
            var d = list.data[list.position];
            list.position--;
            return d;
        }

        //#define enet_list_front(list) ((void *) (list) -> sentinel.next)
        public static object enet_list_front(ref ENetList list)
        {
            return list.data.First();
        }


        //#define enet_list_back(list) ((void *) (list) -> sentinel.previous)
        public static object enet_list_back(ref ENetList list)
        {
            list.position--;
            return list.data[list.position];
        }

        public static object enet_list_current(ref ENetList list)
        {
            return list.data[list.position];
        }
    }
}
