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

using Svelto.ECS;

using GamecraftModdingAPI.Utility;

namespace GamecraftModdingAPI.Events
{
    /// <summary>
    /// Keeps track of event handlers and emitters.
    /// This is used to add, remove and get API event handlers and emitters.
    /// </summary>
    public static class EventManager
    {
        private static Dictionary<string, IEventEmitterEngine> _eventEmitters = new Dictionary<string, IEventEmitterEngine>();

        private static Dictionary<string, IEventHandlerEngine> _eventHandlers = new Dictionary<string, IEventHandlerEngine>();

        // event handler management
        
        public static void AddEventHandler(IEventHandlerEngine engine)
        {
            _eventHandlers[engine.Name] = engine;
        }

        public static bool ExistsEventHandler(string name)
        {
            return _eventHandlers.ContainsKey(name);
        }

        public static bool ExistsEventHandler(IEventHandlerEngine engine)
        {
            return ExistsEventHandler(engine.Name);
        }

        public static IEventHandlerEngine GetEventHandler(string name)
        {
            return _eventHandlers[name];
        }

        public static string[] GetEventHandlerNames()
        {
            return _eventHandlers.Keys.ToArray();
        }

        public static void RemoveEventHandler(string name)
        {
            _eventHandlers.Remove(name);
        }

        // event emitter management

        public static void AddEventEmitter(IEventEmitterEngine engine)
        {
            _eventEmitters[engine.Name] = engine;
        }

        public static bool ExistsEventEmitter(string name)
        {
            return _eventEmitters.ContainsKey(name);
        }

        public static bool ExistsEventEmitter(IEventEmitterEngine engine)
        {
            return ExistsEventEmitter(engine.Name);
        }

        public static IEventEmitterEngine GetEventEmitter(string name)
        {
            return _eventEmitters[name];
        }

        public static string[] GetEventEmitterNames()
        {
            return _eventEmitters.Keys.ToArray();
        }

        public static void RemoveEventEmitter(string name)
        {
            if (_eventEmitters[name].isRemovable)
            {
                _eventEmitters.Remove(name);
            }
        }

        public static void RegisterEngines(EnginesRoot enginesRoot)
        {
            // Register handlers before emitters so no events are missed
            var entityFactory = enginesRoot.GenerateEntityFactory();
            foreach (var key in _eventHandlers.Keys)
            {
                Logging.MetaDebugLog($"Registering IEventHandlerEngine {_eventHandlers[key].Name}");
                enginesRoot.AddEngine(_eventHandlers[key]);
            }
            foreach (var key in _eventEmitters.Keys)
            {
                Logging.MetaDebugLog($"Registering IEventEmitterEngine {_eventEmitters[key].Name}");
                _eventEmitters[key].Factory = entityFactory;
                enginesRoot.AddEngine(_eventEmitters[key]);
            }
        }
    }
}