#include "shared_model.h"
#include <ranges>
#include <exception>
#include <iostream>

#include "tool.h"


namespace {
std::vector<SharedModel *> g_sharedModel{};
}

//= SharedMesh public
SharedMesh::SharedMesh(int index, const Z::Mesh *mesh, ID3D11Device *device) {
    this->modelIdx = index;
    this->name = mesh->name;
    this->hasSkin = mesh->hasSkin;
    this->localTsf = mesh->localTsf;
    this->countIndices = mesh->ar_indices.size();

    // 创建gpu资源 顶点buffer
    D3D11_BUFFER_DESC d_vert{};
    d_vert.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    d_vert.ByteWidth = sizeof(Z::VertexData) * mesh->ar_vertices.size();
    d_vert.Usage = D3D11_USAGE_IMMUTABLE;

    D3D11_SUBRESOURCE_DATA initData{};
    initData.pSysMem = mesh->ar_vertices.data();

    HRESULT hr = device->CreateBuffer(&d_vert, &initData,
                                      buf_vert.ReleaseAndGetAddressOf());
    if (FAILED(hr)) {
        MessageBoxW(nullptr, L"Create VertexBuffer failed",
                    L"Resource::SharedMesh Constructor",MB_OK);
        throw std::runtime_error{"Create VertexBuffer failed"};
    }

    // 创建gpu资源 index buffer
    D3D11_BUFFER_DESC d_idx{};
    d_idx.BindFlags = D3D11_BIND_INDEX_BUFFER;
    d_idx.Usage = D3D11_USAGE_IMMUTABLE;
    d_idx.ByteWidth = sizeof(UINT) * std::size(mesh->ar_indices);

    D3D11_SUBRESOURCE_DATA initIdxData{};
    initIdxData.pSysMem = mesh->ar_indices.data();

    hr = device->CreateBuffer(&d_idx, &initIdxData, buf_index.GetAddressOf());
    if (FAILED(hr)) {
        MessageBoxW(nullptr, L"Create Index Buffer failed",
                    L"Resource::SharedMesh Constructor",MB_OK);
        throw std::runtime_error{"Create Index failed"};
    }
}
SharedMesh::~SharedMesh() = default;


//= SharedModel public
SharedModel *SharedModel::S_AddSharedModel(Z::Model *model, ID3D11Device *device) {
    // 以 model.name 索引,如果已存在,就返回
    auto it = std::ranges::find_if(g_sharedModel,
                                   [model](const SharedModel *item) {
                                       return item->name == model->name;
                                   });
    if (it != g_sharedModel.end()) { return *it; }
    // 如果不存在,则创建一个 shared mesh ,返回新创建的对象的指针
    size_t cmesh = model->ar_meshDatas.size();

    SharedModel *psm = new SharedModel{
        static_cast<int>(g_sharedModel.size()),
        model->name,
        {}
    };

    psm->ar_sharedMesh.reserve(cmesh);
    try {
        for (int i = 0; i < cmesh; ++i) {
            psm->ar_sharedMesh.emplace_back(i, &model->ar_meshDatas[i], device);
        }
    } catch (std::exception &e) {
        delete psm;
        MessageBoxW(nullptr, Z::u8_to_wstring(e.what()).c_str(),
                    L"创建shared mesh失败",MB_OK);
        return nullptr;
    }

    g_sharedModel.push_back(psm);

    return psm;
}




















//
