/**
 * Copyright (c) 2021 Dominic Masters
 * 
 * This software is released under the MIT License.
 * https://opensource.org/licenses/MIT
 */

#include "cube.h"

void cubeBuffer(primitive_t *prim,
  float x, float y, float z,
  float w, float h, float d,
  int32_t verticeStart, int32_t indiceStart
) {
  vertice_t *vertices = malloc(sizeof(vertice_t) * CUBE_VERTICE_COUNT);
  indice_t *indices = malloc(sizeof(indice_t) * CUBE_INDICE_COUNT);

  vertices[0].x = x, vertices[0].y = y, vertices[0].z = z;
  vertices[0].u = 0, vertices[0].v = 0;

  vertices[1].x = x+w, vertices[1].y = y, vertices[1].z = z;
  vertices[1].u = 1, vertices[1].v = 0;

  vertices[2].x = x, vertices[2].y = y+h, vertices[2].z = z;
  vertices[2].u = 0, vertices[2].v = 1;

  vertices[3].x = x+w, vertices[3].y = y+h, vertices[3].z = z;
  vertices[3].u = 1, vertices[3].v = 1;

  vertices[4].x = x, vertices[4].y = y, vertices[4].z = z+d;
  vertices[4].u = 0, vertices[4].v = 0;

  vertices[5].x = x+w, vertices[5].y = y, vertices[5].z = z+d;
  vertices[5].u = 1, vertices[5].v = 0;

  vertices[6].x = x, vertices[6].y = y+h, vertices[6].z = z+d;
  vertices[6].u = 0, vertices[6].v = 1;

  vertices[7].x = x+w, vertices[7].y = y+h, vertices[7].z = z+d;
  vertices[7].u = 1, vertices[7].v = 1;

  // Back
  indices[ 0] = (indice_t)(verticeStart + 0);
  indices[ 1] = (indice_t)(verticeStart + 1);
  indices[ 2] = (indice_t)(verticeStart + 3);

  indices[ 3] = (indice_t)(verticeStart + 0);
  indices[ 4] = (indice_t)(verticeStart + 2);
  indices[ 5] = (indice_t)(verticeStart + 3);
  
  // Right
  indices[ 6] = (indice_t)(verticeStart + 1);
  indices[ 7] = (indice_t)(verticeStart + 5);
  indices[ 8] = (indice_t)(verticeStart + 7);

  indices[ 9] = (indice_t)(verticeStart + 1);
  indices[10] = (indice_t)(verticeStart + 3);
  indices[11] = (indice_t)(verticeStart + 7);

  // Left
  indices[12] = (indice_t)(verticeStart + 4);
  indices[13] = (indice_t)(verticeStart + 0);
  indices[14] = (indice_t)(verticeStart + 2);

  indices[15] = (indice_t)(verticeStart + 4);
  indices[16] = (indice_t)(verticeStart + 6);
  indices[17] = (indice_t)(verticeStart + 2);

  // Front
  indices[18] = (indice_t)(verticeStart + 5);
  indices[19] = (indice_t)(verticeStart + 4);
  indices[20] = (indice_t)(verticeStart + 6);

  indices[21] = (indice_t)(verticeStart + 5);
  indices[22] = (indice_t)(verticeStart + 7);
  indices[23] = (indice_t)(verticeStart + 6);

  // Top
  indices[24] = (indice_t)(verticeStart + 7);
  indices[25] = (indice_t)(verticeStart + 2);
  indices[26] = (indice_t)(verticeStart + 6);

  indices[27] = (indice_t)(verticeStart + 7);
  indices[28] = (indice_t)(verticeStart + 3);
  indices[29] = (indice_t)(verticeStart + 2);

  // Bottom
  indices[30] = (indice_t)(verticeStart + 1);
  indices[31] = (indice_t)(verticeStart + 0);
  indices[32] = (indice_t)(verticeStart + 4);

  indices[33] = (indice_t)(verticeStart + 1);
  indices[34] = (indice_t)(verticeStart + 4);
  indices[35] = (indice_t)(verticeStart + 5);


  primitiveBufferVertices(prim, verticeStart, CUBE_VERTICE_COUNT, vertices);
  primitiveBufferIndices(prim, indiceStart, CUBE_INDICE_COUNT, indices);
  
  free(vertices);
  free(indices);
}

void cubeInit(primitive_t *primitive, float w, float h, float d) {
  primitiveInit(primitive, CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT);
  cubeBuffer(primitive,
    -w/2, -h/2, -d/2,
    w, h, d,
    0, 0
  );
}