using System;
using System.Collections.Generic;
using ComponentFramework.Modules;
using MTV3D65;

namespace ComponentFramework
{
    /// <summary>
    /// The public interface for the <see cref="Core"/> class.
    /// </summary>
    public interface ICore
    {
        /// <summary>
        /// Switches the rendering from windowed mode to fullscreen mode.
        /// </summary>
        void SwitchWindowed();

        /// <summary>
        /// Switches the rendering from fullscreen mode to windowed mode.
        /// </summary>
        void SwitchFullscreen();

        /// <summary>
        /// Gets the singleton service reference from an interface type.
        /// </summary>
        /// <typeparam name="T">The interface type to search for</typeparam>
        /// <returns>The matching service implementation</returns>
        /// <exception cref="KeyNotFoundException">If the service cannot be found</exception>
        T GetService<T>() where T : IService;

        /// <summary>
        /// Injects service dependencies into a module (or any class that has service dependencies).
        /// </summary>
        /// <param name="module">The module to process</param>
        void InjectServices(object module);

        /// <summary>
        /// Creates a component from a type and loads it.
        /// </summary>
        /// <typeparam name="T">The component type to create</typeparam>
        /// <returns>The created, loaded but not yet initialized component</returns>
        T CreateAndLoadComponent<T>() where T : Component;

        /// <summary>
        /// Creates a component from a type and loads it.
        /// </summary>
        /// <param name="componentType">The component type to create</param>
        /// <returns>The created, loaded but not yet initialized component</returns>
        Component CreateAndLoadComponent(Type componentType);

        /// <summary>
        /// Loads an already-instantiated component. 
        /// The initialization is deferred to the next loop.
        /// </summary>
        /// <param name="component">The component to load</param>
        void LoadComponent(Component component);

        /// <summary>
        /// Unloads a component, which schedules its removal and dispose.
        /// </summary>
        /// <param name="component">The component to remove</param>
        void UnloadComponent(Component component);

        /// <summary>
        /// Re-calls the <see cref="Component.Draw()"/> method of all loaded components.
        /// </summary>
        void ReDraw();

        /// <summary>
        /// Stops looping and exits the application.
        /// </summary>
        void Exit();

        /// <summary>
        /// Provides access to the only <see cref="TVEngine"/> reference.
        /// </summary>
        TVEngine Engine { get; }

        /// <summary>
        /// Provides access to the engine initialization settings.
        /// </summary>
        EngineSettings Settings { get; }
    }
}
