﻿using System.Text;
using _2DeepEngine.Graphics;

namespace _2DeepEngine.Platform
{
    public sealed class GLShaderBundle : ShaderBundle
    {
        public readonly uint Handle;

        public unsafe GLShaderBundle(IShader vertexShader, IShader geometryShader, IShader pixelShader)
        {
            Handle = OpenGL.CreateProgram();

            OpenGL.AttachShader(Handle, ((GLShader) vertexShader).Handle);
            OpenGL.AttachShader(Handle, ((GLShader) pixelShader).Handle);
            if (geometryShader != null)
                OpenGL.AttachShader(Handle, ((GLShader) geometryShader).Handle);
            OpenGL.LinkProgram(Handle);
            
            vertexShader.Dispose();
            pixelShader.Dispose();
            geometryShader?.Dispose();

            int status;
            OpenGL.GetProgramiv(Handle, OpenGL.Enums.LinkStatus, &status);
            if (status != 0) return;

            int length;
            OpenGL.GetProgramiv(Handle, OpenGL.Enums.InfoLogLength, &length);
            var log = new byte[length];
            fixed (byte* ptr = &log[0])
            {
                OpenGL.GetProgramInfoLog(Handle, length, (int*) 0, ptr);
            }
            throw new PlatformException(Encoding.ASCII.GetString(log));
        }

        public override void Bind()
        {
            OpenGL.UseProgram(Handle);
        }

        public override void Unbind()
        {
            OpenGL.UseProgram(0);
        }
    }
}