/*
 * Decompiled with CFR 0.152.
 * 
 * Could not load the following classes:
 *  it.unimi.dsi.fastutil.objects.ObjectArrayList
 *  meteordevelopment.orbit.EventHandler
 *  net.irisshaders.iris.api.v0.IrisApi
 *  net.minecraft.class_1799
 *  net.minecraft.class_2338
 *  net.minecraft.class_2338$class_2339
 *  net.minecraft.class_2382
 *  net.minecraft.class_243
 *  net.minecraft.class_332
 *  org.joml.Matrix3x2fStack
 *  org.joml.Matrix4f
 *  org.joml.Matrix4fc
 *  org.joml.Vector4f
 */
package meteordevelopment.meteorclient.utils.render;

import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List;
import meteordevelopment.meteorclient.MeteorClient;
import meteordevelopment.meteorclient.events.render.Render3DEvent;
import meteordevelopment.meteorclient.events.world.TickEvent;
import meteordevelopment.meteorclient.renderer.Renderer2D;
import meteordevelopment.meteorclient.renderer.ShapeMode;
import meteordevelopment.meteorclient.utils.PostInit;
import meteordevelopment.meteorclient.utils.misc.Pool;
import meteordevelopment.meteorclient.utils.render.color.Color;
import meteordevelopment.orbit.EventHandler;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.class_1799;
import net.minecraft.class_2338;
import net.minecraft.class_2382;
import net.minecraft.class_243;
import net.minecraft.class_332;
import org.joml.Matrix3x2fStack;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Vector4f;

public class RenderUtils {
    public static class_243 center;
    public static final Matrix4f projection;
    private static final Pool<RenderBlock> renderBlockPool;
    private static final List<RenderBlock> renderBlocks;

    private RenderUtils() {
    }

    @PostInit
    public static void init() {
        MeteorClient.EVENT_BUS.subscribe(RenderUtils.class);
    }

    public static boolean isShaderPackInUse() {
        return IrisApi.getInstance().isShaderPackInUse();
    }

    public static void drawItem(class_332 drawContext, class_1799 itemStack, int x, int y, float scale, boolean overlay, String countOverride, boolean disableGuiScale) {
        Matrix3x2fStack matrices = drawContext.method_51448();
        matrices.pushMatrix();
        if (disableGuiScale) {
            matrices.scale(1.0f / (float)MeteorClient.mc.method_22683().method_4495());
        }
        matrices.scale(scale, scale);
        int scaledX = (int)((float)x / scale);
        int scaledY = (int)((float)y / scale);
        drawContext.method_51427(itemStack, scaledX, scaledY);
        if (overlay) {
            drawContext.method_51432(MeteorClient.mc.field_1772, itemStack, scaledX, scaledY, countOverride);
        }
        matrices.popMatrix();
    }

    public static void drawItem(class_332 drawContext, class_1799 itemStack, int x, int y, float scale, boolean overlay) {
        RenderUtils.drawItem(drawContext, itemStack, x, y, scale, overlay, null, true);
    }

    public static void renderRoundedQuad(Matrix3x2fStack matrices, java.awt.Color color, double x1, double y1, double x2, double y2, double radius, double samples) {
        Color c = new Color(color);
        if (radius <= 0.0) {
            Renderer2D.COLOR.begin();
            Renderer2D.COLOR.quad(x1, y1, x2 - x1, y2 - y1, c);
            Renderer2D.COLOR.end();
            Renderer2D.COLOR.render();
            return;
        }
        Renderer2D.COLOR.begin();
        double rad = Math.toRadians(90.0 / samples);
        Renderer2D.COLOR.quad(x1 + radius, y1 + radius, x2 - x1 - radius * 2.0, y2 - y1 - radius * 2.0, c);
        Renderer2D.COLOR.quad(x1 + radius, y1, x2 - x1 - radius * 2.0, radius, c);
        Renderer2D.COLOR.quad(x1 + radius, y2 - radius, x2 - x1 - radius * 2.0, radius, c);
        Renderer2D.COLOR.quad(x1, y1 + radius, radius, y2 - y1 - radius * 2.0, c);
        Renderer2D.COLOR.quad(x2 - radius, y1 + radius, radius, y2 - y1 - radius * 2.0, c);
        int i = 0;
        while ((double)i < samples) {
            double a1 = (double)i * rad;
            double a2 = (double)(i + 1) * rad;
            double s1 = Math.sin(a1) * radius;
            double c1 = Math.cos(a1) * radius;
            double s2 = Math.sin(a2) * radius;
            double c2 = Math.cos(a2) * radius;
            Renderer2D.COLOR.triangle(x1 + radius, y1 + radius, x1 + radius - c1, y1 + radius - s1, x1 + radius - c2, y1 + radius - s2, c);
            Renderer2D.COLOR.triangle(x2 - radius, y1 + radius, x2 - radius + s1, y1 + radius - c1, x2 - radius + s2, y1 + radius - c2, c);
            Renderer2D.COLOR.triangle(x2 - radius, y2 - radius, x2 - radius + c1, y2 - radius + s1, x2 - radius + c2, y2 - radius + s2, c);
            Renderer2D.COLOR.triangle(x1 + radius, y2 - radius, x1 + radius - s1, y2 - radius + c1, x1 + radius - s2, y2 - radius + c2, c);
            ++i;
        }
        Renderer2D.COLOR.end();
        Renderer2D.COLOR.render();
    }

    public static void renderRoundedOutline(class_332 context, java.awt.Color color, double x1, double y1, double x2, double y2, double r1, double r2, double r3, double r4, double width, double samples) {
        Color c = new Color(color);
        Renderer2D.COLOR.begin();
        double radStep = Math.toRadians(90.0 / samples);
        Renderer2D.COLOR.line(x1 + r1, y1, x2 - r2, y1, c);
        Renderer2D.COLOR.line(x1 + r4, y2, x2 - r3, y2, c);
        Renderer2D.COLOR.line(x1, y1 + r1, x1, y2 - r4, c);
        Renderer2D.COLOR.line(x2, y1 + r2, x2, y2 - r3, c);
        int i = 0;
        while ((double)i < samples) {
            double a1 = (double)i * radStep;
            double a2 = (double)(i + 1) * radStep;
            Renderer2D.COLOR.line(x1 + r1 - Math.cos(a1) * r1, y1 + r1 - Math.sin(a1) * r1, x1 + r1 - Math.cos(a2) * r1, y1 + r1 - Math.sin(a2) * r1, c);
            Renderer2D.COLOR.line(x2 - r2 + Math.sin(a1) * r2, y1 + r2 - Math.cos(a1) * r2, x2 - r2 + Math.sin(a2) * r2, y1 + r2 - Math.cos(a2) * r2, c);
            Renderer2D.COLOR.line(x2 - r3 + Math.cos(a1) * r3, y2 - r3 + Math.sin(a1) * r3, x2 - r3 + Math.cos(a2) * r3, y2 - r3 + Math.sin(a2) * r3, c);
            Renderer2D.COLOR.line(x1 + r4 - Math.sin(a1) * r4, y2 - r4 + Math.cos(a1) * r4, x1 + r4 - Math.sin(a2) * r4, y2 - r4 + Math.cos(a2) * r4, c);
            ++i;
        }
        Renderer2D.COLOR.end();
        Renderer2D.COLOR.render();
    }

    public static void updateScreenCenter(Matrix4f projection, Matrix4f view) {
        RenderUtils.projection.set((Matrix4fc)projection);
        Matrix4f invProjection = new Matrix4f((Matrix4fc)projection).invert();
        Matrix4f invView = new Matrix4f((Matrix4fc)view).invert();
        Vector4f center4 = new Vector4f(0.0f, 0.0f, 0.0f, 1.0f).mul((Matrix4fc)invProjection).mul((Matrix4fc)invView);
        center4.div(center4.w);
        class_243 camera = MeteorClient.mc.field_1773.method_19418().method_71156();
        center = new class_243(camera.field_1352 + (double)center4.x, camera.field_1351 + (double)center4.y, camera.field_1350 + (double)center4.z);
    }

    public static void renderTickingBlock(class_2338 blockPos, Color sideColor, Color lineColor, ShapeMode shapeMode, int excludeDir, int duration, boolean fade, boolean shrink) {
        renderBlocks.removeIf(next -> {
            if (next.pos.equals((Object)blockPos)) {
                renderBlockPool.free((RenderBlock)next);
                return true;
            }
            return false;
        });
        renderBlocks.add(renderBlockPool.get().set(blockPos, sideColor, lineColor, shapeMode, excludeDir, duration, fade, shrink));
    }

    @EventHandler
    private static void onTick(TickEvent.Pre event) {
        if (renderBlocks.isEmpty()) {
            return;
        }
        renderBlocks.removeIf(next -> {
            next.tick();
            if (next.ticks <= 0) {
                renderBlockPool.free((RenderBlock)next);
                return true;
            }
            return false;
        });
    }

    @EventHandler
    private static void onRender(Render3DEvent event) {
        renderBlocks.forEach(block -> block.render(event));
    }

    static {
        projection = new Matrix4f();
        renderBlockPool = new Pool<RenderBlock>(RenderBlock::new);
        renderBlocks = new ObjectArrayList();
    }

    public static class RenderBlock {
        public class_2338.class_2339 pos = new class_2338.class_2339();
        public Color sideColor;
        public Color lineColor;
        public ShapeMode shapeMode;
        public int excludeDir;
        public int ticks;
        public int duration;
        public boolean fade;
        public boolean shrink;

        public RenderBlock set(class_2338 blockPos, Color sideColor, Color lineColor, ShapeMode shapeMode, int excludeDir, int duration, boolean fade, boolean shrink) {
            this.pos.method_10101((class_2382)blockPos);
            this.sideColor = sideColor;
            this.lineColor = lineColor;
            this.shapeMode = shapeMode;
            this.excludeDir = excludeDir;
            this.fade = fade;
            this.shrink = shrink;
            this.ticks = duration;
            this.duration = duration;
            return this;
        }

        public void tick() {
            --this.ticks;
        }

        public void render(Render3DEvent event) {
            int preSideA = this.sideColor.a;
            int preLineA = this.lineColor.a;
            double x1 = this.pos.method_10263();
            double y1 = this.pos.method_10264();
            double z1 = this.pos.method_10260();
            double x2 = this.pos.method_10263() + 1;
            double y2 = this.pos.method_10264() + 1;
            double z2 = this.pos.method_10260() + 1;
            double d = (double)((float)this.ticks - event.tickDelta) / (double)this.duration;
            if (this.fade) {
                this.sideColor.a = (int)((double)this.sideColor.a * d);
                this.lineColor.a = (int)((double)this.lineColor.a * d);
            }
            if (this.shrink) {
                x1 += d;
                y1 += d;
                z1 += d;
                x2 -= d;
                y2 -= d;
                z2 -= d;
            }
            event.renderer.box(x1, y1, z1, x2, y2, z2, this.sideColor, this.lineColor, this.shapeMode, this.excludeDir);
            this.sideColor.a = preSideA;
            this.lineColor.a = preLineA;
        }
    }
}

