using OpenTK.Graphics.OpenGLES2;


namespace YourNamespaceHere;


public class Shader : IDisposable
{
    int Handle;

    public Shader(string vertexPath, string fragmentPath) {
        
        string VertexShaderSource = File.ReadAllText(vertexPath);
        string FragmentShaderSource = File.ReadAllText(fragmentPath);

        int VertexShader = GL.CreateShader(ShaderType.VertexShader);
        GL.ShaderSource(VertexShader, VertexShaderSource);
        
        int FragmentShader = GL.CreateShader(ShaderType.FragmentShader);
        GL.ShaderSource(FragmentShader, FragmentShaderSource);
        
        GL.CompileShader(VertexShader);
        GL.GetShaderi(VertexShader, ShaderParameterName.CompileStatus, out int success);
        if (success == 0) {
            GL.GetShaderInfoLog(VertexShader, out string output);
            throw new Exception(output);
        }
        
        GL.CompileShader(FragmentShader);
        GL.GetShaderi(FragmentShader, ShaderParameterName.CompileStatus, out int success1);
        if (success1 == 0) {
            GL.GetShaderInfoLog(VertexShader, out string output);
            throw new Exception(output);
        }
        
        Handle = GL.CreateProgram();

        GL.AttachShader(Handle, VertexShader);
        GL.AttachShader(Handle, FragmentShader);

        GL.LinkProgram(Handle);

        GL.GetProgrami(Handle, ProgramProperty.LinkStatus, out int success3);
        if (success3 == 0)
        {
            GL.GetProgramInfoLog(Handle, out string infoLog);
            Console.WriteLine(infoLog);
        }
        
        GL.DetachShader(Handle, VertexShader);
        GL.DetachShader(Handle, FragmentShader);
        GL.DeleteShader(FragmentShader);
        GL.DeleteShader(VertexShader);
    }
    
    public void Use()
    {
        GL.UseProgram(Handle);
    }
    
    private bool disposedValue = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            GL.DeleteProgram(Handle);

            disposedValue = true;
        }
    }
    
    ~Shader()
    {
        if (disposedValue == false)
        {
            Console.WriteLine("GPU Resource leak! Did you forget to call Dispose()?");
        }
    }
    
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}