using Engine.Graphics.Framebuffer;
using Engine.Graphics.Pixel;
using OpenTK.Graphics.OpenGL;
using Serilog;

namespace Engine.Graphics.Texture;

public class DynamicTexture : Texture, IFramebufferAttachment
{
  private readonly PixelFormat _format;
  private readonly PixelType _type;
  private readonly PixelInternalFormat _internalFormat;

  internal DynamicTexture(int parWidth, int parHeight, PixelFormat parFormat, PixelType parType,
    PixelInternalFormat parInternalFormat)
    : base(parWidth, parHeight)
  {
    _format = parFormat;
    _type = parType;
    _internalFormat = parInternalFormat;

    GL.BindTexture(TextureTarget.Texture2D, Handle);
    GL.TexImage2D(TextureTarget.Texture2D, 0, _internalFormat, Width, Height, 0, _format, _type,
      IntPtr.Zero);
  }

  public static DynamicTexture Create<T>(int parWidth, int parHeight)
    where T : struct, IPixel
  {
    var pixel = default(T);
    return new DynamicTexture(parWidth, parHeight, pixel.Format, pixel.Type, pixel.InternalFormat);
  }

  public void Resize(int parWidth, int parHeight)
  {
    if (Width == parWidth && Height == parHeight)
    {
      return;
    }

    Width = parWidth;
    Height = parHeight;

    Bind();
    GL.TexImage2D(TextureTarget.Texture2D, 0, _internalFormat, Width, Height, 0, _format, _type,
      IntPtr.Zero);

    Log.Debug("Texture {Handle} resized to {Width}x{Height}", Handle, Width, Height);
  }

  public void Attach(Framebuffer.Framebuffer parFramebuffer, FramebufferAttachment parAttachment)
  {
    GL.NamedFramebufferTexture(parFramebuffer.Handle, parAttachment, Handle, 0);
  }
}