using System;
using Microsoft.DirectX.Direct3D;
using MTV3D65;

namespace ComponentFramework.Modules
{
    /// <summary>
    /// A module with rendering support and render-order awareness.
    /// </summary>
    public abstract class Component : Module, IComparable<Component>, IDisposable
    {
        /// <summary>
        /// Protected parameterized constructor. Initializes the graphics device reference.
        /// </summary>
        /// <param name="core">The core interface used to load this component.</param>
        protected Component(ICore core) : base(core) 
        {
            GraphicsDevice = new Device(InternalObjects.GetDevice3D());
        }

        /// <summary>
        /// Performs pre-drawing operations. 
        /// This method is called before <see cref="TVEngine.Clear()"/>.
        /// </summary>
        public virtual void PreDraw() { }
        /// <summary>
        /// Performs drawing operations. 
        /// This method is called between <see cref="TVEngine.Clear()"/> and <see cref="TVEngine.RenderToScreen()"/>.
        /// </summary>
        public virtual void Draw() { }
        /// <summary>
        /// Performs post-drawing operations. 
        /// This method is called after <see cref="TVEngine.RenderToScreen()"/>.
        /// </summary>
        public virtual void PostDraw() { }

        /// <summary>
        /// The render (and update) order of this component among other components.
        /// Its value should not change during the component's lifetime.
        /// The default implementation returns 0.
        /// </summary>
        /// TODO : Allow change of the render order
        public virtual int Order
        {
            get { return 0; }
        }

        /// <summary>
        /// Compares the current object with another object of the same type.
        /// </summary>
        /// <returns>
        /// A 32-bit signed integer that indicates the relative order of the objects being compared. 
        /// The return value has the following meanings: 
        /// Value Meaning Less than zero This object is less than the <paramref name="other" /> parameter.
        /// Zero This object is equal to <paramref name="other" />. 
        /// Greater than zero This object is greater than <paramref name="other" />. 
        /// </returns>
        /// <param name="other">An object to compare with this object.</param>
        public int CompareTo(Component other)
        {
            return Order - other.Order;
        }

        /// <summary>
        /// The Managed DirectX graphics device reference.
        /// </summary>
        protected Device GraphicsDevice { get; private set; }

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

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

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