#pragma once
#include <meshoptimizer.h>

inline void optimize_fetch(render::Model::Data& out) {
    ZoneScopedN("Optimize");
    std::vector<unsigned int> remap(out.indices.size());
    size_t vertex_count = meshopt_optimizeVertexFetch(out.vertices.data(), out.indices.data(), out.indices.size(), out.vertices.data(), out.vertices.size(), sizeof(render::PackedVertexData));
    out.vertices.resize(vertex_count, render::PackedVertexData(0, 0, 0, 0, 0, 0, 0));
}

//MAYBE: when networking meshopt_encodeVertexBuffer

template<typename I>
inline void simplify_buffer(std::vector<I> &out, const std::vector<I> &indices, const std::vector<render::VertexData>& vertices, float threshold = .2f, float target_error = 1e-2f) {
    out.resize(indices.size());
    out.resize(meshopt_simplify(out.data(), indices.data(), indices.size(), &vertices.front().Position.x, vertices.size(), sizeof(render::VertexData), indices.size() * threshold, target_error));
}
#include <iostream>
template <typename I>
inline std::vector<size_t> simplify_lod(std::vector<I> &indices, const std::vector<render::VertexData> &vertices, const std::vector<std::pair<float, float>> &levels)
{
    ZoneScopedN("LOD");
    typename std::vector<I> full(indices);
    indices.resize(0);
    std::vector<size_t> offsets;
    typename std::vector<I> part;
    for (const auto &[threshold, error]: levels) {
        ZoneScopedN("Level");
        simplify_buffer(part, full, vertices, threshold, error);
        meshopt_optimizeVertexCache(part.data(), part.data(), part.size(), vertices.size());
        offsets.push_back((offsets.empty() ? 0 : offsets.back()) + part.size());
        indices.reserve(indices.size() + part.size());
        indices.insert(indices.end(), part.begin(), part.end());
    }
    indices.reserve(indices.size() + full.size());
    indices.insert(indices.end(), full.begin(), full.end());
    return offsets;
}
template <typename I>
inline void simplify(std::vector<I> &indices, const std::vector<render::VertexData> &vertices) {
    ZoneScopedN("LOD");
    simplify_buffer(indices, indices, vertices);
    meshopt_optimizeVertexCache(indices.data(), indices.data(), indices.size(), vertices.size());
}