//
// Created by trotFunky on 03/11/2019.
//

#include <Engine.h>
#include "DataHandling/Texture.h"
#include "MovementManager.h"
#include "TileTypes.h"
#include "Maze.h"

static int score = 0;

static Texture ground;
static Texture wall;
static Texture out;
static Texture raptor;
static Model3D raptor_model;

static Maze* maze;

static constexpr float horizontal_speed = 0.15;
static constexpr int units_per_pixel = 2;
static constexpr int map_side = 32;
static constexpr int corner_pos = (map_side*units_per_pixel);

void manage_inputs()
{
    if (InputStatus::is_key_pressed(0x1B))
    {
        glutDestroyWindow(glutGetWindow());
        exit(EXIT_SUCCESS);
    }

    Vec3d translation{0,0,0};

    if (InputStatus::is_special_key_pressed(GLUT_KEY_RIGHT))
    {
        translation.z += horizontal_speed;
    }
    if (InputStatus::is_special_key_pressed(GLUT_KEY_LEFT))
    {
        translation.z -= horizontal_speed;
    }

    if (InputStatus::is_special_key_pressed(GLUT_KEY_UP))
    {
        translation.x += horizontal_speed;
    }
    if (InputStatus::is_special_key_pressed(GLUT_KEY_DOWN))
    {
        translation.x -= horizontal_speed;
    }

    constrained_translation(translation,OGLE::camera,maze->map,units_per_pixel);

    Vec3i map_colour = current_map_colour(OGLE::camera.get_eyepos(),maze->map, units_per_pixel);
    if (map_colour == Tiles::end)
    {
        std::cout << "Success !" << std::endl;
        std::cout << "You managed to collect " << score << " raptors!" << std::endl;
        glutDestroyWindow(glutGetWindow());
        exit(EXIT_SUCCESS);
    }
    else if(map_colour == Tiles::objective)
    {
        if (maze->remove_objective({static_cast<int>(OGLE::camera.get_eyepos().x/maze->scaling_factor),
                                static_cast<int>(OGLE::camera.get_eyepos().z/maze->scaling_factor)}))
        {
            score += 1;
        }
    }

    Vec2i mouse_delta = InputStatus::get_mouse_delta(true);
    if (mouse_delta.x != 0 || mouse_delta.y != 0)
    {
        OGLE::camera.rotate({0,
                             -mouse_delta.x / InputStatus::mouse_sensitivity.x,
                             -mouse_delta.y / InputStatus::mouse_sensitivity.y});
    }
}

void display()
{
    manage_inputs();

    maze->draw();
}

int main(int argc, char** argv)
{
    OGLE::setup(argc,argv,display,"The Labyrinth !");

    ground.load_rgb_tga("resources/ground.tga");
    wall.load_rgb_tga("resources/wall.tga");
    out.load_rgb_tga("resources/Outside.tga");
    raptor.load_rgb_tga("resources/raptor.tga");
    raptor_model.load_ascii_off_file("resources/raptor.off");
    raptor_model.assign_texture(raptor);
    raptor_model.set_scaling(0.0025,0.0025,0.0025);
    raptor_model.set_rotation(-90,1,0,0);

    OGLE::camera.set_position({corner_pos/2,1,corner_pos/2});

    maze = new Maze("resources/Map.tga", 2, ground, wall, out, raptor_model);

    // Fill colour is sky blue.
    glClearColor(0.53,0.81,0.75,1);

    glutMainLoop();
    return 0;
}