#ifndef FRAMEBUFFER_HPP
#define FRAMEBUFFER_HPP

#include "open_engine/ref_scope.hpp"

#include <cstdint>
#include <initializer_list>
#include <vector>

namespace OpenEngine {

    enum class FramebufferTextureFormat
    {
        None = 0,

        // Color
        RGBA8,
        RED_INTEGER,

        // Depth/Stencil
        DEPTH24STENCIL8,

        // Default
        Depth = DEPTH24STENCIL8
    };

    struct FramebufferTextureSpecification
    {
        FramebufferTextureSpecification() = default;
        FramebufferTextureSpecification(FramebufferTextureFormat format)
            : texture_format(format)
        {};

        FramebufferTextureFormat texture_format = FramebufferTextureFormat::None;
    };

    struct FramebufferAttachmentSpecification
    {
        FramebufferAttachmentSpecification() = default;
        FramebufferAttachmentSpecification(std::initializer_list<FramebufferTextureSpecification> attachments)
            : attachments(attachments)
        {}

        std::vector<FramebufferTextureSpecification> attachments;
    };

    struct FramebufferSpecification
    {
        uint32_t width, height;
        FramebufferAttachmentSpecification attachments;
        uint32_t samples = 1;

        bool swap_chain_target = false;
    };

    class FrameBuffer
    {
        public:
            virtual ~FrameBuffer() = default;
            virtual void Bind() = 0;
            virtual void Unbind() = 0;

            virtual void Resize(uint32_t width, uint32_t height) = 0;
            virtual int ReadPixel(uint32_t index, int x, int y) = 0;
            virtual void ClearBufferI(int index, int value) = 0;

		    virtual uint32_t GetColorAttachmentRendererID(uint32_t index = 0) const = 0;

            virtual const FramebufferSpecification& GetSpecification() const = 0;

            static Ref<FrameBuffer> Create(const FramebufferSpecification& spec);
    };
}

#endif // FRAMEBUFFER_HPP
