using System;
using XGame.Framework.Asset;
using XGame.Framework.Map;
using XGame.Framework.Quality;
using XGame.Framework.Time;
using XGame.Framework.UI;

namespace XGame.Framework.Nodes
{
    /// <summary>
    /// 每个NodeGroup一个Context
    /// </summary>
    public sealed class NodeContext : IDisposable, INodeTreeSetter
    {
        public IQualityModule Quality { get; private set; }
        private ITimeModule _timeModule;
        private ITimeProxy _timeProxy;
        public ITimeProxy Time => _timeProxy ?? (_timeProxy = new TimeProxy(_timeModule));
        public IUIModule UI { get; private set; }
        public IMapModule Map { get; private set; }
        /// <summary>
        /// 资源加载模块，需要时才创建
        /// </summary>
        private IAssetModule _asset;
        /// <summary>
        /// 资源加载模块，需要时才创建
        /// </summary>
        public IAssetModule Asset => _asset ?? (_asset = new AssetModule());
        /// <summary>
        /// NodeTree
        /// </summary>
        public INodeTree Tree { get; private set; }
        INodeTree INodeTreeSetter.NodeTree { set => Tree = value; }

        public NodeContext(IQualityModule qualityModule, ITimeModule timeModule, IUIModule uiModule, IMapModule mapModule)
        {
            Quality = qualityModule;
            _timeModule = timeModule;
            UI = uiModule;
            Map = mapModule;
        }
        public NodeContext Clone()
        {
            var context = new NodeContext(Quality, _timeModule, UI, Map);
            (context as INodeTreeSetter).NodeTree = Tree;
            return context;
        }
        /// <summary>
        /// 取消定时器、清理资源加载监听等
        /// </summary>
        public void Clear()
        {
            _timeProxy?.CancelAll();
            _asset?.StopAllAsyncs();
        }
        void IDisposable.Dispose()
        {
            Quality = null;
            UI = null;
            _timeModule = null;
            _timeProxy?.CancelAll();
            _timeProxy = null;
            (_asset as IDisposable)?.Dispose();
            _asset = null;
        }
    }
}
