using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace VisimBox.Renderer
{
    /// <summary>
    /// Interface for renderer
    /// </summary>
    public interface IRenderer : IDisposable
    {
        #region Managers

        /// <summary>
        /// Texture manager
        /// </summary>
        TextureManager TextureMan { get; }

        /// <summary>
        /// Bitmap font manager
        /// </summary>
        Render2D.FontManager FontMan { get; }

        /// <summary>
        /// Material manager
        /// </summary>
        MaterialManager MaterialMan { get; }

        /// <summary>
        /// Vertex buffer manager
        /// </summary>
        VertexBufferManager VertexMan { get; }

        /// <summary>
        /// Index buffer manager
        /// </summary>
        IndexBufferManager IndexMan { get; }

        /// <summary>
        /// Mesh manager
        /// </summary>
        MeshManager MeshMan { get; }

        /// <summary>
        /// Light manager
        /// </summary>
        LightManager LightMan { get; }


        #endregion

        #region Rendering contexts

        /// <summary>
        /// Main rendering context
        /// </summary>
        IRenderContext MainContext { get; }

        #endregion


        #region Initializing, closing, settings

        /// <summary>
        /// Initializes renderer
        /// </summary>
        /// <param name="settings">Settings for primary render context</param>
        void Initialize(RenderContextSettings settings);

        /// <summary>
        /// Adds another render context
        /// </summary>
        /// <param name="settings">Settings for context</param>
        /// <returns>Pointer to new context</returns>
        IRenderContext AddNewContext(RenderContextSettings settings);

        /// <summary>
        /// Shuts down selected render context
        /// </summary>
        /// <param name="irc">render context</param>
        void RemoveContext(IRenderContext irc);

        /// <summary>
        /// Closes renderer
        /// </summary>
        void Close();

        /// <summary>
        /// Returns true if thread with rendering is idle (any context)
        /// </summary>
        /// <returns></returns>
        bool IsIdle();

        #endregion


        #region Rendering
        /// <summary>
        /// Automatically renders all contexts
        /// </summary>
        void RenderAllContexts();

        /// <summary>
        /// Starts rendering frame on activated context
        /// </summary>
        void StartFrame();

        /// <summary>
        /// Ends rendering frame on activated context (and shows it on screen)
        /// </summary>
        void EndFrame();
        #endregion

    }

    /// <summary>
    /// Event arguments for renderer
    /// </summary>
    public class RendererEventArgs : EventArgs
    {
        /// <summary>
        /// Renderer using event
        /// </summary>
        public IRenderer Renderer;
        /// <summary>
        /// Active render context
        /// </summary>
        public IRenderContext RC;
        
        /// <summary>
        /// Currently used camera
        /// </summary>
        public ICamera Camera;

        /// <summary>
        /// Flags for object types to render
        /// </summary>
        public UInt64 RenderFlags;

        public RendererEventArgs(IRenderer ir, IRenderContext irc, ICamera camera, UInt64 flags = UInt64.MaxValue)
        {
            Renderer = ir;
            RC = irc;
            Camera = camera;
            RenderFlags = flags;
        }
    }

    /// <summary>
    /// Delagate for renderer event declaration 
    /// </summary>
    /// <param name="renderer">Renderer calling event</param>
    /// <param name="e">Argument</param>
    public delegate void RendererEvent(object sender, RendererEventArgs e);
}
