//
// 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();

    // шар 2
    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));
    shader->uniformMatrix("model", model * translate * scale);
    mesh_sphere->draw();

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

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

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


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

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

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

    // тут нужен нужен translate_x+, translate_x-, translate_up
    auto translate_xp = glm::translate(glm::mat4(1.0f), glm::vec3(1.7, 0, 0));
    auto translate_up = glm::translate(glm::mat4(1.0f), glm::vec3(0, 1, 0));
    auto scale_0_7 = glm::scale(glm::mat4(1.0f), glm::vec3(0.7, 0.7,0.7));

    // первый снеговик, смещаем наверх, крутим
    drawSnowman(translate_up * rotate);

    // второй снеговик
    drawSnowman(translate_xp * scale_0_7 * translate_up * rotate);

    // третий снеговик
    drawSnowman(translate_xp * scale_0_7 * translate_xp * scale_0_7 * translate_up * rotate);
}

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;
}