package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen;

import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.vulkan.VkImageViewCreateInfo;
import org.tinylog.Logger;

import java.nio.LongBuffer;

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

public class ImageView {

    private final int AspectMask;
    private final int MipLevels;
    private final long VulkanImage;
    private final long VulkanImageView;
    private final boolean DepthImage;

    public ImageView(Device device, long vulkanImage, ImageViewData imageViewData, boolean DepthImage){
        this.AspectMask = imageViewData.AspectMask;
        this.MipLevels = imageViewData.MipLevels;
        this.VulkanImage = vulkanImage;
        this.DepthImage = DepthImage;
        try(var MemStack = MemoryStack.stackPush()){
            LongBuffer LongPointer = MemStack.mallocLong(1);
            var ViewCreateInfo = VkImageViewCreateInfo.calloc(MemStack)
                    .sType$Default()
                    .image(VulkanImage)
                    .viewType(imageViewData.ViewType)
                    .format(imageViewData.Format)
                    .subresourceRange(it -> it
                            .aspectMask(AspectMask)
                            .baseMipLevel(0)
                            .levelCount(MipLevels)
                            .baseArrayLayer(imageViewData.BaseArrayLayer)
                            .layerCount(imageViewData.LayerCount));
            vkCheck(vkCreateImageView(device.FetchVulkanDevice(), ViewCreateInfo, null, LongPointer),"Failed to create ImageView");
            VulkanImageView = LongPointer.get(0);
        }
    }

    public void cleanup(Device device){
        Logger.debug("Destroying Image View");
        vkDestroyImageView(device.FetchVulkanDevice(), VulkanImageView, null);
    }

    public int GetAspectMask(){
        return AspectMask;
    }
    public int GetMipLevels(){
        return MipLevels;
    }
    public long GetVulkanImageView(){
        return VulkanImageView;
    }
    public long GetVulkanImage(){return VulkanImage;}
    public boolean IsDepthImage(){return DepthImage;}

    public static class ImageViewData{
        private int AspectMask;
        private int BaseArrayLayer;
        private int Format;
        private int LayerCount;
        private int MipLevels;
        private int ViewType;

        public ImageViewData(){
            this.BaseArrayLayer = 0;
            this.LayerCount = 1;
            this.MipLevels = 1;
            this.ViewType = VK_IMAGE_VIEW_TYPE_2D;
        }
        public ImageView.ImageViewData AspectMask(int aspectMask){
            this.AspectMask = aspectMask;
            return this;
        }
        public ImageView.ImageViewData BaseArrayLayer(int baseArrayLayer){
            this.BaseArrayLayer = baseArrayLayer;
            return this;
        }
        public ImageView.ImageViewData Format(int format){
            this.Format = format;
            return this;
        }
        public ImageView.ImageViewData LayerCount(int layerCount){
            this.LayerCount = layerCount;
            return this;
        }
        public ImageView.ImageViewData MipLevels(int mipLevels){
            this.MipLevels = mipLevels;
            return this;
        }
        public ImageView.ImageViewData ViewType(int viewType){
            this.ViewType = viewType;
            return this;
        }
    }
}
