using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VisimBox.Renderer.RenderObjects;

namespace VisimBox.Renderer
{
    public class Renderer : IRenderer
    {
        protected bool initialized = false;
        protected TextureManager TexMan;
        protected VertexBufferManager _VertexMan;
        protected IndexBufferManager _IndexMan;
        protected MeshManager _MeshMan;
        protected MaterialManager _MaterialMan;
        protected Render2D.FontManager _FontMan;
        protected LightManager _LightMan;

        protected List<IRenderContext> rContexts;

        protected IRenderContext mainContext;

        public IRenderContext MainContext
        {
            get { return mainContext; }
        }


        public Renderer()
        {
            rContexts = new List<IRenderContext>();
        }

        protected void AddContext(IRenderContext ctx)
        {
            if (!rContexts.Contains(ctx))
                rContexts.Add(ctx);
        }


        #region IRenderer Members

        virtual public bool IsIdle()
        {
            return false;
        }

        virtual public void Initialize(RenderContextSettings settings)
        {
            if (initialized)
            {
                return;
            }
            IRenderContext irc = CreateNewContext(settings);
            AddContext(irc);
            mainContext = irc;

            initialized = true;
            _MaterialMan.Add("default", System.Drawing.Color.White);
            VisimBox.Console.WriteLine("Renderer initialized.");
        }

        virtual public IRenderContext AddNewContext(RenderContextSettings settings)
        {
            if (!initialized)
                return null;
            IRenderContext irc = CreateNewContext(settings);
            AddContext(irc);
            return irc;
        }

        /// <summary>
        /// Shuts down selected render context
        /// </summary>
        /// <param name="irc">render context</param>
        public virtual void RemoveContext(IRenderContext irc)
        {
            if (rContexts.Contains(irc))
            {
                rContexts.Remove(irc);
                irc.Dispose();
            }
        }


        virtual protected IRenderContext CreateNewContext(RenderContextSettings settings)
        {
            return null;
        }

        virtual public void StartFrame()
        {
            mainContext.StartFrame();
        }

        virtual public void EndFrame()
        {
            mainContext.EndFrame();
        }

        public void RenderAllContexts()
        {
            foreach (var rc in rContexts)
            {
                rc.RenderFrame();
            }
        }

        public virtual void Close()
        {
            if (!initialized)
                return;
            if (_FontMan != null)
            {
                _FontMan.Dispose();
                _FontMan = null;
            }
            if (_MeshMan != null)
            {
                _MeshMan.Dispose();
                _MeshMan = null;
            }
            if (_VertexMan != null)
            {
                _VertexMan.Dispose();
                _VertexMan = null;
            }
            if (_IndexMan != null)
            {
                _IndexMan.Dispose();
                _IndexMan = null;
            }
            if (_LightMan != null)
            {
                _LightMan.Dispose();
                _LightMan = null;
            }
            if (_MaterialMan != null)
            {
                _MaterialMan.Dispose();
                _MaterialMan = null;
            }
            if (TexMan != null)
            {
                TexMan.Dispose();
                TexMan = null;
            }

            foreach (var rc in rContexts)
            {
                rc.Dispose();
            }
            rContexts = null;

        }

        public TextureManager TextureMan { get { return TexMan; } }
        public VertexBufferManager VertexMan { get { return _VertexMan; } }
        public IndexBufferManager IndexMan { get { return _IndexMan; } }
        public MaterialManager MaterialMan { get { return _MaterialMan; } }
        public Render2D.FontManager FontMan { get { return _FontMan; } }
        public MeshManager MeshMan { get { return _MeshMan; } }
        public LightManager LightMan { get { return _LightMan; } }

        #endregion

        
        #region IDisposable Members

        public virtual void Dispose()
        {
            Close();
        }

        #endregion
    }
}
