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

namespace VisimBox.Renderer
{
    public interface IIndexBuffer : IHWBuffer<int>
    {
    }

    /*
    public interface IIndexBuffer : IResource
    {
        /// <summary>
        /// Internal ID for the index buffer
        /// </summary>
        uint InternalID { get; }

        /// <summary>
        /// If cached, index buffer will keep uint[] copy of the data in the system memory.
        /// All user read / write operations will be routed to cached copy. 
        /// Use ReadCache / WriteCache to update indexbuffer
        /// </summary>
        bool Cached { get; set; }

        /// <summary>
        /// Reference to uint[] used as cache
        /// </summary>
        uint[] Cache { get; }

        /// <summary>
        /// Reads content of the index buffer to cache
        /// </summary>
        void ReadCache();

        /// <summary>
        /// Reads part of the index buffer to cache
        /// </summary>
        /// <param name="start">starting index</param>
        /// <param name="count">number of vertex to be read from the VBO</param>
        void ReadCache(int start, int count);

        /// <summary>
        /// Writes content of the cache to index buffer
        /// </summary>
        void WriteCache();

        /// <summary>
        /// Writes content of the cache to index buffer
        /// </summary>
        /// <param name="start">starting index</param>
        /// <param name="count">number of vertex to be written to the VBO</param>
        void WriteCache(int start, int count);
    }
    */
    
    /// <summary>
    /// Abstract base for index buffer, storing indices for elements
    /// </summary>
    public abstract class IndexBuffer : HWBuffer<int>, IIndexBuffer
    {

        protected IndexBuffer(int count, bool cache, ResourceUsage usage) : base(count, cache, usage)
        {
        }

        protected IndexBuffer(int[] indices, bool cache, ResourceUsage usage)
            : base(indices, cache, usage)
        {
        }

        public override ResourceType ResourceType
        {
            get { return Resources.ResourceType.IndexBuffer; }
        }

        public abstract void BindBuffer();

    }


    /// <summary>
    /// Abstract base manager for index buffers
    /// </summary>
    public abstract class IndexBufferManager : AbstractResMan<IIndexBuffer>
    {

        /// <summary>
        /// Adds new already created index buffer to manager (use CreateBuffer to get correct index buffer!)
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">Valid index buffer</param>
        public override void Add(string key, IIndexBuffer value)
        {
            base.Add(key, value);
        }

        /// <summary>
        /// Creates new index buffer from int array
        /// </summary>
        /// <param name="key"></param>
        /// <param name="indices">indices containing data for indexbuffer</param>
        public virtual void Add(string key, int[] indices, ResourceUsage usage = ResourceUsage.Static)
        {
            IIndexBuffer ivb = CreateBuffer(indices, usage);
            Add(key, ivb);
        }

        public abstract IIndexBuffer CreateBuffer(int[] indices, ResourceUsage usage = ResourceUsage.Static);

        /// <summary>
        /// Binds index buffer for using in renderer
        /// </summary>
        /// <param name="name">Name of the buffer</param>
        public virtual void BindBuffer(string name)
        {
            if (!resources.ContainsKey(name))
            {
                Console.DebugLine(string.Format("IndexBuffer {0} not found", name));
                return;
            }
            BindBuffer(this[name]);
        }

        /// <summary>
        /// Binds index buffer for using in renderer
        /// </summary>
        /// <param name="vb">indexBuffer object</param>
        public abstract void BindBuffer(IIndexBuffer vb);

        /// <summary>
        /// Unbinds buffer - sets current index buffer to null
        /// </summary>
        public abstract void UnBindBuffer();
    }

}
