using OpenTK.Graphics.OpenGL;
using Serilog;

namespace Engine.Graphics.Buffer;

public class IndexBuffer : OpenGlObject
{
  internal int Count { get; }

  public IndexBuffer(int parCount, BufferStorageFlags parFlags = BufferStorageFlags.None)
  {
    Count = parCount;

    GL.CreateBuffers(1, out int handle);
    Handle = handle;

    GL.NamedBufferStorage(Handle, Count * sizeof(uint), IntPtr.Zero, parFlags);

    Log.Debug("Index buffer {Handle} created with {Count} elements", Handle, Count);
  }


  public IndexBuffer(uint[] parData, BufferStorageFlags parFlags = BufferStorageFlags.None)
  {
    Count = parData.Length;

    GL.CreateBuffers(1, out int handle);
    Handle = handle;

    GL.NamedBufferStorage(Handle, Count * sizeof(uint), parData, parFlags);

    Log.Debug("Index buffer {Handle} created with {Count} elements", Handle, Count);
  }

  public void UploadData(uint[] parData)
  {
    UploadData(0, parData);
  }

  public void UploadData(int parOffset, uint[] parData)
  {
    if (parOffset < 0)
    {
      throw new ArgumentException("Offset must be greater than 0");
    }

    if (parData.Length + parOffset > Count)
    {
      throw new ArgumentException("Data array is too large");
    }

    GL.NamedBufferSubData(Handle, parOffset, parData.Length * sizeof(uint), parData);
  }

  internal override void Bind()
  {
    GL.BindBuffer(BufferTarget.ElementArrayBuffer, Handle);
  }

  internal override void Unbind()
  {
    GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
  }

  protected override void Destroy()
  {
    GL.DeleteBuffer(Handle);
  }
}