#pragma once
#include <cstdint>

#include "renderer.h"

class renderer_texture_array {
public:
    explicit renderer_texture_array(const texture_format in_format) : format(in_format) {}
    virtual ~renderer_texture_array() = default;

    virtual void* lock(const uint32_t index, uint32_t* out_row_pitch) = 0;
    virtual void unlock(const uint32_t index) = 0;

    virtual void update_subresource(const uint32_t index, const Eigen::AlignedBox2i& in_area, const void* in_buffer, uint32_t in_buffer_size) = 0;

    void set_count(const uint32_t in_count) {
        if (in_count > MAX_TEXTURE_SIZE) {
            throw std::runtime_error("Texture array size is too large.");
        }
        if (in_count == 0) {
            throw std::runtime_error("Texture array size must be greater than 0.");
        }
        if (in_count == get_count()) {
            return;
        }
        on_set_count(in_count);
    }

    virtual bool resize(const Eigen::Vector2i& size) = 0;
    virtual Eigen::Vector2i size() = 0;

    virtual void* get_native_handle() = 0;
    virtual void* get_shader_resource_view() = 0;

    [[nodiscard]] virtual uint32_t get_count() = 0;
    [[nodiscard]] texture_format get_format() const { return format; }
protected:
    virtual void on_set_count(uint32_t in_count) = 0;
private:
    const uint32_t MAX_TEXTURE_SIZE = 256;

    const texture_format format;
};
