package me.eater.threedom.gl.vertex

import me.eater.threedom.gl.GL.stack
import org.lwjgl.opengl.GL30.*
import org.lwjgl.system.MemoryUtil
import java.nio.ByteBuffer

open class VertexBuffer<T : VertexData>(
    items: List<T> = listOf(),
    val interleaved: Boolean = false,
    val usage: Int = GL_STATIC_DRAW
) {
    val id: Int = run {
        val pId = stack.mallocInt(1)
        glGenBuffers(pId)
        pId.get(0)
    }

    @Suppress("CanBePrimaryConstructorProperty")
    open val items: List<T> = items
    var stride: Int
        private set

    init {
        val size = items.size * (items.firstOrNull()?.length ?: 0).also { stride = it }
        val byteBuffer = MemoryUtil.memAlloc(size)

        var offset = 0
        for (i in items.indices) {
            val item = items[i]

            if (interleaved) {
                item.write(offset, byteBuffer)
                offset += item.length
            } else {
                item.writeNonInterleaved(i, items.size, byteBuffer)
            }
        }

        glBindBuffer(GL_ARRAY_BUFFER, id)
        glBufferData(GL_ARRAY_BUFFER, byteBuffer, usage)
        glBindBuffer(GL_ARRAY_BUFFER, 0)
        MemoryUtil.memFree(byteBuffer)
    }
}
