package ru.dbotthepony.mc.otm.client.render

import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.Tesselator
import com.mojang.blaze3d.vertex.VertexConsumer
import net.minecraft.core.Vec3i
import org.joml.Matrix3f
import org.joml.Matrix4f
import org.joml.Vector3f
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.core.math.IAngle
import ru.dbotthepony.mc.otm.core.math.Vector
import ru.dbotthepony.mc.otm.core.math.rotateAroundPoint
import ru.dbotthepony.mc.otm.core.math.rotateAroundThis
import ru.dbotthepony.mc.otm.core.math.translation

val tesselator: Tesselator get() = Tesselator.getInstance()

// what meth have you been smoking, mojang, with new names
fun VertexConsumer.vertex(matrix4f: Matrix4f, x: Float, y: Float, z: Float): VertexConsumer = addVertex(matrix4f, x, y, z)
fun VertexConsumer.vertex(poseStack: PoseStack, x: Float, y: Float, z: Float): VertexConsumer = addVertex(poseStack.last.pose, x, y, z)
fun VertexConsumer.vertex(x: Float, y: Float, z: Float): VertexConsumer = addVertex(x, y, z)
fun VertexConsumer.uv(u: Float, v: Float): VertexConsumer = setUv(u, v)
fun VertexConsumer.overlayCoords(coords: Int): VertexConsumer = setOverlay(coords)
fun VertexConsumer.light(coords: Int): VertexConsumer = setLight(coords)

fun VertexConsumer.normal(vector: Vector): VertexConsumer = setNormal(vector.x.toFloat(), vector.y.toFloat(), vector.z.toFloat())
fun VertexConsumer.normal(pose: PoseStack.Pose, vector: Vector): VertexConsumer = setNormal(pose, vector.x.toFloat(), vector.y.toFloat(), vector.z.toFloat())
fun VertexConsumer.normal(x: Float, y: Float, z: Float): VertexConsumer = setNormal(x, y, z)
fun VertexConsumer.normal(pose: PoseStack.Pose, x: Float, y: Float, z: Float): VertexConsumer = setNormal(pose, x, y, z)
fun VertexConsumer.vertex(matrix4f: Matrix4f, vector: Vector): VertexConsumer = vertex(matrix4f, vector.x.toFloat(), vector.y.toFloat(), vector.z.toFloat())
fun VertexConsumer.color(color: RGBAColor?): VertexConsumer {
	if (color != null)
		setColor(color.redInt, color.greenInt, color.blueInt, color.alphaInt)

	return this
}

fun VertexConsumer.color(r: Float, g: Float, b: Float, a: Float): VertexConsumer {
	return setColor(r, g, b, a)
}

fun PoseStack.translate(vector: Vector) = translate(vector.x, vector.y, vector.z)
fun PoseStack.translate(vector: Vec3i) = translate(vector.x.toDouble(), vector.y.toDouble(), vector.z.toDouble())
fun PoseStack.translate(vector: Vector3f) = translate(vector.x(), vector.y(), vector.z())

fun PoseStack.rotateAroundPoint(point: Vector, axis: Vector, rotation: Float, isDegrees: Boolean = false) {
	val last = last()
	last.pose().rotateAroundPoint(point, axis, rotation, isDegrees)
	last.normal().rotate(axis.rotateAroundThis(rotation, isDegrees))
}

fun PoseStack.rotateAroundPoint(point: Vector, rotation: IAngle) {
	val last = last()
	last.pose().rotateAroundPoint(point, rotation)
	// last.normal().mul(rotation.forward().rotateAroundThis(rotation))
}

fun PoseStack.rotateAroundPoint(point: Vector3f, axis: Vector, rotation: Float, isDegrees: Boolean = false) {
	val last = last()
	last.pose().rotateAroundPoint(point, axis, rotation, isDegrees)
	last.normal().rotate(axis.rotateAroundThis(rotation, isDegrees))
}

fun PoseStack.rotateAroundPoint(point: Vector3f, rotation: IAngle) {
	val last = last()
	last.pose().rotateAroundPoint(point, rotation)
	// last.normal().mul(rotation.forward().rotateAroundThis(rotation))
}

fun PoseStack.translation(): Vector3f {
	return last().pose().translation
}

inline val PoseStack.last: PoseStack.Pose get() = last()
inline val PoseStack.Pose.pose: Matrix4f get() = pose()
