package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader;

import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.vulkan.VkSamplerCreateInfo;

import java.nio.LongBuffer;

import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck;
import static org.lwjgl.vulkan.VK10.*;

public class TextureSampler {
    private static final int MAX_ANISOTROPY = 16;
    private final long VkSampler;

    public TextureSampler(VulkanContext VkCtx, TextureSamplerInfo textureSamplerInfo){
        try(var MemStack = MemoryStack.stackPush()){
            var SamplerInfo = VkSamplerCreateInfo.calloc(MemStack)
                    .sType$Default()
                    .magFilter(VK_FILTER_NEAREST)
                    .minFilter(VK_FILTER_NEAREST)
                    .addressModeU(textureSamplerInfo.AddressMode())
                    .addressModeV(textureSamplerInfo.AddressMode())
                    .addressModeW(textureSamplerInfo.AddressMode())
                    .borderColor(textureSamplerInfo.BorderColour())
                    .unnormalizedCoordinates(false)
                    .compareEnable(false)
                    .compareOp(VK_COMPARE_OP_NEVER)
                    .mipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST)
                    .minLod(0.0f)
                    .maxLod(textureSamplerInfo.MipLevels())
                    .mipLodBias(0.0f);
            if(textureSamplerInfo.Anisotropy() && VkCtx.GetDevice().SamplesAnisotropy()){
                SamplerInfo
                        .anisotropyEnable(true)
                        .maxAnisotropy(MAX_ANISOTROPY);
            }
            LongBuffer LongPointer = MemStack.mallocLong(1);
            vkCheck(vkCreateSampler(VkCtx.GetDevice().FetchVulkanDevice(), SamplerInfo,null,LongPointer)
                    ,"Failed to create sampler");
            VkSampler = LongPointer.get(0);
        }
    }

    public long GetVkSampler(){return VkSampler;}
    public void CleanUp(VulkanContext VkCtx){
        vkDestroySampler(VkCtx.GetDevice().FetchVulkanDevice(), VkSampler,null);
    }
}
