package ocelot.desktop.graphics.mesh

import ocelot.desktop.graphics.ShaderProgram
import ocelot.desktop.graphics.buffer.{IndexBuffer, VertexBuffer}
import ocelot.desktop.util.{Logging, Resource}
import org.lwjgl.opengl._

class VertexArray(shader: ShaderProgram) extends Logging with Resource {
  private val isMacOS = GLContext.getCapabilities.GL_APPLE_vertex_array_object
  private var indexBuffer: Option[IndexBuffer] = None

  val array: Int = if (isMacOS)
    APPLEVertexArrayObject.glGenVertexArraysAPPLE()
  else
    ARBVertexArrayObject.glGenVertexArrays()

  def addVertexBuffer[V <: Vertex](buffer: VertexBuffer[V], instanced: Boolean = false): Unit = {
    bind()

    for (attr <- buffer.ty.attributes) {
      val location = shader.getAttributeLocation(attr.name)

      buffer.bind()
      GL20.glEnableVertexAttribArray(location)
      GL20.glVertexAttribPointer(location, attr.size, attr.ty, attr.normalized, attr.stride, attr.pointer)

      if (instanced) ARBInstancedArrays.glVertexAttribDivisorARB(location, 1)
    }
  }

  def addIndexBuffer(buffer: IndexBuffer): Unit = {
    bind()
    buffer.bind()
    indexBuffer = Some(buffer)
  }

  def bind(): Unit = {
    if (isMacOS)
      APPLEVertexArrayObject.glBindVertexArrayAPPLE(array)
    else
      ARBVertexArrayObject.glBindVertexArray(array)

    indexBuffer.foreach(_.bind())
  }

  override def freeResource(): Unit = {
    super.freeResource()
    if (isMacOS)
      APPLEVertexArrayObject.glDeleteVertexArraysAPPLE(array)
    else
      ARBVertexArrayObject.glDeleteVertexArrays(array)
  }
}
