package net.minecraft.client.render.debug;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.ColorHelper.Argb;
import org.joml.Matrix4f;

@Environment(EnvType.CLIENT)
public class ChunkBorderDebugRenderer implements DebugRenderer.Renderer {
	private final MinecraftClient client;
	private static final int DARK_CYAN = Argb.getArgb(255, 0, 155, 155);
	private static final int YELLOW = Argb.getArgb(255, 255, 255, 0);

	public ChunkBorderDebugRenderer(MinecraftClient client) {
		this.client = client;
	}

	@Override
	public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, double cameraX, double cameraY, double cameraZ) {
		Entity entity = this.client.gameRenderer.getCamera().getFocusedEntity();
		float f = (float)(this.client.world.getBottomY() - cameraY);
		float g = (float)(this.client.world.getTopY() - cameraY);
		ChunkPos chunkPos = entity.getChunkPos();
		float h = (float)(chunkPos.getStartX() - cameraX);
		float i = (float)(chunkPos.getStartZ() - cameraZ);
		VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderLayer.getDebugLineStrip(1.0));
		Matrix4f matrix4f = matrices.peek().getPositionMatrix();

		for (int j = -16; j <= 32; j += 16) {
			for (int k = -16; k <= 32; k += 16) {
				vertexConsumer.vertex(matrix4f, h + j, f, i + k).color(1.0F, 0.0F, 0.0F, 0.0F).next();
				vertexConsumer.vertex(matrix4f, h + j, f, i + k).color(1.0F, 0.0F, 0.0F, 0.5F).next();
				vertexConsumer.vertex(matrix4f, h + j, g, i + k).color(1.0F, 0.0F, 0.0F, 0.5F).next();
				vertexConsumer.vertex(matrix4f, h + j, g, i + k).color(1.0F, 0.0F, 0.0F, 0.0F).next();
			}
		}

		for (int j = 2; j < 16; j += 2) {
			int k = j % 4 == 0 ? DARK_CYAN : YELLOW;
			vertexConsumer.vertex(matrix4f, h + j, f, i).color(1.0F, 1.0F, 0.0F, 0.0F).next();
			vertexConsumer.vertex(matrix4f, h + j, f, i).color(k).next();
			vertexConsumer.vertex(matrix4f, h + j, g, i).color(k).next();
			vertexConsumer.vertex(matrix4f, h + j, g, i).color(1.0F, 1.0F, 0.0F, 0.0F).next();
			vertexConsumer.vertex(matrix4f, h + j, f, i + 16.0F).color(1.0F, 1.0F, 0.0F, 0.0F).next();
			vertexConsumer.vertex(matrix4f, h + j, f, i + 16.0F).color(k).next();
			vertexConsumer.vertex(matrix4f, h + j, g, i + 16.0F).color(k).next();
			vertexConsumer.vertex(matrix4f, h + j, g, i + 16.0F).color(1.0F, 1.0F, 0.0F, 0.0F).next();
		}

		for (int j = 2; j < 16; j += 2) {
			int k = j % 4 == 0 ? DARK_CYAN : YELLOW;
			vertexConsumer.vertex(matrix4f, h, f, i + j).color(1.0F, 1.0F, 0.0F, 0.0F).next();
			vertexConsumer.vertex(matrix4f, h, f, i + j).color(k).next();
			vertexConsumer.vertex(matrix4f, h, g, i + j).color(k).next();
			vertexConsumer.vertex(matrix4f, h, g, i + j).color(1.0F, 1.0F, 0.0F, 0.0F).next();
			vertexConsumer.vertex(matrix4f, h + 16.0F, f, i + j).color(1.0F, 1.0F, 0.0F, 0.0F).next();
			vertexConsumer.vertex(matrix4f, h + 16.0F, f, i + j).color(k).next();
			vertexConsumer.vertex(matrix4f, h + 16.0F, g, i + j).color(k).next();
			vertexConsumer.vertex(matrix4f, h + 16.0F, g, i + j).color(1.0F, 1.0F, 0.0F, 0.0F).next();
		}

		for (int j = this.client.world.getBottomY(); j <= this.client.world.getTopY(); j += 2) {
			float l = (float)(j - cameraY);
			int m = j % 8 == 0 ? DARK_CYAN : YELLOW;
			vertexConsumer.vertex(matrix4f, h, l, i).color(1.0F, 1.0F, 0.0F, 0.0F).next();
			vertexConsumer.vertex(matrix4f, h, l, i).color(m).next();
			vertexConsumer.vertex(matrix4f, h, l, i + 16.0F).color(m).next();
			vertexConsumer.vertex(matrix4f, h + 16.0F, l, i + 16.0F).color(m).next();
			vertexConsumer.vertex(matrix4f, h + 16.0F, l, i).color(m).next();
			vertexConsumer.vertex(matrix4f, h, l, i).color(m).next();
			vertexConsumer.vertex(matrix4f, h, l, i).color(1.0F, 1.0F, 0.0F, 0.0F).next();
		}

		vertexConsumer = vertexConsumers.getBuffer(RenderLayer.getDebugLineStrip(2.0));

		for (int j = 0; j <= 16; j += 16) {
			for (int k = 0; k <= 16; k += 16) {
				vertexConsumer.vertex(matrix4f, h + j, f, i + k).color(0.25F, 0.25F, 1.0F, 0.0F).next();
				vertexConsumer.vertex(matrix4f, h + j, f, i + k).color(0.25F, 0.25F, 1.0F, 1.0F).next();
				vertexConsumer.vertex(matrix4f, h + j, g, i + k).color(0.25F, 0.25F, 1.0F, 1.0F).next();
				vertexConsumer.vertex(matrix4f, h + j, g, i + k).color(0.25F, 0.25F, 1.0F, 0.0F).next();
			}
		}

		for (int j = this.client.world.getBottomY(); j <= this.client.world.getTopY(); j += 16) {
			float l = (float)(j - cameraY);
			vertexConsumer.vertex(matrix4f, h, l, i).color(0.25F, 0.25F, 1.0F, 0.0F).next();
			vertexConsumer.vertex(matrix4f, h, l, i).color(0.25F, 0.25F, 1.0F, 1.0F).next();
			vertexConsumer.vertex(matrix4f, h, l, i + 16.0F).color(0.25F, 0.25F, 1.0F, 1.0F).next();
			vertexConsumer.vertex(matrix4f, h + 16.0F, l, i + 16.0F).color(0.25F, 0.25F, 1.0F, 1.0F).next();
			vertexConsumer.vertex(matrix4f, h + 16.0F, l, i).color(0.25F, 0.25F, 1.0F, 1.0F).next();
			vertexConsumer.vertex(matrix4f, h, l, i).color(0.25F, 0.25F, 1.0F, 1.0F).next();
			vertexConsumer.vertex(matrix4f, h, l, i).color(0.25F, 0.25F, 1.0F, 0.0F).next();
		}
	}
}
