using System.Runtime.InteropServices;
using Bindings.ObjectiveC;
using static Bindings.ObjectiveC.ObjectiveCRuntime;

namespace Bindings.Metal;

[StructLayout(LayoutKind.Sequential)]
public struct MTLRenderPipelineDescriptor
{
    public readonly nint NativePtr;

    public MTLRenderPipelineDescriptor(nint ptr) => NativePtr = ptr;

    public static MTLRenderPipelineDescriptor New()
    {
        var cls = new ObjCClass("MTLRenderPipelineDescriptor");
        var ret = cls.AllocInit<MTLRenderPipelineDescriptor>();
        return ret;
    }

    public void Release() => release(NativePtr);

    public MTLFunction vertexFunction
    {
        get => objc_msgSend<MTLFunction>(NativePtr, sel_vertexFunction);
        set => objc_msgSend(NativePtr, sel_setVertexFunction, value.NativePtr);
    }

    public MTLFunction fragmentFunction
    {
        get => objc_msgSend<MTLFunction>(NativePtr, sel_fragmentFunction);
        set => objc_msgSend(NativePtr, sel_setFragmentFunction, value.NativePtr);
    }

    public MTLRenderPipelineColorAttachmentDescriptorArray colorAttachments
        => objc_msgSend<MTLRenderPipelineColorAttachmentDescriptorArray>(NativePtr, sel_colorAttachments);

    public MTLPixelFormat depthAttachmentPixelFormat
    {
        get => (MTLPixelFormat)uint_objc_msgSend(NativePtr, sel_depthAttachmentPixelFormat);
        set => objc_msgSend(NativePtr, sel_setDepthAttachmentPixelFormat, (uint)value);
    }

    public MTLPixelFormat stencilAttachmentPixelFormat
    {
        get => (MTLPixelFormat)uint_objc_msgSend(NativePtr, sel_stencilAttachmentPixelFormat);
        set => objc_msgSend(NativePtr, sel_setStencilAttachmentPixelFormat, (uint)value);
    }

    public nuint sampleCount
    {
        get => UIntPtr_objc_msgSend(NativePtr, sel_sampleCount);
        set => objc_msgSend(NativePtr, sel_setSampleCount, value);
    }

    public MTLVertexDescriptor vertexDescriptor => objc_msgSend<MTLVertexDescriptor>(NativePtr, sel_vertexDescriptor);

    public Bool8 alphaToCoverageEnabled
    {
        get => bool8_objc_msgSend(NativePtr, sel_isAlphaToCoverageEnabled);
        set => objc_msgSend(NativePtr, sel_setAlphaToCoverageEnabled, value);
    }

    private static readonly Selector sel_vertexFunction = "vertexFunction";
    private static readonly Selector sel_setVertexFunction = "setVertexFunction:";
    private static readonly Selector sel_fragmentFunction = "fragmentFunction";
    private static readonly Selector sel_setFragmentFunction = "setFragmentFunction:";
    private static readonly Selector sel_colorAttachments = "colorAttachments";
    private static readonly Selector sel_depthAttachmentPixelFormat = "depthAttachmentPixelFormat";
    private static readonly Selector sel_setDepthAttachmentPixelFormat = "setDepthAttachmentPixelFormat:";
    private static readonly Selector sel_stencilAttachmentPixelFormat = "stencilAttachmentPixelFormat";
    private static readonly Selector sel_setStencilAttachmentPixelFormat = "setStencilAttachmentPixelFormat:";
    private static readonly Selector sel_sampleCount = "sampleCount";
    private static readonly Selector sel_setSampleCount = "setSampleCount:";
    private static readonly Selector sel_vertexDescriptor = "vertexDescriptor";
    private static readonly Selector sel_isAlphaToCoverageEnabled = "isAlphaToCoverageEnabled";
    private static readonly Selector sel_setAlphaToCoverageEnabled = "setAlphaToCoverageEnabled:";
}