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

import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.resources.ResourceLocation
import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty

data class StretchingRectangleElement(
	val topLeft: AbstractMatterySprite,
	val topRight: AbstractMatterySprite,
	val bottomLeft: AbstractMatterySprite,
	val bottomRight: AbstractMatterySprite,
	val left: AbstractMatterySprite,
	val right: AbstractMatterySprite,
	val top: AbstractMatterySprite,
	val bottom: AbstractMatterySprite,
	val middle: AbstractMatterySprite,
	val padding: DockProperty = DockProperty.EMPTY
) {
	fun render(
		stack: PoseStack,
		x: Float = 0f,
		y: Float = 0f,
		width: Float,
		height: Float,
	) {
		val bgWidth = width - topLeft.width.coerceAtMost(bottomLeft.width) - topRight.width.coerceAtMost(bottomRight.width) - padding.left - padding.right
		val bgHeight = height - topLeft.height.coerceAtMost(bottomLeft.height) - topRight.height.coerceAtMost(bottomRight.height) - padding.top - padding.bottom

		if (bgWidth > 0 && bgHeight > 0) {
			middle.render(stack, x + topLeft.width + padding.left, y + topLeft.height + padding.top, bgWidth, bgHeight)
		}

		top.render(stack, x + topLeft.width, y, width = width - topLeft.width - topRight.width)
		bottom.render(stack, x + bottomLeft.width, y + height - bottom.height, width = width - bottomLeft.width - bottomRight.width)

		left.render(stack, x, y + topLeft.height, height = height - topLeft.height - bottomLeft.height)
		right.render(stack, x + width - right.width, y + topRight.height, height = height - topRight.height - bottomRight.height)

		topLeft.render(stack, x, y)
		topRight.render(stack, x + width - topRight.width, y)

		bottomLeft.render(stack, x, y + height - bottomLeft.height)
		bottomRight.render(stack, x + width - bottomRight.width, y + height - bottomLeft.height)
	}

	@JvmOverloads
	fun render(
		graphics: GuiGraphics,
		x: Float = 0f,
		y: Float = 0f,
		width: Float,
		height: Float,
	) = render(graphics.pose(), x, y, width, height)

	companion object {
		fun square(
			texture: ResourceLocation,
			x: Float,
			y: Float,
			cornerWidth: Float,
			cornerHeight: Float,
			width: Float,
			height: Float,
			sideThickness: Float,
			imageWidth: Float = 256f,
			imageHeight: Float = 256f,
		): StretchingRectangleElement {
			val innerThickness = sideThickness.coerceAtLeast(cornerWidth).coerceAtLeast(cornerHeight)
			val padding = sideThickness - innerThickness

			return StretchingRectangleElement(
				topLeft = texture.sprite(x, y, cornerWidth, cornerHeight, imageWidth, imageHeight),
				topRight = texture.sprite(
					x + width - cornerWidth,
					y,
					cornerWidth,
					cornerHeight,
					imageWidth,
					imageHeight
				),
				bottomLeft = texture.sprite(
					x,
					y + height - cornerHeight,
					cornerWidth,
					cornerHeight,
					imageWidth,
					imageHeight
				),
				bottomRight = texture.sprite(
					x + width - cornerWidth,
					y + height - cornerHeight,
					cornerWidth,
					cornerHeight,
					imageWidth,
					imageHeight
				),

				top = texture.sprite(
					x + cornerWidth,
					y,
					width - cornerWidth * 2f,
					sideThickness,
					imageWidth,
					imageHeight
				),
				bottom = texture.sprite(
					x + cornerWidth,
					y + height - sideThickness,
					width - cornerWidth * 2f,
					sideThickness,
					imageWidth,
					imageHeight
				),
				left = texture.sprite(x, y, sideThickness, height - cornerHeight * 2f, imageWidth, imageHeight),
				right = texture.sprite(
					x,
					y + width - sideThickness,
					sideThickness,
					height - cornerHeight * 2f,
					imageWidth,
					imageHeight
				),

				middle = texture.sprite(
					x + innerThickness,
					y + innerThickness,
					width - innerThickness * 2f,
					height - innerThickness * 2f,
					imageWidth,
					imageHeight
				),
				padding = DockProperty(padding, padding, padding, padding)
			)
		}
	}
}
