﻿using System;
using System.Collections.Generic;

namespace JLGames.RocketDriver.Games.RpgMaterial.Common
{
    public interface IElementSet
    {
        /// <summary>
        /// Size
        /// 总量
        /// </summary>
        int Size { get; }

        /// <summary>
        /// Check if exist
        /// 检查是否存在
        /// </summary>
        /// <param name="eKey"></param>
        /// <returns></returns>
        bool Exist(string eKey);

        /// <summary>
        /// Get element by element key
        /// 取元素
        /// </summary>
        /// <param name="eKey"></param>
        /// <returns></returns>
        IElement GetElement(string eKey);

        /// <summary>
        /// Get element by element key and convert to TAs
        /// 取元素
        /// </summary>
        /// <param name="eKey"></param>
        /// <returns></returns>
        TAs GetElement<TAs>(string eKey) where TAs : IElement;

        /// <summary>
        /// Get element by match function and convert to TAs
        /// 取元素
        /// </summary>
        /// <param name="match"></param>
        /// <returns></returns>
        TAs GetElement<TAs>(Predicate<TAs> match) where TAs : IElement;

        /// <summary>
        /// Get elements by elements keys and convert to TAs array
        /// 取多个元素
        /// </summary>
        /// <param name="eKeyArr"></param>
        /// <returns></returns>
        TAs[] GetElements<TAs>(string[] eKeyArr) where TAs : IElement;

        /// <summary>
        /// Get elements by elements keys and convert to TAs array
        /// 取多个元素
        /// </summary>
        /// <param name="eKeyArr"></param>
        /// <returns></returns>
        TAs[] GetElements<TAs>(IEnumerable<string> eKeyArr) where TAs : IElement;

        /// <summary>
        /// Get elements by match function and convert to TAs array
        /// 取多个元素
        /// </summary>
        /// <param name="match"></param>
        /// <returns></returns>
        TAs[] GetElements<TAs>(Predicate<TAs> match) where TAs : IElement;

        /// <summary>
        /// Get all elements and convert to TAs array
        /// 取全部元素
        /// </summary>
        /// <returns></returns>
        TAs[] GetElements<TAs>() where TAs : IElement;

        /// <summary>
        /// Iterate over each element
        /// 遍历每个元素
        /// </summary>
        /// <param name="each"></param>
        void ForeachElement<TAs>(Action<TAs> each) where TAs : IElement;

        /// <summary>
        /// Remove element by element key
        /// 移除元素
        /// </summary>
        /// <param name="eKey"></param>
        /// <returns>被移除的元素</returns>
        IElement RemoveElement(string eKey);

        /// <summary>
        /// Remove elements by element keys
        /// 移除多个元素
        /// If element key is not exist, return default value of Type
        /// 如果对应EKey不存在，补default(T)
        /// </summary>
        /// <param name="eKeyArr"></param>
        /// <returns></returns>
        IElement[] RemoveElements(string[] eKeyArr);

        /// <summary>
        /// Remove elements by element keys
        /// 移除多个元素
        /// If element key is not exist, return default value of Type
        /// 如果对应EKey不存在，补default(T)
        /// </summary>
        /// <param name="eKeyArr"></param>
        /// <returns></returns>
        IElement[] RemoveElements(IEnumerable<string> eKeyArr);

        /// <summary>
        /// Remove elements by match function
        /// 移除多个元素
        /// </summary>
        /// <param name="match"></param>
        /// <returns></returns>
        IElement[] RemoveElements(Predicate<IElement> match);

        /// <summary>
        /// Remove all elements
        /// 移除全部元素
        /// </summary>
        /// <returns></returns>
        IElement[] RemoveElements();

        /// <summary>
        /// Add element into set.
        /// 添加元素
        /// Ignore if element key is exist
        /// 如果元素的EKey存在，忽略
        /// </summary>
        /// <param name="ele"></param>
        void AddElement(IElement ele);

        /// <summary>
        /// Add elements into set.
        /// 添加元素
        /// Ignore if element key is exist
        /// 如果元素的EKey存在，忽略
        /// </summary>
        /// <param name="eleArr"></param>
        void AddElements<TAs>(IEnumerable<TAs> eleArr) where TAs : IElement;

        /// <summary>
        /// Replace element into set.
        /// 添加元素
        /// Add if element key is not exist, and replace if element key is exist.
        /// 如果元素的EKey不存在，直接添加
        /// </summary>
        /// <param name="ele"></param>
        void ReplaceElement(IElement ele);

        /// <summary>
        /// Replace elements into set.
        /// 添加元素
        /// Add if element key is not exist, and replace if element key is exist.
        /// 如果元素的EKey不存在，直接添加
        /// </summary>
        /// <param name="eleArr"></param>
        void ReplaceElements<TAs>(IEnumerable<TAs> eleArr) where TAs : IElement;

        /// <summary>
        /// Sort elements
        /// 排序
        /// </summary>
        /// <param name="comparer"></param>
        void SortElements(IComparer<IElement> comparer);

        /// <summary>
        /// Sort elements
        /// 排序
        /// </summary>
        /// <param name="comparison"></param>
        void SortElements(Comparison<IElement> comparison);
    }

    public interface IElementSet<T> : IElementSet where T : IElement
    {
        /// <summary>
        /// Get element by index
        /// 索引器
        /// </summary>
        /// <param name="index"></param>
        T this[int index] { get; set; }

        /// <summary>
        /// Get element by element key
        /// 取元素
        /// </summary>
        /// <param name="eKey"></param>
        /// <returns></returns>
        T Get(string eKey);

        /// <summary>
        /// Get element by match function
        /// 取元素
        /// </summary>
        /// <param name="match"></param>
        /// <returns></returns>
        T Get(Predicate<T> match);

        /// <summary>
        /// Get elements by element keys
        /// 取多个元素
        /// </summary>
        /// <param name="eKeyArr"></param>
        /// <returns></returns>
        T[] GetRange(string[] eKeyArr);

        /// <summary>
        /// Get elements by element keys
        /// 取多个元素
        /// </summary>
        /// <param name="eKeyArr"></param>
        /// <returns></returns>
        T[] GetRange(IEnumerable<string> eKeyArr);

        /// <summary>
        /// Get elements by match function
        /// 取多个元素
        /// </summary>
        /// <param name="match"></param>
        /// <returns></returns>
        T[] GetRange(Predicate<T> match);

        /// <summary>
        /// Get all elements
        /// 取全部元素
        /// </summary>
        /// <returns></returns>
        T[] GetAll();

        /// <summary>
        /// 遍历每个元素
        /// </summary>
        /// <param name="each"></param>
        void Foreach(Action<T> each);

        /// <summary>
        /// Iterate over each element
        /// 遍历每个元素
        /// </summary>
        /// <param name="each"></param>
        void Foreach<TAs>(Action<TAs> each) where TAs : T;

        /// <summary>
        /// Remove element by element key
        /// 移除元素
        /// </summary>
        /// <param name="eKey"></param>
        /// <returns>被移除的元素</returns>
        T Remove(string eKey);

        /// <summary>
        /// Remove elements by element keys
        /// 移除多个元素
        /// If element key is not exist, return default value of Type
        /// 如果对应EKey不存在，补default(T)
        /// </summary>
        /// <param name="eKeyArr"></param>
        /// <returns></returns>
        T[] RemoveRange(string[] eKeyArr);

        /// <summary>
        /// Remove elements by element keys
        /// 移除多个元素
        /// If element key is not exist, return default value of Type
        /// 如果对应EKey不存在，补default(T)
        /// </summary>
        /// <param name="eKeyArr"></param>
        /// <returns></returns>
        T[] RemoveRange(IEnumerable<string> eKeyArr);

        /// <summary>
        /// Remove elements by match function
        /// 移除多个元素
        /// </summary>
        /// <param name="match"></param>
        /// <returns></returns>
        T[] RemoveRange(Predicate<T> match);

        /// <summary>
        /// Remove all elements
        /// 移除全部元素
        /// </summary>
        /// <returns></returns>
        T[] RemoveAll();

        /// <summary>
        /// Add element into set.
        /// 添加元素
        /// Ignore if element key is exist
        /// 如果元素的EKey存在，忽略
        /// </summary>
        /// <param name="ele"></param>
        void Add(T ele);

        /// <summary>
        /// Add elements into set.
        /// 添加元素
        /// Ignore if element key is exist
        /// 如果元素的EKey存在，忽略
        /// </summary>
        /// <param name="eleArr"></param>
        void AddRange(IEnumerable<T> eleArr);

        /// <summary>
        /// Replace element into set.
        /// 添加元素
        /// Add if element key is not exist, and replace if element key is exist.
        /// 如果元素的EKey不存在，直接添加
        /// </summary>
        /// <param name="ele"></param>
        void Replace(T ele);

        /// <summary>
        /// Replace elements into set.
        /// 添加元素
        /// Add if element key is not exist, and replace if element key is exist.
        /// 如果元素的EKey不存在，直接添加
        /// </summary>
        /// <param name="eleArr"></param>
        void ReplaceRange(IEnumerable<T> eleArr);

        /// <summary>
        /// Sort elements
        /// 排序
        /// </summary>
        /// <param name="comparer"></param>
        void Sort(IComparer<T> comparer);

        /// <summary>
        /// Sort elements
        /// 排序
        /// </summary>
        /// <param name="comparer"></param>
        void Sort<TAs>(IComparer<TAs> comparer) where TAs : T;

        /// <summary>
        /// Sort elements
        /// 排序
        /// </summary>
        /// <param name="comparison"></param>
        void Sort(Comparison<T> comparison);

        /// <summary>
        /// Sort elements
        /// 排序
        /// </summary>
        /// <param name="comparison"></param>
        void Sort<TAs>(Comparison<TAs> comparison) where TAs : T;
    }
}