using System;
using XGame.Framework.Asyncs;
using XGame.Framework.Data;
using XGame.Framework.Interfaces;
using XGame.Framework.Loadable;

namespace XGame.Framework.Nodes
{
    /// <summary>
    /// Node节点
    /// 激活: LoadAsync->Enable
    /// 隐藏: Disable->UnloadAsync
    /// </summary>
    public abstract class Node : AsyncLoadable, INode, IUpdate, ILateUpdate, IDisposable
    {
        #region 接口实现
        public bool Active { get; protected set; }
        public NodeContext Context { get; private set; }
        private DataGroup _dataGroup;
        private NodeComponentGroup _componentGroup;
        public void Init(NodeContext context)
        {
            Context = context;
            _dataGroup = new DataGroup();
            _componentGroup = new NodeComponentGroup(Context);
            AddData(_dataGroup);
            AddComponent(_componentGroup);
            OnInited();
        }
        public void Enable(object intent = null)
        {
            if (Active) return;
            if (State != LoadState.Loaded) return;

            Active = true;
            _componentGroup.Enable(intent);
        }

        public void Disable()
        {
            if (!Active) return;
            if (State != LoadState.Loaded) return;
            Active = false;
            _componentGroup.Disable();
        }
        public void Update(int millisecond)
        {
            if (!Active) return;
            _componentGroup.Update(millisecond);
        }
        public void LateUpdate(int millisecond)
        {
            if (!Active) return;
            _componentGroup.LateUpdate(millisecond);
        }
        void IDisposable.Dispose()
        {
            OnDispose();
            ClearAsyncs();
            _componentGroup.Dispose();
            //(Context as IDisposable).Dispose();
        }
        #endregion

        protected override void OnLoadAsync(IAsyncGroup group)
        {
            _dataGroup.OnLoadAsync(group);
            _componentGroup.OnLoadAsync(group);
        }
        protected override void OnUnloadAsync(IAsyncGroup group)
        {
            _dataGroup.OnUnloadAsync(group);
            _componentGroup.OnUnloadAsync(group);
        }
        protected abstract void AddData(IDataGroup group);
        protected abstract void AddComponent(INodeComponentGroup group);

        protected abstract void OnInited();
        protected abstract void OnDispose();
    }

}
