using System;
using System.Collections.Generic;
namespace Stary.Evo
{

    
    public class EnumEventSystem 
    {
        public static readonly EnumEventSystem Global = new EnumEventSystem();
        
        private readonly Dictionary<string, IEasyEvent> mEvents = new Dictionary<string, IEasyEvent>(50);
        
        public EnumEventSystem(){}

        #region 功能函数

        public  IUnRegister Register<T>(T key, Action onEvent)where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);
            if (mEvents.TryGetValue(kv, out var e))
            {
                var easyEvent = e.As<EasyEvent>();
                return easyEvent.Register(onEvent);
            }
            else
            {
                var easyEvent = new EasyEvent();
                mEvents.Add(kv,easyEvent);
                return easyEvent.Register(onEvent);
            }
        }
        public  IUnRegister Register<T,T1>(T key, Action<T1> onEvent)where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);
            if (mEvents.TryGetValue(kv, out var e))
            {
                var easyEvent = e.As<EasyEvent<T1>>();
                return easyEvent.Register(onEvent);
            }
            else
            {
                var easyEvent = new EasyEvent<T1>();
                mEvents.Add(kv,easyEvent);
                return easyEvent.Register(onEvent);
            }
        }
        public  IUnRegister Register<T,T1,T2>(T key, Action<T1,T2> onEvent)where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);
            if (mEvents.TryGetValue(kv, out var e))
            {
                var easyEvent = e.As<EasyEvent<T1,T2>>();
                return easyEvent.Register(onEvent);
            }
            else
            {
                var easyEvent = new EasyEvent<T1,T2>();
                mEvents.Add(kv,easyEvent);
                return easyEvent.Register(onEvent);
            }
        }
        public IUnRegister Register<T,T1,T2,T3>(T key, Action<T1,T2,T3> onEvent) where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);

            if (mEvents.TryGetValue(kv, out var e))
            {
                var easyEvent = e.As<EasyEvent<T1,T2,T3>>();
                return easyEvent.Register(onEvent);
            }
            else
            {
                var easyEvent = new EasyEvent<T1,T2,T3>();
                mEvents.Add(kv, easyEvent);
                return easyEvent.Register(onEvent);
            }
        }
        public IUnRegister Register<T>(T key, Action<object[]> onEvent) where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);

            if (mEvents.TryGetValue(kv, out var e))
            {
                var easyEvent = e.As<EasyEvent<object[]>>();
                return easyEvent.Register(onEvent);
            }
            else
            {
                var easyEvent = new EasyEvent<object[]>();
                mEvents.Add(kv, easyEvent);
                return easyEvent.Register(onEvent);
            }
        }
        public void UnRegister<T>(T key, Action onEvent) where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);

            if (mEvents.TryGetValue(kv, out var e))
            {
                e.As<EasyEvent>()?.UnRegister(onEvent);
            }
        }
        public void UnRegister<T,T1>(T key, Action<T1> onEvent) where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);

            if (mEvents.TryGetValue(kv, out var e))
            {
                e.As<EasyEvent<T1>>()?.UnRegister(onEvent);
            }
        }
        public void UnRegister<T,T1,T2>(T key, Action<T1,T2> onEvent) where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);

            if (mEvents.TryGetValue(kv, out var e))
            {
                e.As<EasyEvent<T1,T2>>()?.UnRegister(onEvent);
            }
        }
        public void UnRegister<T,T1,T2,T3>(T key, Action<T1,T2,T3> onEvent) where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);

            if (mEvents.TryGetValue(kv, out var e))
            {
                e.As<EasyEvent<T1,T2,T3>>()?.UnRegister(onEvent);
            }
        }
        public void UnRegister<T>(T key, Action<object[]> onEvent) where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);

            if (mEvents.TryGetValue(kv, out var e))
            {
                e.As<EasyEvent<object[]>>()?.UnRegister(onEvent);
            }
        }

     

        public void UnRegisterAll()
        {
            mEvents.Clear();
        }
        public void Send<T>(T key) where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);

            if (mEvents.TryGetValue(kv, out var e))
            {
                e.As<EasyEvent>().Trigger();
            }
        }
        public void Send<T,T1>(T key, T1 t1) where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);

            if (mEvents.TryGetValue(kv, out var e))
            {
                e.As<EasyEvent<T1>>().Trigger(t1);
            }
        }
        public void Send<T,T1,T2>(T key, T1 t1,T2 t2) where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);

            if (mEvents.TryGetValue(kv, out var e))
            {
                e.As<EasyEvent<T1,T2>>().Trigger(t1,t2);
            }
        }
        public void Send<T,T1,T2,T3>(T key, T1 t1,T2 t2 ,T3 t3) where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);

            if (mEvents.TryGetValue(kv, out var e))
            {
                e.As<EasyEvent<T1,T2,T3>>().Trigger(t1,t2,t3);
            }
        }
        public void Send<T>(T key, params object[] args) where T : IConvertible
        {
            var kv = typeof(T).ToString()+ key.ToInt32(null);

            if (mEvents.TryGetValue(kv, out var e))
            {
                e.As<EasyEvent<string,object[]>>().Trigger(kv,args);
            }
        }

        #endregion

        public void Dispose()
        {
            mEvents.Clear();
        }
    }
}