#define STB_IMAGE_IMPLEMENTATION

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <stb_image.h>
#include <funcs.h>
#include <shader.h>
#include "data.cpp"

int main() {
    // Initalize GLFW
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // Open Window
    GLFWwindow* window = glfwCreateWindow(800, 600, "Howdy Naif!", NULL, NULL);
    if (window == NULL) {
        std::cout << "Could not open the window!\n";
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // Start GLAD loader
    if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)){
    std::cout << "Failed to initialize GLAD" << std::endl;
    return -1;
    }

    // Set viewport
    glViewport(0, 0, 800, 600);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    // glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
    // glfwSetCursorPosCallback(window, mouse_callback);

    // Create Data
    unsigned int gridX = 10, gridY = 3;
    float* tileCoords = makeGridPoints(gridX, gridY);
    unsigned int* tileIndices = makeGridIndex(gridX, gridY);
    
    // Use and set shader
    Shader myShader("../shaders/vert.vs", "../shaders/frag.fs");
    myShader.use();
 
    // Create Vertex Buffer and bind it to array buffer, then specifiy how to use that data
    unsigned int VAO, VBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, 5*gridX*gridY*sizeof(float), tileCoords, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)(3*sizeof(float)));
    glEnableVertexAttribArray(1);
    
    // Element Buffers
    unsigned int EBO;
    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*(gridX-1)*(gridY-1)*sizeof(unsigned int), tileIndices, GL_STATIC_DRAW);

    myShader.use();
    glBindVertexArray(VAO);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
    // Window loop
    while(!glfwWindowShouldClose(window)) {
        // Input checking
        processInput(window);

        // Rendering Loop
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawElements(GL_TRIANGLES, (gridX-1)*(gridY-1)*6, GL_UNSIGNED_INT, 0);

        // Events and buffer swap
        glfwPollEvents();
        glfwSwapBuffers(window);
    }

    glfwTerminate();

    delete[] tileCoords;
    //delete[] tileIndices;
    return 0;
}