#pragma once

#include <extra2d/core/types.h>
#include <cstddef>
#include <cstdint>

namespace extra2d {

// ============================================================================
// 缓冲区类型枚举
// ============================================================================
enum class BufferType {
    Vertex,     // 顶点缓冲
    Index,      // 索引缓冲
    Uniform     // 统一缓冲
};

// ============================================================================
// 缓冲区使用模式枚举
// ============================================================================
enum class BufferUsage {
    Static,     // 静态数据，很少更新
    Dynamic,    // 动态数据，频繁更新
    Stream      // 流式数据，每帧更新
};

// ============================================================================
// 缓冲区描述结构
// ============================================================================
struct BufferDesc {
    BufferType type = BufferType::Vertex;
    BufferUsage usage = BufferUsage::Static;
    size_t size = 0;                    // 缓冲区大小（字节）
    const void* initialData = nullptr;  // 初始数据
};

// ============================================================================
// 缓冲区抽象接口 - 渲染后端无关
// ============================================================================
class Buffer {
public:
    virtual ~Buffer() = default;

    /**
     * @brief 绑定缓冲区
     */
    virtual void bind() = 0;

    /**
     * @brief 解绑缓冲区
     */
    virtual void unbind() = 0;

    /**
     * @brief 设置缓冲区数据（完全替换）
     * @param data 数据指针
     * @param size 数据大小（字节）
     */
    virtual void setData(const void* data, size_t size) = 0;

    /**
     * @brief 更新缓冲区部分数据
     * @param data 数据指针
     * @param offset 偏移量（字节）
     * @param size 数据大小（字节）
     */
    virtual void updateData(const void* data, size_t offset, size_t size) = 0;

    /**
     * @brief 映射缓冲区到内存（用于直接写入）
     * @return 映射后的内存指针，失败返回 nullptr
     */
    virtual void* map() = 0;

    /**
     * @brief 解除缓冲区映射
     */
    virtual void unmap() = 0;

    /**
     * @brief 获取缓冲区大小
     * @return 缓冲区大小（字节）
     */
    virtual size_t getSize() const = 0;

    /**
     * @brief 获取缓冲区类型
     * @return 缓冲区类型
     */
    virtual BufferType getType() const = 0;

    /**
     * @brief 获取缓冲区使用模式
     * @return 使用模式
     */
    virtual BufferUsage getUsage() const = 0;

    /**
     * @brief 检查缓冲区是否有效
     * @return 有效返回 true
     */
    virtual bool isValid() const = 0;

    /**
     * @brief 获取原生句柄（后端特定）
     * @return 原生句柄值
     */
    virtual uintptr_t getNativeHandle() const = 0;
};

} // namespace extra2d
