#pragma once
#include "texture/texture_map_types.h"
#include <vector>
#include <cstring>

#include "geometry/rect.h"

class texture_map_utils {
public:
    // 从映射纹理中提取区域数据
    static std::vector<std::byte> extract_region(
        const texture_map&     map,
        const rect_t<int32_t>& region,
        int                    bytes_per_pixel)
    {
        // 验证区域有效性
        if (region.left() < 0 || region.top() < 0 ||
            region.left() + region.width() > map.size.x() ||
            region.top() + region.height() > map.size.y() ||
            region.width() <= 0 || region.height() <= 0) {
            return {}; // 返回空数据
        }

        // 分配结果缓冲区
        std::vector<std::byte> result(region.width() * region.height() * bytes_per_pixel);

        // 从映射内存中复制指定区域
        const auto dst = reinterpret_cast<uint8_t*>(result.data());
        const auto src = reinterpret_cast<const uint8_t*>(map.data.data());

        for (int y = 0; y < region.height(); ++y) {
            const uint8_t* src_row = src + (region.top() + y) * map.row_pitch + region.left() * bytes_per_pixel;
            uint8_t* dst_row = dst + y * region.width() * bytes_per_pixel;
            std::memcpy(dst_row, src_row, region.width() * bytes_per_pixel);
        }

        return result;
    }

    // 将数据写入映射纹理的指定区域
    static bool write_region(const texture_map& map, const void* data, const rect_t<int32_t>& region,
                             const int          bytes_per_pixel) {
        // 检查只读标志
        if (map.read_only) {
            return false;
        }

        // 验证区域有效性
        if (region.left() < 0 || region.top() < 0 ||
            region.left() + region.width() > map.size.x() ||
            region.top() + region.height() > map.size.y() ||
            region.width() <= 0 || region.height() <= 0) {
            return false;
        }

        // 写入映射内存
        const auto src = static_cast<const uint8_t*>(data);
        const auto dst = reinterpret_cast<uint8_t*>(map.data.data());

        for (int y = 0; y < region.height(); ++y) {
            uint8_t* dst_row = dst + (region.top() + y) * map.row_pitch + region.left() * bytes_per_pixel;
            const uint8_t* src_row = src + y * region.width() * bytes_per_pixel;
            std::memcpy(dst_row, src_row, region.width() * bytes_per_pixel);
        }

        return true;
    }
};
