package net.minecraft.client.renderer.debug;

import com.mojang.blaze3d.vertex.BufferBuilder;
import net.minecraft.util.Mth;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.Tesselator;
import net.minecraft.world.level.pathfinder.Node;
import net.minecraft.core.BlockPos;
import java.util.Locale;
import net.minecraft.world.phys.AABB;
import com.mojang.blaze3d.systems.RenderSystem;
import java.util.Iterator;
import net.minecraft.client.renderer.MultiBufferSource;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.Util;
import com.google.common.collect.Maps;
import net.minecraft.world.level.pathfinder.Path;
import java.util.Map;

public class PathfindingRenderer implements DebugRenderer.SimpleDebugRenderer {
    private final Map<Integer, Path> pathMap;
    private final Map<Integer, Float> pathMaxDist;
    private final Map<Integer, Long> creationMap;
    
    public PathfindingRenderer() {
        this.pathMap = Maps.newHashMap();
        this.pathMaxDist = Maps.newHashMap();
        this.creationMap = Maps.newHashMap();
    }
    
    public void addPath(final int integer, final Path cqq, final float float3) {
        this.pathMap.put(integer, cqq);
        this.creationMap.put(integer, Util.getMillis());
        this.pathMaxDist.put(integer, float3);
    }
    
    @Override
    public void render(final PoseStack cyl, final MultiBufferSource dqt, final double double3, final double double4, final double double5) {
        if (this.pathMap.isEmpty()) {
            return;
        }
        final long long10 = Util.getMillis();
        for (final Integer integer13 : this.pathMap.keySet()) {
            final Path cqq14 = this.pathMap.get(integer13);
            final float float15 = this.pathMaxDist.get(integer13);
            renderPath(cqq14, float15, true, true, double3, double4, double5);
        }
        for (final Integer integer14 : this.creationMap.keySet().<Integer>toArray(new Integer[0])) {
            if (long10 - this.creationMap.get(integer14) > 5000L) {
                this.pathMap.remove(integer14);
                this.creationMap.remove(integer14);
            }
        }
    }
    
    public static void renderPath(final Path cqq, final float float2, final boolean boolean3, final boolean boolean4, final double double5, final double double6, final double double7) {
        RenderSystem.pushMatrix();
        RenderSystem.enableBlend();
        RenderSystem.defaultBlendFunc();
        RenderSystem.color4f(0.0f, 1.0f, 0.0f, 0.75f);
        RenderSystem.disableTexture();
        RenderSystem.lineWidth(6.0f);
        doRenderPath(cqq, float2, boolean3, boolean4, double5, double6, double7);
        RenderSystem.enableTexture();
        RenderSystem.disableBlend();
        RenderSystem.popMatrix();
    }
    
    private static void doRenderPath(final Path cqq, final float float2, final boolean boolean3, final boolean boolean4, final double double5, final double double6, final double double7) {
        renderPathLine(cqq, double5, double6, double7);
        final BlockPos fk11 = cqq.getTarget();
        if (distanceToCamera(fk11, double5, double6, double7) <= 80.0f) {
            DebugRenderer.renderFilledBox(new AABB(fk11.getX() + 0.25f, fk11.getY() + 0.25f, fk11.getZ() + 0.25, fk11.getX() + 0.75f, fk11.getY() + 0.75f, fk11.getZ() + 0.75f).move(-double5, -double6, -double7), 0.0f, 1.0f, 0.0f, 0.5f);
            for (int integer12 = 0; integer12 < cqq.getSize(); ++integer12) {
                final Node cqo13 = cqq.get(integer12);
                if (distanceToCamera(cqo13.asBlockPos(), double5, double6, double7) <= 80.0f) {
                    final float float3 = (integer12 == cqq.getIndex()) ? 1.0f : 0.0f;
                    final float float4 = (integer12 == cqq.getIndex()) ? 0.0f : 1.0f;
                    DebugRenderer.renderFilledBox(new AABB(cqo13.x + 0.5f - float2, cqo13.y + 0.01f * integer12, cqo13.z + 0.5f - float2, cqo13.x + 0.5f + float2, cqo13.y + 0.25f + 0.01f * integer12, cqo13.z + 0.5f + float2).move(-double5, -double6, -double7), float3, 0.0f, float4, 0.5f);
                }
            }
        }
        if (boolean3) {
            for (final Node cqo14 : cqq.getClosedSet()) {
                if (distanceToCamera(cqo14.asBlockPos(), double5, double6, double7) <= 80.0f) {
                    DebugRenderer.renderFilledBox(new AABB(cqo14.x + 0.5f - float2 / 2.0f, cqo14.y + 0.01f, cqo14.z + 0.5f - float2 / 2.0f, cqo14.x + 0.5f + float2 / 2.0f, cqo14.y + 0.1, cqo14.z + 0.5f + float2 / 2.0f).move(-double5, -double6, -double7), 1.0f, 0.8f, 0.8f, 0.5f);
                }
            }
            for (final Node cqo14 : cqq.getOpenSet()) {
                if (distanceToCamera(cqo14.asBlockPos(), double5, double6, double7) <= 80.0f) {
                    DebugRenderer.renderFilledBox(new AABB(cqo14.x + 0.5f - float2 / 2.0f, cqo14.y + 0.01f, cqo14.z + 0.5f - float2 / 2.0f, cqo14.x + 0.5f + float2 / 2.0f, cqo14.y + 0.1, cqo14.z + 0.5f + float2 / 2.0f).move(-double5, -double6, -double7), 0.8f, 1.0f, 1.0f, 0.5f);
                }
            }
        }
        if (boolean4) {
            for (int integer12 = 0; integer12 < cqq.getSize(); ++integer12) {
                final Node cqo13 = cqq.get(integer12);
                if (distanceToCamera(cqo13.asBlockPos(), double5, double6, double7) <= 80.0f) {
                    DebugRenderer.renderFloatingText(String.format("%s", cqo13.type), cqo13.x + 0.5, cqo13.y + 0.75, cqo13.z + 0.5, -1);
                    DebugRenderer.renderFloatingText(String.format(Locale.ROOT, "%.2f", cqo13.costMalus), cqo13.x + 0.5, cqo13.y + 0.25, cqo13.z + 0.5, -1);
                }
            }
        }
    }
    
    public static void renderPathLine(final Path cqq, final double double2, final double double3, final double double4) {
        final Tesselator cym8 = Tesselator.getInstance();
        final BufferBuilder cyg9 = cym8.getBuilder();
        cyg9.begin(3, DefaultVertexFormat.POSITION_COLOR);
        for (int integer10 = 0; integer10 < cqq.getSize(); ++integer10) {
            final Node cqo11 = cqq.get(integer10);
            if (distanceToCamera(cqo11.asBlockPos(), double2, double3, double4) <= 80.0f) {
                final float float12 = integer10 / (float)cqq.getSize() * 0.33f;
                final int integer11 = (integer10 == 0) ? 0 : Mth.hsvToRgb(float12, 0.9f, 0.9f);
                final int integer12 = integer11 >> 16 & 0xFF;
                final int integer13 = integer11 >> 8 & 0xFF;
                final int integer14 = integer11 & 0xFF;
                cyg9.vertex(cqo11.x - double2 + 0.5, cqo11.y - double3 + 0.5, cqo11.z - double4 + 0.5).color(integer12, integer13, integer14, 255).endVertex();
            }
        }
        cym8.end();
    }
    
    private static float distanceToCamera(final BlockPos fk, final double double2, final double double3, final double double4) {
        return (float)(Math.abs(fk.getX() - double2) + Math.abs(fk.getY() - double3) + Math.abs(fk.getZ() - double4));
    }
}
