// SPDX-License-Identifier: Unlicense

#include "geometry.h"

#include "opengl.h"
#include "data.h"
#include "global.h"

static const f32 highwayVertices[] = {
#include "../res/meshes/planeY.vertices"
#include "../res/meshes/planeZ.vertices"
#include "../res/meshes/planeZFlippedV.vertices"
#include "../res/meshes/fret.vertices"
#include "../res/meshes/string.vertices"
#include "../res/meshes/capo.vertices"
#include "../res/meshes/noteArpeggio.vertices"
#include "../res/meshes/noteZeroArpeggioLeft.vertices"
#include "../res/meshes/noteZeroArpeggioRight.vertices"
#include "../res/meshes/noteBendStepFull.vertices"
#include "../res/meshes/noteBendStepHalf.vertices"
#include "../res/meshes/noteHex.vertices"
#include "../res/meshes/noteRect.vertices"
#include "../res/meshes/noteFretboard.vertices"
#include "../res/meshes/noteStand.vertices"
#include "../res/meshes/noteSymbolFretMute.vertices"
#include "../res/meshes/noteSymbolHammerOn.vertices"
#include "../res/meshes/noteSymbolHarmonic.vertices"
#include "../res/meshes/noteSymbolPalmMute.vertices"
#include "../res/meshes/noteSymbolPinchHarmonic.vertices"
#include "../res/meshes/noteSymbolPop.vertices"
#include "../res/meshes/noteSymbolPullOff.vertices"
#include "../res/meshes/noteSymbolSlap.vertices"
#include "../res/meshes/noteSymbolTap.vertices"
#include "../res/meshes/noteSymbolSlimX.vertices"
#include "../res/meshes/noteSymbolTriangleDown.vertices"
#include "../res/meshes/noteSymbolSlimEye.vertices"
#include "../res/meshes/noteSymbolWideEye.vertices"
#include "../res/meshes/noteSymbolWideX.vertices"
#include "../res/meshes/noteSymbolWideUpsideV.vertices"
#include "../res/meshes/noteSymbolTriangleUp.vertices"
#include "../res/meshes/noteSymbolWideOffsetV.vertices"
#include "../res/meshes/noteSymbolWideV.vertices"
#include "../res/meshes/noteSymbolSineRight.vertices"
#include "../res/meshes/noteSymbolSineLeft.vertices"
#include "../res/meshes/noteZeroLeft.vertices"
#include "../res/meshes/noteZeroMiddle.vertices"
#include "../res/meshes/noteZeroRight.vertices"
#include "../res/meshes/particle0.vertices"
#include "../res/meshes/particle1.vertices"
#include "../res/meshes/particle2.vertices"
#ifndef PLATFORM_EMSCRIPTEN
#ifdef SHR3D_ENVIRONMENT_SKYBOX
#include "../res/meshes/skysphere.vertices"
#endif // SHR3D_ENVIRONMENT_SKYBOX
#ifdef SHR3D_OPENXR
#include "../res/meshes/xrPointer.vertices"
#include "../res/meshes/xrDebugAxis.vertices"
#ifdef SHR3D_OPENXR_CONTROLLER_PICO4
#include "../res/meshes/xrController_Pico4Left.vertices"
#include "../res/meshes/xrController_Pico4Right.vertices"
#endif // SHR3D_OPENXR_CONTROLLER_PICO4
#ifdef SHR3D_OPENXR_CONTROLLER_QUEST3
#include "../res/meshes/xrController_Quest3Left.vertices"
#include "../res/meshes/xrController_Quest3Right.vertices"
#endif // SHR3D_OPENXR_CONTROLLER_QUEST3
#ifdef SHR3D_OPENXR_CONTROLLER_QUEST3_NEON
#include "../res/meshes/xrController_Quest3NeonLeft.vertices"
#include "../res/meshes/xrController_Quest3NeonRight.vertices"
#endif // SHR3D_OPENXR_CONTROLLER_QUEST3_NEON
#endif // SHR3D_OPENXR
#ifdef SHR3D_NOTE_CUTS
#include "../res/meshes/note25vl.vertices"
#include "../res/meshes/note25vr.vertices"
#include "../res/meshes/note375vl.vertices"
#include "../res/meshes/note375vr.vertices"
#include "../res/meshes/note50hb.vertices"
#include "../res/meshes/note50ht.vertices"
#include "../res/meshes/note50vl.vertices"
#include "../res/meshes/note50vr.vertices"
#include "../res/meshes/note625vl.vertices"
#include "../res/meshes/note625vr.vertices"
#include "../res/meshes/note75vl.vertices"
#include "../res/meshes/note75vr.vertices"
#endif // SHR3D_NOTE_CUTS
#endif // PLATFORM_EMSCRIPTEN
};
static const u32 highwayIndices[] = {
#include "../res/meshes/planeY.indices"
#include "../res/meshes/planeZ.indices"
#include "../res/meshes/planeZFlippedV.indices"
#include "../res/meshes/fret.indices"
#include "../res/meshes/string.indices"
#include "../res/meshes/capo.indices"
#include "../res/meshes/noteArpeggio.indices"
#include "../res/meshes/noteZeroArpeggioLeft.indices"
#include "../res/meshes/noteZeroArpeggioRight.indices"
#include "../res/meshes/noteBendStepFull.indices"
#include "../res/meshes/noteBendStepHalf.indices"
#include "../res/meshes/noteHex.indices"
#include "../res/meshes/noteRect.indices"
#include "../res/meshes/noteFretboard.indices"
#include "../res/meshes/noteStand.indices"
#include "../res/meshes/noteSymbolFretMute.indices"
#include "../res/meshes/noteSymbolHammerOn.indices"
#include "../res/meshes/noteSymbolHarmonic.indices"
#include "../res/meshes/noteSymbolPalmMute.indices"
#include "../res/meshes/noteSymbolPinchHarmonic.indices"
#include "../res/meshes/noteSymbolPop.indices"
#include "../res/meshes/noteSymbolPullOff.indices"
#include "../res/meshes/noteSymbolSlap.indices"
#include "../res/meshes/noteSymbolTap.indices"
#include "../res/meshes/noteSymbolSlimX.indices"
#include "../res/meshes/noteSymbolTriangleDown.indices"
#include "../res/meshes/noteSymbolSlimEye.indices"
#include "../res/meshes/noteSymbolWideEye.indices"
#include "../res/meshes/noteSymbolWideX.indices"
#include "../res/meshes/noteSymbolWideUpsideV.indices"
#include "../res/meshes/noteSymbolTriangleUp.indices"
#include "../res/meshes/noteSymbolWideOffsetV.indices"
#include "../res/meshes/noteSymbolWideV.indices"
#include "../res/meshes/noteSymbolSineRight.indices"
#include "../res/meshes/noteSymbolSineLeft.indices"
#include "../res/meshes/noteZeroLeft.indices"
#include "../res/meshes/noteZeroMiddle.indices"
#include "../res/meshes/noteZeroRight.indices"
#include "../res/meshes/particle0.indices"
#include "../res/meshes/particle1.indices"
#include "../res/meshes/particle2.indices"
#ifndef PLATFORM_EMSCRIPTEN
#ifdef SHR3D_ENVIRONMENT_SKYBOX
#include "../res/meshes/skysphere.indices"
#endif // SHR3D_ENVIRONMENT_SKYBOX
#ifdef SHR3D_OPENXR
#include "../res/meshes/xrPointer.indices"
#include "../res/meshes/xrDebugAxis.indices"
#ifdef SHR3D_OPENXR_CONTROLLER_PICO4
#include "../res/meshes/xrController_Pico4Left.indices"
#include "../res/meshes/xrController_Pico4Right.indices"
#endif // SHR3D_OPENXR_CONTROLLER_PICO4
#ifdef SHR3D_OPENXR_CONTROLLER_QUEST3
#include "../res/meshes/xrController_Quest3Left.indices"
#include "../res/meshes/xrController_Quest3Right.indices"
#endif // SHR3D_OPENXR_CONTROLLER_QUEST3
#ifdef SHR3D_OPENXR_CONTROLLER_QUEST3_NEON
#include "../res/meshes/xrController_Quest3NeonLeft.indices"
#include "../res/meshes/xrController_Quest3NeonRight.indices"
#endif // SHR3D_OPENXR_CONTROLLER_QUEST3_NEON
#endif // SHR3D_OPENXR
#ifdef SHR3D_NOTE_CUTS
#include "../res/meshes/note25vl.indices"
#include "../res/meshes/note25vr.indices"
#include "../res/meshes/note375vl.indices"
#include "../res/meshes/note375vr.indices"
#include "../res/meshes/note50hb.indices"
#include "../res/meshes/note50ht.indices"
#include "../res/meshes/note50vl.indices"
#include "../res/meshes/note50vr.indices"
#include "../res/meshes/note625vl.indices"
#include "../res/meshes/note625vr.indices"
#include "../res/meshes/note75vl.indices"
#include "../res/meshes/note75vr.indices"
#endif // SHR3D_NOTE_CUTS
#endif // PLATFORM_EMSCRIPTEN
};

static GLuint setupVao(const GLsizeiptr vertexDataSize, const f32* vertexData, const GLsizeiptr indexDataSize, const u32* indexData) // indexed rendering
{
  GLuint vao;
  GL(glGenVertexArrays(1, &vao));
  GL(glBindVertexArray(vao));

  GLuint vbo;
  GL(glGenBuffers(1, &vbo));
  GL(glBindBuffer(GL_ARRAY_BUFFER, vbo));
  GL(glBufferData(GL_ARRAY_BUFFER, vertexDataSize, vertexData, GL_STATIC_DRAW));

  GL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), nullptr)); // vertex coords
  GL(glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)))); // uv coords
  GL(glEnableVertexAttribArray(0));
  GL(glEnableVertexAttribArray(1));

  GLuint ebo;
  GL(glGenBuffers(1, &ebo));
  GL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo));
  GL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexDataSize, indexData, GL_STATIC_DRAW));

  return vao;
}

void Geometry::init()
{
  Global::staticDrawVao = setupVao(sizeof(highwayVertices), highwayVertices, sizeof(highwayIndices), highwayIndices);

  GL(glBindVertexArray(Global::dynamicDrawVao));
  GL(glBindBuffer(GL_ARRAY_BUFFER, Global::vbo));
}
