package speiger.src.coreengine.rendering.models.buffers;

import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL33;

import speiger.src.coreengine.rendering.utils.values.GLDataType;

public record BufferAttribute(int index, int size, GLDataType type, boolean normal, int instancedAmount) {
	public BufferAttribute(int index, int size) {
		this(index, size, GLDataType.FLOAT, false, 0);
	}
	
	public BufferAttribute(int index, int size, GLDataType type) {
		this(index, size, type, false, 0);
	}
	
	public BufferAttribute(int index, int size, GLDataType type, boolean normal) {
		this(index, size, type, normal, 0);
	}
	
	public BufferAttribute(int index, int size, GLDataType type, int instancedAmount) {
		this(index, size, type, false, instancedAmount);
	}
	
	public static BufferAttribute[] array(int startIndex, int width, int size, GLDataType type) { return array(startIndex, width, size, type, false, 0); }
	public static BufferAttribute[] array(int startIndex, int width, int size, GLDataType type, boolean normal) { return array(startIndex, width, size, type, normal, 0); }
	public static BufferAttribute[] array(int startIndex, int width, int size, GLDataType type, int instanceAmount) { return array(startIndex, width, size, type, false, instanceAmount); }
	public static BufferAttribute[] array(int startIndex, int width, int size, GLDataType type, boolean normal, int instancedAmount) { 
		BufferAttribute[] attributes = new BufferAttribute[width];
		for(int i = 0;i < width;i++) {
			attributes[i] = new BufferAttribute(startIndex + i, size, type, normal, instancedAmount);
		}
		return attributes;
	}
	
	public void bind() { GL20.glEnableVertexAttribArray(index); }
	public void unbind() { GL20.glDisableVertexAttribArray(index); }
	
	public void applyAttribute(int stride, int offset) {
		GL20.glVertexAttribPointer(index, size, type.glValue(), normal, stride, offset);
		if(instancedAmount > 0) GL33.glVertexAttribDivisor(index, instancedAmount);
	}
}
