#pragma once
#include "imgui.h"
#include "renderer.h"
#include "application/application.h"

class render_resource : public std::enable_shared_from_this<render_resource> {
public:
    render_resource() {
        format = vk::Format::eUndefined;
        width_ = 0;
        height_ = 0;
        image = nullptr;
        image_view = nullptr;
        sampler = nullptr;
        memory = nullptr;
        descriptor_set = nullptr;
    }
    virtual ~render_resource() {
        render_resource::destroy();
    }

    [[nodiscard]] int get_width() const { return width_; }
    [[nodiscard]] int get_height() const { return height_; }
    [[nodiscard]] ImTextureID get_texture_id() const { return descriptor_set; }
    [[nodiscard]] vk::DescriptorImageInfo get_descriptor_info() const {
        vk::DescriptorImageInfo info;
        info.setImageLayout(vk::ImageLayout::eShaderReadOnlyOptimal);
        info.setImageView(image_view);
        info.setSampler(sampler);
        return info;
    }

    void init(uint32_t width, uint32_t height, vk::Format in_format) {
        width_ = width;
        height_ = height;
        format = in_format;
        on_init();
    }
    void resize(uint32_t width, uint32_t height) {
        if (width_ == width && height_ == height) {
            return;
        }
        destroy();
        init(width, height, format);
    }
    void draw() const {
        ImGui::Image(get_texture_id(), ImVec2(static_cast<float>(get_width()), static_cast<float>(get_height())));
    }
    virtual void destroy() {
        const auto r = application::get()->get_renderer();
        const auto& device = r->device;
        device.destroySampler(sampler);
        device.destroyImageView(image_view);
        device.destroyImage(image);
        device.freeMemory(memory);
        ImGui_ImplVulkan_RemoveTexture(descriptor_set);
        sampler = nullptr;
        image_view = nullptr;
        image = nullptr;
        memory = nullptr;
        descriptor_set = nullptr;
    }

    vk::Image image;
    vk::ImageView image_view;
    vk::Sampler sampler;
    vk::DescriptorSet descriptor_set;
    vk::DeviceMemory memory;
    vk::Format format;
protected:
    virtual void on_init() = 0;
    uint32_t width_;
    uint32_t height_;
};