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

const fs = require('fs');
const path = require('path');

const MODEL_NAME = 'Poker Chip';
const FLIP_TEXTURE_Y = true;

let rawVertices = [];
let faces = [];
let coordinates = [];
const filePath = path.join(__dirname, '..', '..', 'assets', 'models', 'Chip Single', 'Single Chip.obj');
const data = fs.readFileSync(filePath, 'utf-8');

const scale = 0.1;

data.split('\n').forEach(line => {
  const bits = line.trim().split(' ');
  if(!bits.length || bits.every(n => !n || !bits.length)) return;
  const lineType = bits.shift();

  if(lineType === 'v') {
    const [ x, y, z ] = bits.map(n => {
      const val = parseFloat(n) * scale;
      return val;
    });
    rawVertices.push({ x, y, z });
  } else if(lineType === 'vt') {
    let [ u, v ] = bits.map(n => parseFloat(n));
    if(FLIP_TEXTURE_Y) v = 1 - v;
    coordinates.push({ u, v });
  } else if(lineType === 'f') {
    faces.push(bits.map(n => {
      const [ vertice, coordinate ] = n.split('/').map(n => parseInt(n));
      return { vertice, coordinate };
    }));
  }
});

const verticeCompare = (vl, vr) => (
  vl.x === vr.x &&
  vl.y === vr.y &&
  vl.z === vr.z &&
  vl.u === vr.u &&
  vl.v === vr.v
);

const indices = [];
const vertices = [];

faces.forEach(face => {
  face.forEach(faceIndice => {
    const rawVert = rawVertices[faceIndice.vertice-1];
    const rawCoord = coordinates[faceIndice.coordinate-1];
    const vertice = { ...rawVert, ...rawCoord };

    const indice = vertices.findIndex(vert => {
      return verticeCompare(vert, vertice);
    });

    if(indice === -1) {
      indices.push(vertices.length);
      vertices.push(vertice);
    } else {
      indices.push(indice);
    }
  })
})


const MODEL_NAME_CAPS = MODEL_NAME.replace(/\s/g, '_').toUpperCase();
const MODEL_NAME_CAMEL = [
  MODEL_NAME[0].toLowerCase(),
  MODEL_NAME.split(' ').join('').substr(1)
].join('')
// const fn = MODEL_NAME.toLowerCase().split(' ').join('');
const fn = 'model';

const license = `/**
 * Copyright (c) ${new Date().getFullYear()} Dominic Masters
 * 
 * This software is released under the MIT License.
 * https://opensource.org/licenses/MIT
 */
`;

// Write header file
const header = `${license}
#pragma once
#include <dawn/dawn.h>
#include "../primitive.h"

#define ${MODEL_NAME_CAPS}_NAME "${MODEL_NAME}"
#define ${MODEL_NAME_CAPS}_VERTICE_COUNT ${vertices.length}
#define ${MODEL_NAME_CAPS}_INDICE_COUNT ${indices.length}
#define ${MODEL_NAME_CAPS}_TRIANGLE_COUNT ${indices.length/3}

/**
 * Generated Model ${MODEL_NAME}
 * Generated at ${new Date().toUTCString()}
 * @returns ${MODEL_NAME} as a primitive.
 */
primitive_t * ${MODEL_NAME_CAMEL}Create();
`;

// Write Source file
const strVertices = vertices.map((v,i) => {
  return `{ .x = ${v.x}, .y = ${v.y}, .z = ${v.z}, .u = ${v.u}, .v = ${v.v} }`;
}).join(',\n    ');

const strIndices = indices.map(i => {
  return `${i}`;
}).join(',\n    ');

const source = `${license}
#include "${fn}.h"

primitive_t * ${MODEL_NAME_CAMEL}Create() {
  vertice_t vertices[${MODEL_NAME_CAPS}_VERTICE_COUNT] = {
    ${strVertices}
  };

  indice_t indices[${MODEL_NAME_CAPS}_INDICE_COUNT] = {
    ${strIndices}
  };

  primitive_t *primitive = primitiveCreate(
    ${MODEL_NAME_CAPS}_VERTICE_COUNT,
    ${MODEL_NAME_CAPS}_INDICE_COUNT
  );

  primitiveBufferVertices(primitive, 0, ${MODEL_NAME_CAPS}_VERTICE_COUNT, vertices);
  primitiveBufferIndices(primitive, 0, ${MODEL_NAME_CAPS}_INDICE_COUNT, indices);
  return primitive;
}
`;


fs.writeFileSync(path.join(__dirname, fn+'.h'), header);
fs.writeFileSync(path.join(__dirname, fn+'.c'), source);