#include "worldgen.h"
#include <cglm/struct.h>
#include <GL/glew.h>
#include <math.h>
#include <string.h>

#define MIN(i, j) (((i) < (j)) ? (i) : (j))
#define MAX(i, j) (((i) > (j)) ? (i) : (j))

#define ORDER 0
#define RSQRT5 0.4472135954999579f
#define TWICE_RSQRT5 0.8944271909999159f
#define GOLDEN 1.618033988749895f

mesh* generateWorld(vec3s position)
{
    // placeholder struct for world mesh
    mesh* worldMesh = (mesh*) malloc(sizeof(mesh));
    populateIcosphere(worldMesh, ORDER, 1.0f);
    return worldMesh;
}

void populateIcosphere(mesh* worldMesh, unsigned char order, GLfloat radius)
{
    int T = powf(4, order);
    worldMesh->numVertices = (10*T + 2) * 3; // Final heap array size for vertices

    // Initial vertex array. Not used other than to initialize heap array in mesh
    GLfloat vertices[] = {
        -1.0f, GOLDEN, 0.0f, 1.0f, GOLDEN, 0.0f, -1.0f, -GOLDEN, 0.0f, 1.0f, -GOLDEN, 0.0f,
        0.0f, -1.0f, GOLDEN, 0.0f, 1.0f, GOLDEN, 0.0f, -1.0f, -GOLDEN, 0.0f, 1.0f, -GOLDEN,
        GOLDEN, 0.0f, -1.0f, GOLDEN, 0.0f, 1.0f, -GOLDEN, 0.0f, -1.0f, -GOLDEN, 0.0f, 1.0f
    };


    unsigned int triangles[] = {
        0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 
        11, 10, 2, 5, 11, 4, 1, 5, 9, 7, 1, 8, 10, 7, 6, 
        3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 
        9, 8, 1, 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7
    };
}

void normalizeVertices(GLfloat* vertices, unsigned int numVertices, GLfloat radius)
{
    printf("Normalizing %d vertices\n", numVertices);
    vec3s vertex;
    for( int i = 0; i < numVertices; i += 3)
    {
            vertex.x = vertices[i];
            vertex.y = vertices[i + 1];
            vertex.z = vertices[i + 2];
            
            vertex = glms_vec3_scale_as(vertex, radius);

            vertices[i] = vertex.x;
            vertices[i + 1] = vertex.y;
            vertices[i + 2] = vertex.z;
    }
}

unsigned int reducedSymmetricPair(unsigned int a, unsigned int b)
{
    return ((a+b+1)*(a+b+1) - (a+b+1)&1) >> 2 + MIN(a,b);
}
