/*
 * Decompiled with CFR 0.152.
 * 
 * Could not load the following classes:
 *  net.minecraft.class_1922
 *  net.minecraft.class_2338
 *  net.minecraft.class_2338$class_2339
 *  net.minecraft.class_2350
 *  net.minecraft.class_2350$class_2351
 *  net.minecraft.class_259
 *  net.minecraft.class_265
 *  net.minecraft.class_2680
 */
package meteordevelopment.meteorclient.systems.modules.render.blockesp;

import meteordevelopment.meteorclient.MeteorClient;
import meteordevelopment.meteorclient.events.render.Render3DEvent;
import meteordevelopment.meteorclient.renderer.ShapeMode;
import meteordevelopment.meteorclient.systems.modules.Modules;
import meteordevelopment.meteorclient.systems.modules.render.blockesp.BlockESP;
import meteordevelopment.meteorclient.systems.modules.render.blockesp.ESPBlockData;
import meteordevelopment.meteorclient.systems.modules.render.blockesp.ESPGroup;
import meteordevelopment.meteorclient.utils.render.color.SettingColor;
import net.minecraft.class_1922;
import net.minecraft.class_2338;
import net.minecraft.class_2350;
import net.minecraft.class_259;
import net.minecraft.class_265;
import net.minecraft.class_2680;

public class ESPBlock {
    private static final class_2338.class_2339 blockPos = new class_2338.class_2339();
    private static final BlockESP blockEsp = Modules.get().get(BlockESP.class);
    public static final int FO = 2;
    public static final int FO_RI = 4;
    public static final int RI = 8;
    public static final int BA_RI = 16;
    public static final int BA = 32;
    public static final int BA_LE = 64;
    public static final int LE = 128;
    public static final int FO_LE = 256;
    public static final int TO = 512;
    public static final int TO_FO = 1024;
    public static final int TO_BA = 2048;
    public static final int TO_RI = 4096;
    public static final int TO_LE = 8192;
    public static final int BO = 16384;
    public static final int BO_FO = 32768;
    public static final int BO_BA = 65536;
    public static final int BO_RI = 131072;
    public static final int BO_LE = 262144;
    public static final int[] SIDES = new int[]{2, 32, 128, 8, 512, 16384};
    public final int x;
    public final int y;
    public final int z;
    private class_2680 state;
    public int neighbours;
    public ESPGroup group;
    public boolean loaded = true;

    public ESPBlock(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public ESPBlock getSideBlock(int side) {
        return switch (side) {
            case 2 -> blockEsp.getBlock(this.x, this.y, this.z + 1);
            case 32 -> blockEsp.getBlock(this.x, this.y, this.z - 1);
            case 128 -> blockEsp.getBlock(this.x - 1, this.y, this.z);
            case 8 -> blockEsp.getBlock(this.x + 1, this.y, this.z);
            case 512 -> blockEsp.getBlock(this.x, this.y + 1, this.z);
            case 16384 -> blockEsp.getBlock(this.x, this.y - 1, this.z);
            default -> null;
        };
    }

    private void assignGroup() {
        ESPGroup firstGroup = null;
        for (int side : SIDES) {
            ESPBlock neighbour;
            if ((this.neighbours & side) != side || (neighbour = this.getSideBlock(side)) == null || neighbour.group == null) continue;
            if (firstGroup == null) {
                firstGroup = neighbour.group;
                continue;
            }
            if (firstGroup == neighbour.group) continue;
            firstGroup.merge(neighbour.group);
        }
        if (firstGroup == null) {
            firstGroup = blockEsp.newGroup(this.state.method_26204());
        }
        firstGroup.add(this);
    }

    public void update() {
        this.state = MeteorClient.mc.field_1687.method_8320((class_2338)blockPos.method_10103(this.x, this.y, this.z));
        this.neighbours = 0;
        if (this.isNeighbour(class_2350.field_11035)) {
            this.neighbours |= 2;
        }
        if (this.isNeighbourDiagonal(1.0, 0.0, 1.0)) {
            this.neighbours |= 4;
        }
        if (this.isNeighbour(class_2350.field_11034)) {
            this.neighbours |= 8;
        }
        if (this.isNeighbourDiagonal(1.0, 0.0, -1.0)) {
            this.neighbours |= 0x10;
        }
        if (this.isNeighbour(class_2350.field_11043)) {
            this.neighbours |= 0x20;
        }
        if (this.isNeighbourDiagonal(-1.0, 0.0, -1.0)) {
            this.neighbours |= 0x40;
        }
        if (this.isNeighbour(class_2350.field_11039)) {
            this.neighbours |= 0x80;
        }
        if (this.isNeighbourDiagonal(-1.0, 0.0, 1.0)) {
            this.neighbours |= 0x100;
        }
        if (this.isNeighbour(class_2350.field_11036)) {
            this.neighbours |= 0x200;
        }
        if (this.isNeighbourDiagonal(0.0, 1.0, 1.0)) {
            this.neighbours |= 0x400;
        }
        if (this.isNeighbourDiagonal(0.0, 1.0, -1.0)) {
            this.neighbours |= 0x800;
        }
        if (this.isNeighbourDiagonal(1.0, 1.0, 0.0)) {
            this.neighbours |= 0x1000;
        }
        if (this.isNeighbourDiagonal(-1.0, 1.0, 0.0)) {
            this.neighbours |= 0x2000;
        }
        if (this.isNeighbour(class_2350.field_11033)) {
            this.neighbours |= 0x4000;
        }
        if (this.isNeighbourDiagonal(0.0, -1.0, 1.0)) {
            this.neighbours |= 0x8000;
        }
        if (this.isNeighbourDiagonal(0.0, -1.0, -1.0)) {
            this.neighbours |= 0x10000;
        }
        if (this.isNeighbourDiagonal(1.0, -1.0, 0.0)) {
            this.neighbours |= 0x20000;
        }
        if (this.isNeighbourDiagonal(-1.0, -1.0, 0.0)) {
            this.neighbours |= 0x40000;
        }
        if (this.group == null) {
            this.assignGroup();
        }
    }

    private boolean isNeighbour(class_2350 dir) {
        blockPos.method_10103(this.x + dir.method_10148(), this.y + dir.method_10164(), this.z + dir.method_10165());
        class_2680 neighbourState = MeteorClient.mc.field_1687.method_8320((class_2338)blockPos);
        if (neighbourState.method_26204() != this.state.method_26204()) {
            return false;
        }
        class_265 cube = class_259.method_1077();
        class_265 shape = this.state.method_26218((class_1922)MeteorClient.mc.field_1687, (class_2338)blockPos);
        class_265 neighbourShape = neighbourState.method_26218((class_1922)MeteorClient.mc.field_1687, (class_2338)blockPos);
        if (shape.method_1110()) {
            shape = cube;
        }
        if (neighbourShape.method_1110()) {
            neighbourShape = cube;
        }
        switch (dir) {
            case field_11035: {
                if (shape.method_1105(class_2350.class_2351.field_11051) != 1.0 || neighbourShape.method_1091(class_2350.class_2351.field_11051) != 0.0) break;
                return true;
            }
            case field_11043: {
                if (shape.method_1091(class_2350.class_2351.field_11051) != 0.0 || neighbourShape.method_1105(class_2350.class_2351.field_11051) != 1.0) break;
                return true;
            }
            case field_11034: {
                if (shape.method_1105(class_2350.class_2351.field_11048) != 1.0 || neighbourShape.method_1091(class_2350.class_2351.field_11048) != 0.0) break;
                return true;
            }
            case field_11039: {
                if (shape.method_1091(class_2350.class_2351.field_11048) != 0.0 || neighbourShape.method_1105(class_2350.class_2351.field_11048) != 1.0) break;
                return true;
            }
            case field_11036: {
                if (shape.method_1105(class_2350.class_2351.field_11052) != 1.0 || neighbourShape.method_1091(class_2350.class_2351.field_11052) != 0.0) break;
                return true;
            }
            case field_11033: {
                if (shape.method_1091(class_2350.class_2351.field_11052) != 0.0 || neighbourShape.method_1105(class_2350.class_2351.field_11052) != 1.0) break;
                return true;
            }
        }
        return false;
    }

    private boolean isNeighbourDiagonal(double x, double y, double z) {
        blockPos.method_10102((double)this.x + x, (double)this.y + y, (double)this.z + z);
        return this.state.method_26204() == MeteorClient.mc.field_1687.method_8320((class_2338)blockPos).method_26204();
    }

    public void render(Render3DEvent event) {
        double x1 = this.x;
        double y1 = this.y;
        double z1 = this.z;
        double x2 = this.x + 1;
        double y2 = this.y + 1;
        double z2 = this.z + 1;
        class_265 shape = this.state.method_26218((class_1922)MeteorClient.mc.field_1687, (class_2338)blockPos);
        if (!shape.method_1110()) {
            x1 = (double)this.x + shape.method_1091(class_2350.class_2351.field_11048);
            y1 = (double)this.y + shape.method_1091(class_2350.class_2351.field_11052);
            z1 = (double)this.z + shape.method_1091(class_2350.class_2351.field_11051);
            x2 = (double)this.x + shape.method_1105(class_2350.class_2351.field_11048);
            y2 = (double)this.y + shape.method_1105(class_2350.class_2351.field_11052);
            z2 = (double)this.z + shape.method_1105(class_2350.class_2351.field_11051);
        }
        ESPBlockData blockData = blockEsp.getBlockData(this.state.method_26204());
        ShapeMode shapeMode = blockData.shapeMode;
        SettingColor lineColor = blockData.lineColor;
        SettingColor sideColor = blockData.sideColor;
        if (this.neighbours == 0) {
            event.renderer.box(x1, y1, z1, x2, y2, z2, sideColor, lineColor, shapeMode, 0);
        } else {
            if (shapeMode.lines()) {
                if ((this.neighbours & 0x80) != 128 && (this.neighbours & 0x20) != 32 || (this.neighbours & 0x80) == 128 && (this.neighbours & 0x20) == 32 && (this.neighbours & 0x40) != 64) {
                    event.renderer.line(x1, y1, z1, x1, y2, z1, lineColor);
                }
                if ((this.neighbours & 0x80) != 128 && (this.neighbours & 2) != 2 || (this.neighbours & 0x80) == 128 && (this.neighbours & 2) == 2 && (this.neighbours & 0x100) != 256) {
                    event.renderer.line(x1, y1, z2, x1, y2, z2, lineColor);
                }
                if ((this.neighbours & 8) != 8 && (this.neighbours & 0x20) != 32 || (this.neighbours & 8) == 8 && (this.neighbours & 0x20) == 32 && (this.neighbours & 0x10) != 16) {
                    event.renderer.line(x2, y1, z1, x2, y2, z1, lineColor);
                }
                if ((this.neighbours & 8) != 8 && (this.neighbours & 2) != 2 || (this.neighbours & 8) == 8 && (this.neighbours & 2) == 2 && (this.neighbours & 4) != 4) {
                    event.renderer.line(x2, y1, z2, x2, y2, z2, lineColor);
                }
                if ((this.neighbours & 0x20) != 32 && (this.neighbours & 0x4000) != 16384 || (this.neighbours & 0x20) != 32 && (this.neighbours & 0x10000) == 65536) {
                    event.renderer.line(x1, y1, z1, x2, y1, z1, lineColor);
                }
                if ((this.neighbours & 2) != 2 && (this.neighbours & 0x4000) != 16384 || (this.neighbours & 2) != 2 && (this.neighbours & 0x8000) == 32768) {
                    event.renderer.line(x1, y1, z2, x2, y1, z2, lineColor);
                }
                if ((this.neighbours & 0x20) != 32 && (this.neighbours & 0x200) != 512 || (this.neighbours & 0x20) != 32 && (this.neighbours & 0x800) == 2048) {
                    event.renderer.line(x1, y2, z1, x2, y2, z1, lineColor);
                }
                if ((this.neighbours & 2) != 2 && (this.neighbours & 0x200) != 512 || (this.neighbours & 2) != 2 && (this.neighbours & 0x400) == 1024) {
                    event.renderer.line(x1, y2, z2, x2, y2, z2, lineColor);
                }
                if ((this.neighbours & 0x80) != 128 && (this.neighbours & 0x4000) != 16384 || (this.neighbours & 0x80) != 128 && (this.neighbours & 0x40000) == 262144) {
                    event.renderer.line(x1, y1, z1, x1, y1, z2, lineColor);
                }
                if ((this.neighbours & 8) != 8 && (this.neighbours & 0x4000) != 16384 || (this.neighbours & 8) != 8 && (this.neighbours & 0x20000) == 131072) {
                    event.renderer.line(x2, y1, z1, x2, y1, z2, lineColor);
                }
                if ((this.neighbours & 0x80) != 128 && (this.neighbours & 0x200) != 512 || (this.neighbours & 0x80) != 128 && (this.neighbours & 0x2000) == 8192) {
                    event.renderer.line(x1, y2, z1, x1, y2, z2, lineColor);
                }
                if ((this.neighbours & 8) != 8 && (this.neighbours & 0x200) != 512 || (this.neighbours & 8) != 8 && (this.neighbours & 0x1000) == 4096) {
                    event.renderer.line(x2, y2, z1, x2, y2, z2, lineColor);
                }
            }
            if (shapeMode.sides()) {
                if ((this.neighbours & 0x4000) != 16384) {
                    event.renderer.quadHorizontal(x1, y1, z1, x2, z2, sideColor);
                }
                if ((this.neighbours & 0x200) != 512) {
                    event.renderer.quadHorizontal(x1, y2, z1, x2, z2, sideColor);
                }
                if ((this.neighbours & 2) != 2) {
                    event.renderer.quadVertical(x1, y1, z2, x2, y2, z2, sideColor);
                }
                if ((this.neighbours & 0x20) != 32) {
                    event.renderer.quadVertical(x1, y1, z1, x2, y2, z1, sideColor);
                }
                if ((this.neighbours & 8) != 8) {
                    event.renderer.quadVertical(x2, y1, z1, x2, y2, z2, sideColor);
                }
                if ((this.neighbours & 0x80) != 128) {
                    event.renderer.quadVertical(x1, y1, z1, x1, y2, z2, sideColor);
                }
            }
        }
    }

    public static long getKey(int x, int y, int z) {
        return (long)y << 16 | (long)(z & 0xF) << 8 | (long)(x & 0xF);
    }

    public static long getKey(class_2338 blockPos) {
        return ESPBlock.getKey(blockPos.method_10263(), blockPos.method_10264(), blockPos.method_10260());
    }
}

