using FL.FGUI;
using FL.Map;
using FL.Nodes;
using System;
using System.Collections.Generic;
using XGame;
using XGame.Framework;
using XGame.Framework.FGUI;
using XGame.Framework.Interfaces;
using XGame.Framework.Map;
using XGame.Framework.Nodes;
using XGame.Framework.Quality;
using XGame.Framework.Time;
using XGame.Framework.UI;

namespace FL.Launch
{
    public class FLGameLogic : IGameLogic
    {
        #region 接口实现

        private ITimeModule _timeModule;
        private IMapModule _mapModule;
        private IUIModule _uiModule;
        private INodeTree _nodeTree;
        /// <summary>
        /// 按照Map、UI、NodeTree的顺序刷新
        /// </summary>
        private List<IUpdate> _updates;
        /// <summary>
        /// 按照Map、UI、NodeTree的顺序刷新
        /// </summary>
        private List<ILateUpdate> _lateUpdates;

        void IGameLogic.Init()
        {
            Log.Debug("FLGameLogic.Init");
            InitModules();
            InitUpdates();
        }

        void IGameLogic.Start()
        {
            Log.Debug("FLGameLogic.Start");
            var appNode = _nodeTree.Root as FLAppNode;
            var async = appNode.LoadAsync();
            async.On(_ =>
            {
                appNode.Enable();
                if (_nodeTree is IUpdate nodeUpdate)
                {
                    _updates.Add(nodeUpdate);
                }
                if (_nodeTree is ILateUpdate nodeLateUpdate)
                {
                    _lateUpdates.Add(nodeLateUpdate);
                }
            });
        }

        void IGameLogic.Update(int millisecond)
        {
            foreach (var update in _updates)
            {
                update?.Update(millisecond);
            }
        }
        void IGameLogic.LateUpdate(int millisecond)
        {
            foreach (var lateUpdate in _lateUpdates)
            {
                lateUpdate?.LateUpdate(millisecond);
            }
        }
        void IGameLogic.Dispose()
        {
            Log.Debug("FLGameLogic.Dispose");
            _updates.Clear();
            _lateUpdates.Clear();
            EventSingle.Dispose();
            UIKeys.Dispose();
            UINestedKeys.Dispose();
            MapKeys.Dispose();
            (_timeModule as IDisposable)?.Dispose();
            (_mapModule as IDisposable)?.Dispose();
            (_uiModule as IDisposable)?.Dispose();
            (_nodeTree as IDisposable)?.Dispose();
        }
        #endregion

        private void InitModules()
        {
            var qualityModule = new QualityModule();
            var timeModule = new TimeModule();
            timeModule.Initialize();
            _timeModule = timeModule;
            //UI
            var uiBuilder = new FguiModuleBuilder();
            uiBuilder.Build(qualityModule, _timeModule);
            _uiModule = uiBuilder.Product;
            //Map
            var mapBuilder = new MapModuleBuilder();
            mapBuilder.Build(qualityModule, timeModule, _uiModule);
            _mapModule = mapBuilder.Product;
            //NodeTree
            var nodeBuild = new NodeTreeBuilder();
            nodeBuild.Build(qualityModule, timeModule, _uiModule, _mapModule, typeof(FLAppNode));
            _nodeTree = nodeBuild.Product;
        }
        private void InitUpdates()
        {
            _updates = new List<IUpdate>();
            _lateUpdates = new List<ILateUpdate>();
            if (_mapModule is IUpdate mapUpdate)
            {
                _updates.Add(mapUpdate);
            }
            if (_mapModule is ILateUpdate mapLateUpdate)
            {
                _lateUpdates.Add(mapLateUpdate);
            }
            if (_uiModule is IUpdate uiUpdate)
            {
                _updates.Add(uiUpdate);
            }
            if (_uiModule is ILateUpdate uiLateUpdate)
            {
                _lateUpdates.Add(uiLateUpdate);
            }
        }
    }
}

