using System;
using MTV3D65;

namespace ComponentFramework.Modules
{
    /// <summary>
    /// The base class for both <see cref="Service"/>s and <see cref="Component"/>s.
    /// Provides the basic TV3D singleton services, a reference to the <see cref="ICore"/>
    /// and a callback for initialization and updating.
    /// </summary>
    public abstract class Module : IDisposable
    {
        /// <summary>
        /// Protected parameterized constructor. Initializes the TV3D singletons.
        /// </summary>
        /// <param name="core">The core interface used to load this module.</param>
        protected Module(ICore core) 
        {
            Atmosphere = new TVAtmosphere();
            CameraFactory = new TVCameraFactory();
            Globals = new TVGlobals();
            InputEngine = new TVInputEngine();
            InternalObjects = new TVInternalObjects();
            LightEngine = new TVLightEngine();
            InternalObjects = new TVInternalObjects();
            LightEngine = new TVLightEngine();
            MathLibrary = new TVMathLibrary();
            Physics = new TVPhysics();
            Scene = new TVScene();
            Screen2DImmediate = new TVScreen2DImmediate();
            Screen2DText = new TVScreen2DText();
            TextureFactory = new TVTextureFactory();
            MaterialFactory = new TVMaterialFactory();
            GameControllers = new TVGameControllers();
            DeviceInfo = new TVDeviceInfo();

            Core = core;
        }

        /// <summary>
        /// Initializes this module. The base implementation should be called by
        /// overriding implementations.
        /// </summary>
        public virtual void Initialize() 
        {
            Initialized = true;
        }

        /// <summary>
        /// Performs update of game logic and non-rendering-related operations.
        /// </summary>
        /// <param name="elapsedTime">The time elapsed since the last update.</param>
        public virtual void Update(TimeSpan elapsedTime) { }

        /// <summary>
        /// Is this module initialized?
        /// </summary>
        public bool Initialized { get; private set; }

        /// <summary>A reference to the <see cref="TVAtmosphere"/> singleton.</summary>
        protected TVAtmosphere Atmosphere { get; private set; }
        /// <summary>A reference to the <see cref="TVCameraFactory"/> singleton.</summary>
        protected TVCameraFactory CameraFactory { get; private set; }
        /// <summary>A reference to the <see cref="TVGlobals"/> singleton.</summary>
        protected TVGlobals Globals { get; private set; }
        /// <summary>A reference to the <see cref="TVInputEngine"/> singleton.</summary>
        protected TVInputEngine InputEngine { get; private set; }
        /// <summary>A reference to the <see cref="TVInternalObjects"/> singleton.</summary>
        protected TVInternalObjects InternalObjects { get; private set; }
        /// <summary>A reference to the <see cref="TVLightEngine"/> singleton.</summary>
        protected TVLightEngine LightEngine { get; private set; }
        /// <summary>A reference to the <see cref="TVMathLibrary"/> singleton.</summary>
        protected TVMathLibrary MathLibrary { get; private set; }
        /// <summary>A reference to the <see cref="TVPhysics"/> singleton.</summary>
        protected TVPhysics Physics { get; private set; }
        /// <summary>A reference to the <see cref="TVScene"/> singleton.</summary>
        protected TVScene Scene { get; private set; }
        /// <summary>A reference to the <see cref="TVScreen2DImmediate"/> singleton.</summary>
        protected TVScreen2DImmediate Screen2DImmediate { get; private set; }
        /// <summary>A reference to the <see cref="TVScreen2DText"/> singleton.</summary>
        protected TVScreen2DText Screen2DText { get; private set; }
        /// <summary>A reference to the <see cref="TVTextureFactory"/> singleton.</summary>
        protected TVTextureFactory TextureFactory { get; private set; }
        /// <summary>A reference to the <see cref="TVMaterialFactory"/> singleton.</summary>
        protected TVMaterialFactory MaterialFactory { get; private set; }
        /// <summary>A reference to the <see cref="TVGameControllers"/> singleton.</summary>
        protected TVGameControllers GameControllers { get; private set; }
        /// <summary>A reference to the <see cref="TVDeviceInfo"/> singleton.</summary>
        protected TVDeviceInfo DeviceInfo { get; private set; }

        /// <summary>
        /// A reference to the core interface used to loaded this module.
        /// </summary>
        protected ICore Core { get; private set; }

        /// <summary>
        /// Does the actual dispose operation, as per the Dispose .NET pattern.
        /// </summary>
        protected virtual void DisposeInternal()
        {
        }

        ///<summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            DisposeInternal();
            GC.SuppressFinalize(this);
            Disposed = true;
        }

        /// <summary>
        /// Whether this component is disposed.
        /// </summary>
        public bool Disposed { get; private set; }
    }
}