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.Matrix4f
import org.joml.Vector3f
import ru.dbotthepony.mc.otm.core.math.IAngle
import ru.dbotthepony.mc.otm.core.math.RGBAColor
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()

fun VertexConsumer.normal(vector: Vector): VertexConsumer = normal(vector.x.toFloat(), vector.y.toFloat(), vector.z.toFloat())
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)
		color(color.redInt, color.greenInt, color.blueInt, color.alphaInt)

	return this
}

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()
