using System;
using XGame.Framework.Components;
using XGame.Framework.Interfaces;
using XGame.Framework.ObjectCollection;

namespace XGame.Framework.Map
{
    /// <summary>
    /// Map实例
    /// </summary>
    public abstract class MapView<TViewModel> : IMapView, IMapContextSetter, IDisposable where TViewModel : class, IMapViewModel
    {
        private MapContext _context;
        public MapContext Context => _context;

        private MapBehaviour _behaviour;
        private TViewModel _viewModel;
        public TViewModel VM => _viewModel;
        private ComponentGroup _componentGroup;
        
        #region 接口实现
        MapContext IMapContextSetter.Context { set => _context = value; }
        MapBehaviour IMapView.Behaviour 
        {
            get => _behaviour;
            set
            {
                _behaviour = value;
                _viewModel = CtreatViewModel(value.Collector);
                _componentGroup = new ComponentGroup(this);
                AddComponent(_componentGroup);
            }
        }
        public bool Active { get; private set; }

        void IMapView.Enable(object intent)
        {
            if (Active) return;
            Active = true;
            _behaviour.gameObject.SetActive(true);
            _componentGroup.Enable(intent);
        }

        void IMapView.Disable()
        {
            if (!Active) return;
            Active = false;
            _behaviour.gameObject.SetActive(false);
            _componentGroup.Disable();
            _context.Clear();
        }

        void IUpdate.Update(int millisecond)
        {
            if (!Active) return;
            _componentGroup.Update(millisecond);    
        }

        void ILateUpdate.LateUpdate(int millisecond)
        {
            if (!Active) return;
            _componentGroup.LateUpdate(millisecond);
        }
        void IDisposable.Dispose()
        {
            OnDispose();
            _componentGroup.Dispose();
            _behaviour = null;
            (_context as IDisposable)?.Dispose();
            _context = null;
            _viewModel = null;
        }
        #endregion
        protected TComponent GetComponent<TComponent>() where TComponent : class, IComponent
        {
            return _componentGroup.Get<TComponent>();
        }

        protected abstract TViewModel CtreatViewModel(IObjectCollector collector);
        protected abstract void AddComponent(IComponentGroup group);

        protected abstract void OnDispose();
    }
}