//
// Created by vlad on 23.03.23.
//

#include "render.h"
#include "../graphics/MeshLoader.h"
#include "../graphics/Shader.h"

#include <glm/ext/matrix_transform.hpp>

static Mesh* mesh_xyz;
static Mesh* mesh_snowman;
static Mesh* mesh_three;
static Mesh* mesh_table;

static Shader* shader;


static void drawStaticSnowman() {
    auto model_scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f, 0.5f, 0.5f));
    auto model_translate = glm::translate(glm::mat4(1.0f), glm::vec3(3, 2, 5));
    auto model_rotate = glm::rotate(glm::mat4(1.0f), glm::radians(45.0f), glm::vec3(1, 1, 1));

    shader->uniformMatrix("model", model_scale * model_translate * model_rotate);
    mesh_snowman->draw();
}

static void drawThree() {
    // "базовая" матрица
    auto tree_translate = glm::translate(glm::mat4(1.0f), glm::vec3(5, 0, -5));
    shader->uniformMatrix("model", tree_translate);

    mesh_three->draw();

    // рисуем снеговиков вокруг дерева
    static float rotation_angle = 0.0f;

    auto showman_translate = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, -3));

    for (int i = 0; i < 6; i++) {
        float offset_angle = glm::radians(60.0f * (float)i);
        auto showman_rotate = glm::rotate(glm::mat4(1.0f), rotation_angle + offset_angle, glm::vec3(0, 1, 0));

        shader->uniformMatrix("model", tree_translate * showman_rotate * showman_translate);

        mesh_snowman->draw();
    }

    rotation_angle += 0.0002f;
}


void renderScene(Camera& cam) {
    auto projview = cam.getProjection() * cam.getView();
    shader->use();

//    shader->uniformMatrix("pr", cam.getProjection() * cam.getView());
    shader->uniformMatrix("projview", projview);
    shader->uniformMatrix("model", glm::mat4(1.0f));
    mesh_xyz->draw();

    mesh_table->draw();

    drawStaticSnowman();
    drawThree();
}

int loadResources() {
    mesh_xyz = MeshLoader::loadMesh("res/xyz");
    if (mesh_xyz == nullptr) {
        std::cerr << "Failed to load 'xyz' mesh!" << std::endl;
        return -1;
    }

    mesh_snowman = MeshLoader::loadMesh("res/snowman");
    if (mesh_snowman == nullptr) {
        std::cerr << "Failed to load 'snowman' mesh!" << std::endl;
        return -1;
    }

    mesh_three = MeshLoader::loadMesh("res/christmas-tree");
    if (mesh_three == nullptr) {
        std::cerr << "Failed to load 'christmas-tree' mesh!" << std::endl;
        return -1;
    }

    mesh_table = MeshLoader::loadMesh("res/table");
    if (mesh_table == nullptr) {
        std::cerr << "Failed to load 'table' mesh!" << std::endl;
        return -1;
    }

    shader = Shader::loadShader("res/main-colored.vsh", "res/main-colored.fsh");
    if (shader == nullptr) {
        return -1;
    }

    return 0;
}

void unloadResources() {
    delete mesh_table;
    delete mesh_xyz;
    delete mesh_snowman;
    delete mesh_three;
    delete shader;
}