//
// Created by sebastian on 08.02.26.
//

#include "TerrainRenderer.h"

#include "../toolbox/MathUtils.h"

void TerrainRenderer::prepare(const Camera &camera, const Light &light) {
    const glm::mat4 viewMatrix = MathUtils::createViewMatrix(camera);
    terrainShader.start();
    terrainShader.loadLight(light.getPosition(), light.getColor());
    terrainShader.loadViewMatrix(viewMatrix);
}

void TerrainRenderer::renderTerrainTiles(const std::unordered_map<TexturedModel *, std::vector<HexRenderData *>> &terrainTiles) {
    for (const auto& [texturedModel, batch] : terrainTiles) {
        prepareTexturedModel(*texturedModel);
        for (const auto& hexTile : batch) {
            prepareInstance(*hexTile);
            glDrawElements(GL_TRIANGLES, texturedModel->getRawModel()->vertexCount, GL_UNSIGNED_INT, 0);
        }
        unbindTexturedModel();
    }

}

void TerrainRenderer::finalizeFrame() {
    terrainShader.stop();
}

void TerrainRenderer::prepareTexturedModel(const TexturedModel &texturedModel) {
    auto rawModel = texturedModel.getRawModel();
    glBindVertexArray(rawModel->vaoID);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texturedModel.getTexture()->getTextureID());
}

void TerrainRenderer::unbindTexturedModel() {
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
    glBindVertexArray(0);
}

void TerrainRenderer::prepareInstance(const HexRenderData &hexTile) {
    glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(hexTile.position, 0,0,0,1);
    terrainShader.loadTransformationMatrix(transformationMatrix);

    terrainShader.loadIsHighlighted(hexTile.highlight);
}
