package site.rekovalev;

import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;

import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;

public class Main {

    private long window;
    final private int  width  = 800,
                       height = 600;

    public void run() {
        System.out.println("<i> Hello LWJGL " + Version.getVersion() + "!");

        init();
        loop();

        glfwFreeCallbacks(window);
        glfwDestroyWindow(window);

        // Уничтожение GLFW и очистка
        glfwTerminate();
        glfwSetErrorCallback(null).free();
    }

    private void init() {
        // Вывод ошибок в STDERR
        GLFWErrorCallback.createPrint(System.err).set();

        // Инициализация glfw
        if ( !glfwInit() )
            throw new IllegalStateException("<!> Ошибка инициализации GLFW");

        // Конфиги
        glfwDefaultWindowHints(); //загрузка стандартных значений параметров
        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); // Отключение возможности изменения размера окна

        // Создание окна
        this.window = glfwCreateWindow(this.width, this.height, "Тестовое окно", NULL, NULL);
        if ( this.window == NULL )
            throw new RuntimeException("<!> Ошибка создания окна");

        // Лямбда-функция для обработки нажатия кнопок
        glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
            if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
                glfwSetWindowShouldClose(window, true); // Создает событие запроса на закрытие
        });

        glfwMakeContextCurrent(window);// Делаем контекст OpenGL

        glfwSwapInterval(1);        // Вертикальная синхронизация

    }

    private void loop() {
        // Требуется для LWJGL использующего GLFW
        // LWJGL определяет контекст для текущего потока и привязывает GL функции к нему.
        GL.createCapabilities();


        glClearColor(1.0f, 0.0f, 0.0f, 0.0f); // Цвет очистки


        while ( !glfwWindowShouldClose(window) ) { //Цикл до события закрытия окна
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Очистка буферов

            /*
            * код тут
            */

            glfwSwapBuffers(window); // перенос COLOR_BUFFER на окно
            glfwPollEvents(); // обработка очереди событий
        }
    }

    public static void main(String[] args) {
        new Main().run();
    }

}