//
// 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_sphere;
static Mesh* mesh_cone;

static Shader* shader;


static void drawSnowman(const glm::mat4& model) {
    // снеговик, типа собран

    // нижний шар
    shader->uniformMatrix("model", model);
    mesh_sphere->draw();

    // теперь хитрость: надо сделать базовую матрицу для головы
    static float rotation_angle = 0.0f;
    // повернуть в +
    auto rotate_p = glm::rotate(glm::mat4(1.0f), rotation_angle, glm::vec3(0, 0, 1));
    // повернуть в -
    auto rotate_m = glm::rotate(glm::mat4(1.0f), -rotation_angle, glm::vec3(0, 0, 1));
    rotation_angle += 0.0004f;

    auto translate = glm::translate(glm::mat4(1.0f), glm::vec3(0, 1.5,0));
    auto scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.5, 0.5 ,0.5));

    // базовая матрица для головы
    auto head_base = model * rotate_m * translate * rotate_p;

    shader->uniformMatrix("model", head_base * scale);
    mesh_sphere->draw();

    // глаз X- (со смещением по Z)
    translate = glm::translate(glm::mat4(1.0f), glm::vec3(-0.25, 0.25, 0.25));
    scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.25, 0.25,0.25));
    shader->uniformMatrix("model", head_base * translate * scale);
    mesh_sphere->draw();

    // глаз X+ (со смещением по Z)
    translate = glm::translate(glm::mat4(1.0f), glm::vec3(0.25, 0.25, 0.25));
    shader->uniformMatrix("model", head_base * translate * scale);
    mesh_sphere->draw();

    // нос, (со смещением по Z)
    translate = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 0.5));
    auto rotate = glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(1, 0, 0));
    shader->uniformMatrix("model",  head_base * translate * scale * rotate);
    mesh_cone->draw();
}


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

    // мировой центр
    auto base = glm::mat4(1.0f);
    shader->uniformMatrix("model", base);
    mesh_xyz->draw();

    // ну и сюда же просто отрисовать снеговика
    drawSnowman(base);
}

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

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

    mesh_cone = MeshLoader::loadMesh("res/cone");
    if (mesh_cone == nullptr) {
        std::cerr << "Failed to load 'cone' 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_xyz;
    delete mesh_cone;
    delete mesh_sphere;
    delete shader;
}