﻿using System;
using JLGames.RocketDriver.Games.RpgMaterial.Material;

namespace JLGames.RocketDriver.Games.RpgMaterial.User
{
    public interface IUserMaterialSet
    {
        /// <summary>
        /// Number of User Material Data Items
        /// 用户材料数据项数量
        /// </summary>
        int UserMaterialSize { get; }

        /// <summary>
        /// Check if user owns the material
        /// 判断用户是否拥有材料
        /// </summary>
        /// <param name="eKey">Id of each data<br/>用于区分每条材料数据的Id</param>
        /// <returns></returns>
        bool ExistUserMaterial(string eKey);

        /// <summary>
        /// Check if user owns the material
        /// 判断用户是否拥有材料
        /// </summary>
        /// <param name="mId"></param>
        /// <returns></returns>
        bool ExistUserMaterial(int mId);

        /// <summary>
        /// Check if user owns the material
        /// 判断用户是否拥有材料
        /// </summary>
        /// <param name="mId"></param>
        /// <param name="uId"></param>
        /// <returns></returns>
        bool ExistUserMaterial(int mId, int uId);

        /// <summary>
        /// Get the number of user materials
        /// 取用户材料数量
        /// None: return 0
        /// 无：返回0
        /// </summary>
        /// <param name="eKey"></param>
        /// <returns></returns>
        int GetUserMaterialNum(string eKey);

        /// <summary>
        /// Get the number of user materials
        /// 取用户材料数量
        /// None: return 0
        /// 无：返回0
        /// </summary>
        /// <param name="mId"></param>
        /// <returns></returns>
        int GetUserMaterialNum(int mId);

        /// <summary>
        /// Get the number of user materials
        /// 取用户材料数量
        /// None: return 0
        /// 无：返回0
        /// </summary>
        /// <param name="mId"></param>
        /// <param name="uId"></param>
        /// <returns></returns>
        int GetUserMaterialNum(int mId, int uId);

        /// <summary>
        /// Get user material data
        /// 取用户材料数据
        /// If the data is the specified data type, convert the type to return, otherwise return null
        /// 如果数据为指定数据类型，则转类型返回，否则返回null
        /// </summary>
        /// <param name="eKey"></param>
        /// <typeparam name="TUAs"></typeparam>
        /// <returns></returns>
        TUAs GetUserMaterialAs<TUAs>(string eKey) where TUAs : IUserMaterial;

        /// <summary>
        /// Get user material data
        /// 取用户材料数据
        /// If the data is the specified data type, convert the type to return, otherwise return null
        /// 如果数据为指定数据类型，则转类型返回，否则返回null
        /// </summary>
        /// <param name="mId"></param>
        /// <param name="uId"></param>
        /// <typeparam name="TUAs"></typeparam>
        /// <returns></returns>
        TUAs GetUserMaterialAs<TUAs>(int mId, int uId = 0) where TUAs : IUserMaterial;

        /// <summary>
        /// Get user material data array
        /// 取用户材料数据
        /// If the data is the specified data type, convert the type to return, otherwise return null
        /// 如果数据为指定数据类型，则转类型返回，否则返回null
        /// </summary>
        /// <typeparam name="TUAs"></typeparam>
        /// <returns></returns>
        TUAs[] GetUserMaterialsAs<TUAs>() where TUAs : IUserMaterial;

        /// <summary>
        /// Get user material data array
        /// 取用户材料数据
        /// If the data is the specified data type, convert the type to return, otherwise return null
        /// 如果数据为指定数据类型，则转类型返回，否则返回null
        /// </summary>
        /// <param name="mId"></param>
        /// <typeparam name="TUAs"></typeparam>
        /// <returns></returns>
        TUAs[] GetUserMaterialsAs<TUAs>(int mId) where TUAs : IUserMaterial;

        /// <summary>
        /// Iterate over each user material data
        /// 遍历指定数据类型的用户材料
        /// </summary>
        /// <param name="each"></param>
        /// <typeparam name="TUAs"></typeparam>
        void ForeachUserMaterialAs<TUAs>(Action<TUAs> each) where TUAs : IUserMaterial;
    }

    public interface IUserMaterialSet<TU, TM, TCfg> : IUserMaterialSet
        where TU : IUserMaterial<TM, TCfg> where TM : IMaterial<TCfg>
    {
        /// <summary>
        /// Get the number of eligible user material data items by match function
        /// 按要求计算符合条件的用户材料数据项数量
        /// </summary>
        /// <param name="match"></param>
        /// <returns></returns>
        int GetSize(Predicate<TU> match);

        /// <summary>
        /// Get user material data by element id
        /// 取用户材料数据
        /// </summary>
        /// <param name="eKey"></param>
        /// <returns></returns>
        TU GetUserMaterial(string eKey);

        /// <summary>
        /// Get user material data by element id
        /// 取用户材料数据
        /// </summary>
        /// <param name="mId"></param>
        /// <param name="uId"></param>
        /// <returns></returns>
        TU GetUserMaterial(int mId, int uId = 0);

        /// <summary>
        /// Get all user material data.
        /// 取全部用户材料数据
        /// </summary>
        /// <returns></returns>
        TU[] GetUserMaterials();

        /// <summary>
        /// Get some user material data by material id.
        /// 取部分用户材料数据
        /// </summary>
        /// <param name="mId">选择的材料Id</param>
        /// <returns></returns>
        TU[] GetUserMaterials(int mId);

        /// <summary>
        /// Get some user material data by match function.
        /// 取部分用户材料数据
        /// </summary>
        /// <returns></returns>
        TU[] GetUserMaterials(Predicate<TU> match);

        /// <summary>
        /// Iterate over each user material data
        /// 遍历全部用户材料
        /// </summary>
        /// <param name="each"></param>
        void ForeachUserMaterial(Action<TU> each);
    }
}