using System;

namespace Stary.Evo
{
    public interface IArchitecture
    {
        /// <summary>
        /// 注册 System
        /// </summary>
        void RegisterSystem<T>(T instance) where T : ISystem;

        /// <summary>
        /// 获取 System
        /// </summary>
        T GetSystem<T>() where T : class, ISystem;


        /// <summary>
        /// 注册 Data
        /// </summary>
        void RegisterData<T>(T instance) where T : IData;

        /// <summary>
        /// 获取 Data
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        T GetData<T>() where T : class, IData;


        /// <summary>
        /// 注册 Utility
        /// </summary>
        void RegisterUtility<T>(T instance) where T : IUtility;

        /// <summary>
        /// 获取 Utility
        /// </summary>
        T GetUtility<T>() where T : class, IUtility;


        /// <summary>
        /// 发送命令
        /// </summary>
        void SendCommand<T>() where T : ICommand, new();

        /// <summary>
        /// 发送命令
        /// </summary>
        void SendCommand<T>(T command) where T : ICommand;

        /// <summary>
        /// 事件发送
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public void SendEvent<TEvent>(TEvent key) where TEvent : IConvertible;

        /// <summary>
        /// 事件发送
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public void SendEvent<TEvent, Tvalue1>(TEvent key, Tvalue1 value) where TEvent : IConvertible;

        /// <summary>
        /// 事件发送
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public void SendEvent<TEvent, Tvalue1, Tvalue2>(TEvent key, Tvalue1 value1, Tvalue2 value2)
            where TEvent : IConvertible;

        /// <summary>
        /// 事件发送
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public void SendEvent<TEvent, Tvlue1, Tvlue2, Tvlue3>(TEvent key, Tvlue1 value1, Tvlue2 vlue2, Tvlue3 vlue3)
            where TEvent : IConvertible;

        /// <summary>
        /// 事件发送
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public void SendEvent<TEvent>(TEvent key, object[] values) where TEvent : IConvertible;

        /// <summary>
        /// 事件监听
        /// </summary>
        /// <param name="onEvent"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IUnRegister RegisterEvent<TEvent>(TEvent key, Action onEvent) where TEvent : IConvertible;

        /// <summary>
        /// 事件监听
        /// </summary>
        /// <param name="onEvent"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IUnRegister RegisterEvent<TEvent, Tvalue1>(TEvent key, Action<Tvalue1> onEvent)
            where TEvent : IConvertible;

        /// <summary>
        /// 事件监听
        /// </summary>
        /// <param name="onEvent"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IUnRegister RegisterEvent<TEvent, Tvalue1, Tvalue2>(TEvent key, Action<Tvalue1, Tvalue2> onEvent)
            where TEvent : IConvertible;

        /// <summary>
        /// 事件监听
        /// </summary>
        /// <param name="onEvent"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IUnRegister RegisterEvent<TEvent, Tvlue1, Tvlue2, Tvlue3>(TEvent key,
            Action<Tvlue1, Tvlue2, Tvlue3> onEvent) where TEvent : IConvertible;

        /// <summary>
        /// 事件监听
        /// </summary>
        /// <param name="onEvent"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IUnRegister RegisterEvent<TEvent>(TEvent key, Action<object[]> onEvent) where TEvent : IConvertible;

        /// <summary>
        /// 事件销毁
        /// </summary>
        /// <param name="onEvent"></param>
        /// <typeparam name="T"></typeparam>
        public void UnRegisterEvent<TEvent>(TEvent key, Action onEvent) where TEvent : IConvertible;

        /// <summary>
        /// 事件销毁
        /// </summary>
        /// <param name="onEvent"></param>
        /// <typeparam name="T"></typeparam>
        public void UnRegisterEvent<TEvent, Tvalue1>(TEvent key, Action<Tvalue1> onEvent) where TEvent : IConvertible;

        /// <summary>
        /// 事件销毁
        /// </summary>
        /// <param name="onEvent"></param>
        /// <typeparam name="T"></typeparam>
        public void UnRegisterEvent<TEvent, Tvalue1, Tvalue2>(TEvent key, Action<Tvalue1, Tvalue2> onEvent)
            where TEvent : IConvertible;

        /// <summary>
        /// 事件销毁
        /// </summary>
        /// <param name="onEvent"></param>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TEvent"></typeparam>
        /// <typeparam name="TVlue1"></typeparam>
        /// <typeparam name="Tvlue2"></typeparam>
        /// <typeparam name="Tvlue3"></typeparam>
        public void UnRegisterEvent<TEvent, Tvlue1, Tvlue2, Tvlue3>(TEvent key, Action<Tvlue1, Tvlue2, Tvlue3> onEvent)
            where TEvent : IConvertible;

        /// <summary>
        /// 事件销毁
        /// </summary>
        /// <param name="key"></param>
        /// <param name="onEvent"></param>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TEvent"></typeparam>
        public void UnRegisterEvent<TEvent>(TEvent key, Action<object[]> onEvent) where TEvent : IConvertible;


        TResult SendQuery<TResult>(IQuery<TResult> query);
    }
}