// SPDX-License-Identifier: Unlicense

#include "geometry.h"

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

//#ifndef SHR3D_OPENGL_DRAW_NON_INDEXED
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_OPENXR
#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
#include "../res/meshes/xrPointer.vertices"
#endif // SHR3D_OPENXR
#ifdef SHR3D_ENVIRONMENT_SKYBOX
#include "../res/meshes/skysphere.vertices"
#endif // SHR3D_ENVIRONMENT_SKYBOX
#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[] = {
//#ifndef SHR3D_OPENGL_DRAW_ZERO_BASED
#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_OPENXR
#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
#include "../res/meshes/xrPointer.indices"
#endif // SHR3D_OPENXR
#ifdef SHR3D_ENVIRONMENT_SKYBOX
#include "../res/meshes/skysphere.indices"
#endif // SHR3D_ENVIRONMENT_SKYBOX
#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
//#else // SHR3D_OPENGL_DRAW_ZERO_BASED
//#include "../res/meshes/indexed-zero-based/planeY.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/planeZ.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/planeZFlippedV.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/fret.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/string.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/capo.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteArpeggio.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteZeroArpeggioLeft.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteZeroArpeggioRight.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteBendStepFull.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteBendStepHalf.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteHex.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteRect.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteFretboard.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteStand.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolFretMute.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolHammerOn.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolHarmonic.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolPalmMute.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolPinchHarmonic.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolPop.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolPullOff.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolSlap.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolTap.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolSlimX.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolTriangleDown.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolSlimEye.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolWideEye.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolWideX.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolWideUpsideV.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolTriangleUp.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolWideOffsetV.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolWideV.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolSineRight.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteSymbolSineLeft.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteZeroLeft.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteZeroMiddle.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/noteZeroRight.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/particle0.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/particle1.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/particle2.indicesZeroBased"
//#ifdef SHR3D_OPENXR
//#include "../res/meshes/indexed-zero-based/xrDebugAxis.indicesZeroBased"
//#ifdef SHR3D_OPENXR_CONTROLLER_PICO4
//#include "../res/meshes/indexed-zero-based/xrController_Pico4Left.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/xrController_Pico4Right.indicesZeroBased"
//#endif // SHR3D_OPENXR_CONTROLLER_PICO4
//#ifdef SHR3D_OPENXR_CONTROLLER_QUEST3
//#include "../res/meshes/indexed-zero-based/xrController_Quest3Left.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/xrController_Quest3Right.indicesZeroBased"
//#endif // SHR3D_OPENXR_CONTROLLER_QUEST3
//#include "../res/meshes/indexed-zero-based/xrPointer.indicesZeroBased"
//#endif // SHR3D_OPENXR
//#ifdef SHR3D_ENVIRONMENT_SKYBOX
//#include "../res/meshes/indexed-zero-based/skysphere.indicesZeroBased"
//#endif // SHR3D_ENVIRONMENT_SKYBOX
//#ifdef SHR3D_NOTE_CUTS
//#include "../res/meshes/indexed-zero-based/note25vl.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/note25vr.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/note375vl.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/note375vr.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/note50hb.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/note50ht.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/note50vl.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/note50vr.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/note625vl.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/note625vr.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/note75vl.indicesZeroBased"
//#include "../res/meshes/indexed-zero-based/note75vr.indicesZeroBased"
//#endif // SHR3D_NOTE_CUTS
//#endif // SHR3D_OPENGL_DRAW_ZERO_BASED
};
//#else // SHR3D_OPENGL_DRAW_NON_INDEXED
//static const f32 highwayVertices[] = {
//#include "../res/meshes/non-indexed/planeY.vertices"
//#include "../res/meshes/non-indexed/planeZ.vertices"
//#include "../res/meshes/non-indexed/planeZFlippedV.vertices"
//#include "../res/meshes/non-indexed/fret.vertices"
//#include "../res/meshes/non-indexed/string.vertices"
//#include "../res/meshes/non-indexed/capo.vertices"
//#include "../res/meshes/non-indexed/noteArpeggio.vertices"
//#include "../res/meshes/non-indexed/noteZeroArpeggioLeft.vertices"
//#include "../res/meshes/non-indexed/noteZeroArpeggioRight.vertices"
//#include "../res/meshes/non-indexed/noteBendStepFull.vertices"
//#include "../res/meshes/non-indexed/noteBendStepHalf.vertices"
//#include "../res/meshes/non-indexed/noteHex.vertices"
//#include "../res/meshes/non-indexed/noteRect.vertices"
//#include "../res/meshes/non-indexed/noteFretboard.vertices"
//#include "../res/meshes/non-indexed/noteStand.vertices"
//#include "../res/meshes/non-indexed/noteSymbolFretMute.vertices"
//#include "../res/meshes/non-indexed/noteSymbolHammerOn.vertices"
//#include "../res/meshes/non-indexed/noteSymbolHarmonic.vertices"
//#include "../res/meshes/non-indexed/noteSymbolPalmMute.vertices"
//#include "../res/meshes/non-indexed/noteSymbolPinchHarmonic.vertices"
//#include "../res/meshes/non-indexed/noteSymbolPop.vertices"
//#include "../res/meshes/non-indexed/noteSymbolPullOff.vertices"
//#include "../res/meshes/non-indexed/noteSymbolSlap.vertices"
//#include "../res/meshes/non-indexed/noteSymbolTap.vertices"
//#include "../res/meshes/non-indexed/noteSymbolSlimX.vertices"
//#include "../res/meshes/non-indexed/noteSymbolTriangleDown.vertices"
//#include "../res/meshes/non-indexed/noteSymbolSlimEye.vertices"
//#include "../res/meshes/non-indexed/noteSymbolWideEye.vertices"
//#include "../res/meshes/non-indexed/noteSymbolWideX.vertices"
//#include "../res/meshes/non-indexed/noteSymbolWideUpsideV.vertices"
//#include "../res/meshes/non-indexed/noteSymbolTriangleUp.vertices"
//#include "../res/meshes/non-indexed/noteSymbolWideOffsetV.vertices"
//#include "../res/meshes/non-indexed/noteSymbolWideV.vertices"
//#include "../res/meshes/non-indexed/noteSymbolSineRight.vertices"
//#include "../res/meshes/non-indexed/noteSymbolSineLeft.vertices"
//#include "../res/meshes/non-indexed/noteZeroLeft.vertices"
//#include "../res/meshes/non-indexed/noteZeroMiddle.vertices"
//#include "../res/meshes/non-indexed/noteZeroRight.vertices"
//#ifdef SHR3D_OPENXR
//#include "../res/meshes/non-indexed/xrDebugAxis.vertices"
//#ifdef SHR3D_OPENXR_CONTROLLER_PICO4
//#include "../res/meshes/non-indexed/xrController_Pico4Left.vertices"
//#include "../res/meshes/non-indexed/xrController_Pico4Right.vertices"
//#endif // SHR3D_OPENXR_CONTROLLER_PICO4
//#ifdef SHR3D_OPENXR_CONTROLLER_QUEST3
//#include "../res/meshes/non-indexed/xrController_Quest3Left.vertices"
//#include "../res/meshes/non-indexed/xrController_Quest3Right.vertices"
//#endif // SHR3D_OPENXR_CONTROLLER_QUEST3
//#include "../res/meshes/non-indexed/xrPointer.vertices"
//#endif // SHR3D_OPENXR
//#ifdef SHR3D_ENVIRONMENT_SKYBOX
//#include "../res/meshes/non-indexed/skysphere.vertices"
//#ifdef SHR3D_NOTE_CUTS
//#include "../res/meshes/non-indexed/note25vl.vertices"
//#include "../res/meshes/non-indexed/note25vr.vertices"
//#include "../res/meshes/non-indexed/note375vl.vertices"
//#include "../res/meshes/non-indexed/note375vr.vertices"
//#include "../res/meshes/non-indexed/note50hb.vertices"
//#include "../res/meshes/non-indexed/note50ht.vertices"
//#include "../res/meshes/non-indexed/note50vl.vertices"
//#include "../res/meshes/non-indexed/note50vr.vertices"
//#include "../res/meshes/non-indexed/note625vl.vertices"
//#include "../res/meshes/non-indexed/note625vr.vertices"
//#include "../res/meshes/non-indexed/note75vl.vertices"
//#include "../res/meshes/non-indexed/note75vr.vertices"
//#endif // SHR3D_NOTE_CUTS
//#endif // SHR3D_ENVIRONMENT_SKYBOX
//};
//#endif // SHR3D_OPENGL_DRAW_NON_INDEXED

//static GLuint setupVao(const GLsizeiptr vertexDataSize, const f32* vertexData)
//{
//  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 coord)s
//  GL(glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat))); // uv coord)s
//  GL(glEnableVertexAttribArray(0));
//  GL(glEnableVertexAttribArray(1));
//
//  return vao;
//}

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()
{
//#ifndef SHR3D_OPENGL_DRAW_NON_INDEXED
  Global::staticDrawVao = setupVao(sizeof(highwayVertices), highwayVertices, sizeof(highwayIndices), highwayIndices);
//#else // SHR3D_OPENGL_DRAW_NON_INDEXED
//  Global::staticDrawVao = setupVao(sizeof(highwayVertices), highwayVertices);
//#endif // SHR3D_OPENGL_DRAW_NON_INDEXED

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