/*
 * Decompiled with CFR 0.152.
 * 
 * Could not load the following classes:
 *  meteordevelopment.orbit.EventHandler
 *  net.minecraft.class_1109
 *  net.minecraft.class_1113
 *  net.minecraft.class_1802
 *  net.minecraft.class_1922
 *  net.minecraft.class_1923
 *  net.minecraft.class_1944
 *  net.minecraft.class_2244
 *  net.minecraft.class_2246
 *  net.minecraft.class_2248
 *  net.minecraft.class_2338
 *  net.minecraft.class_2350
 *  net.minecraft.class_2350$class_2351
 *  net.minecraft.class_2480
 *  net.minecraft.class_2482
 *  net.minecraft.class_2510
 *  net.minecraft.class_2680
 *  net.minecraft.class_2741
 *  net.minecraft.class_2769
 *  net.minecraft.class_2818
 *  net.minecraft.class_2826
 *  net.minecraft.class_3414
 *  net.minecraft.class_3417
 *  net.minecraft.class_368
 */
package meteordevelopment.meteorclient.systems.modules.donut;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import meteordevelopment.meteorclient.events.render.Render3DEvent;
import meteordevelopment.meteorclient.events.world.ChunkDataEvent;
import meteordevelopment.meteorclient.renderer.ShapeMode;
import meteordevelopment.meteorclient.settings.BoolSetting;
import meteordevelopment.meteorclient.settings.ColorSetting;
import meteordevelopment.meteorclient.settings.DoubleSetting;
import meteordevelopment.meteorclient.settings.EnumSetting;
import meteordevelopment.meteorclient.settings.IntSetting;
import meteordevelopment.meteorclient.settings.Setting;
import meteordevelopment.meteorclient.settings.SettingGroup;
import meteordevelopment.meteorclient.systems.modules.Categories;
import meteordevelopment.meteorclient.systems.modules.Module;
import meteordevelopment.meteorclient.utils.render.MeteorToast;
import meteordevelopment.meteorclient.utils.render.color.SettingColor;
import meteordevelopment.orbit.EventHandler;
import net.minecraft.class_1109;
import net.minecraft.class_1113;
import net.minecraft.class_1802;
import net.minecraft.class_1922;
import net.minecraft.class_1923;
import net.minecraft.class_1944;
import net.minecraft.class_2244;
import net.minecraft.class_2246;
import net.minecraft.class_2248;
import net.minecraft.class_2338;
import net.minecraft.class_2350;
import net.minecraft.class_2480;
import net.minecraft.class_2482;
import net.minecraft.class_2510;
import net.minecraft.class_2680;
import net.minecraft.class_2741;
import net.minecraft.class_2769;
import net.minecraft.class_2818;
import net.minecraft.class_2826;
import net.minecraft.class_3414;
import net.minecraft.class_3417;
import net.minecraft.class_368;

public class BaseRadar
extends Module {
    private final SettingGroup sgDetection;
    private final SettingGroup sgRender;
    private final Setting<Integer> minScore;
    private final Setting<Boolean> detectWorkstations;
    private final Setting<Boolean> detectStorage;
    private final Setting<Boolean> detectFarming;
    private final Setting<Boolean> detectLighting;
    private final Setting<Boolean> detectPaths;
    private final Setting<Boolean> detectNetherBlocks;
    private final Setting<Boolean> lightAnomalies;
    private final Setting<Boolean> rotatedDeepslate;
    private final Setting<Boolean> airAnomalies;
    private final Setting<Integer> scanRadius;
    private final Setting<Double> renderHeight;
    private final Setting<ShapeMode> shapeMode;
    private final Setting<SettingColor> lowColor;
    private final Setting<SettingColor> highColor;
    private final Setting<Boolean> showScore;
    private final Map<class_1923, Integer> scores;
    private final Set<class_1923> flagged;
    private final Set<class_1923> alreadyNotified;

    public BaseRadar() {
        super(Categories.Donut, "base-radar", "Scans loaded chunks for concentrations of player-placed blocks to locate hidden bases.");
        this.sgDetection = this.settings.createGroup("Detection");
        this.sgRender = this.settings.createGroup("Render");
        this.minScore = this.sgDetection.add(((IntSetting.Builder)((IntSetting.Builder)((IntSetting.Builder)new IntSetting.Builder().name("min-score")).description("Minimum block-score before a chunk is flagged as a potential base. Increase to reduce false positives.")).defaultValue(5)).range(1, 50).sliderRange(1, 30).build());
        this.detectWorkstations = this.sgDetection.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("workstations")).description("Score crafting tables, furnaces, anvils, etc.")).defaultValue(true)).build());
        this.detectStorage = this.sgDetection.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("storage")).description("Score chests, barrels, shulker boxes, etc.")).defaultValue(true)).build());
        this.detectFarming = this.sgDetection.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("farming-blocks")).description("Score farmland, composters, water with crops above.")).defaultValue(true)).build());
        this.detectLighting = this.sgDetection.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("light-sources")).description("Score torches, lanterns, sea lanterns, glowstone, etc.")).defaultValue(true)).build());
        this.detectPaths = this.sgDetection.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("paths")).description("Score gravel paths, slabs, stairs that indicate a player-built structure.")).defaultValue(true)).build());
        this.detectNetherBlocks = this.sgDetection.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("nether-blocks-overworld")).description("In the overworld, flag nether bricks, quartz, etc. as highly suspicious.")).defaultValue(true)).build());
        this.lightAnomalies = this.sgDetection.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("light-anomalies")).description("Detect light in dark deepslate regions (ignoring lava/glow lichen).")).defaultValue(true)).build());
        this.rotatedDeepslate = this.sgDetection.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("rotated-deepslate")).description("Detect player-placed (rotated) deepslate blocks.")).defaultValue(true)).build());
        this.airAnomalies = this.sgDetection.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("unnatural-air")).description("Detect air pockets deep underground that don't match cave patterns.")).defaultValue(true)).build());
        this.scanRadius = this.sgDetection.add(((IntSetting.Builder)((IntSetting.Builder)((IntSetting.Builder)new IntSetting.Builder().name("scan-radius-chunks")).description("Chunk radius to keep in memory (larger = more RAM).")).defaultValue(12)).range(4, 32).sliderRange(4, 24).build());
        this.renderHeight = this.sgRender.add(((DoubleSetting.Builder)((DoubleSetting.Builder)new DoubleSetting.Builder().name("render-height")).description("Y level to draw the chunk highlight box.")).defaultValue(64.0).range(-64.0, 320.0).sliderRange(-64.0, 320.0).build());
        this.shapeMode = this.sgRender.add(((EnumSetting.Builder)((EnumSetting.Builder)new EnumSetting.Builder().name("shape-mode")).defaultValue(ShapeMode.Both)).build());
        this.lowColor = this.sgRender.add(((ColorSetting.Builder)((ColorSetting.Builder)new ColorSetting.Builder().name("low-score-color")).description("Color for chunks just above the threshold.")).defaultValue(new SettingColor(255, 255, 0, 80)).build());
        this.highColor = this.sgRender.add(((ColorSetting.Builder)((ColorSetting.Builder)new ColorSetting.Builder().name("high-score-color")).description("Color for chunks with a very high score.")).defaultValue(new SettingColor(255, 30, 30, 140)).build());
        this.showScore = this.sgRender.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("show-score-chat")).description("Print found base chunks to chat.")).defaultValue(true)).build());
        this.scores = new ConcurrentHashMap<class_1923, Integer>();
        this.flagged = ConcurrentHashMap.newKeySet();
        this.alreadyNotified = ConcurrentHashMap.newKeySet();
    }

    @Override
    public void onActivate() {
        this.scores.clear();
        this.flagged.clear();
        this.alreadyNotified.clear();
    }

    @Override
    public void onDeactivate() {
        this.scores.clear();
        this.flagged.clear();
        this.alreadyNotified.clear();
    }

    @EventHandler
    private void onChunkLoad(ChunkDataEvent event) {
        if (this.mc.field_1687 == null) {
            return;
        }
        class_2818 chunk = event.chunk();
        class_1923 pos = chunk.method_12004();
        int score = this.scoreChunk(chunk);
        this.scores.put(pos, score);
        if (score >= this.minScore.get()) {
            this.flagged.add(pos);
            if (this.showScore.get().booleanValue() && this.alreadyNotified.add(pos)) {
                this.info("Base Radar: possible base at chunk (highlight)%d, %d(default) (score: (highlight)%d(default)).", pos.field_9181, pos.field_9180, score);
                this.mc.execute(() -> {
                    this.mc.method_1566().method_1999((class_368)new MeteorToast.Builder("Base Radar").icon(class_1802.field_27070).text("Potential base found at " + pos.field_9181 + ", " + pos.field_9180).build());
                    this.mc.method_1483().method_4873((class_1113)class_1109.method_4757((class_3414)class_3417.field_14627, (float)0.5f, (float)0.6f));
                });
            }
        } else {
            this.flagged.remove(pos);
        }
    }

    @EventHandler
    private void onRender3D(Render3DEvent event) {
        if (this.mc.field_1724 == null) {
            return;
        }
        int radius = this.scanRadius.get();
        class_1923 playerChunk = this.mc.field_1724.method_31476();
        for (class_1923 pos : this.flagged) {
            if (Math.abs(pos.field_9181 - playerChunk.field_9181) > radius || Math.abs(pos.field_9180 - playerChunk.field_9180) > radius) continue;
            int score = this.scores.getOrDefault(pos, 0);
            double ratio = Math.min(1.0, (double)(score - this.minScore.get()) / (double)Math.max(1, this.minScore.get() * 4));
            SettingColor lo = this.lowColor.get();
            SettingColor hi = this.highColor.get();
            int r = (int)((double)lo.r + ratio * (double)(hi.r - lo.r));
            int g = (int)((double)lo.g + ratio * (double)(hi.g - lo.g));
            int b = (int)((double)lo.b + ratio * (double)(hi.b - lo.b));
            int a = (int)((double)lo.a + ratio * (double)(hi.a - lo.a));
            SettingColor side = new SettingColor(r, g, b, a);
            SettingColor line = new SettingColor(r, g, b, 255);
            double x1 = pos.method_8326();
            double z1 = pos.method_8328();
            double x2 = x1 + 16.0;
            double z2 = z1 + 16.0;
            double y = this.renderHeight.get();
            event.renderer.box(x1, y - 0.5, z1, x2, y + 0.5, z2, side, line, this.shapeMode.get(), 0);
        }
    }

    private int scoreChunk(class_2818 chunk) {
        int score = 0;
        class_2826[] sections = chunk.method_12006();
        class_1923 cp = chunk.method_12004();
        int lightAnomaliesFound = 0;
        int rotatedFound = 0;
        int airPockets = 0;
        for (int i = 0; i < sections.length; ++i) {
            class_2826 sec = sections[i];
            if (sec == null || sec.method_38292()) continue;
            int sy = chunk.method_31607() + i * 16;
            for (int x = 0; x < 16; ++x) {
                for (int z = 0; z < 16; ++z) {
                    for (int y = 0; y < 16; ++y) {
                        class_2338 pos = new class_2338(cp.method_8326() + x, sy + y, cp.method_8328() + z);
                        class_2680 state = sec.method_12254(x, y, z);
                        class_2248 b = state.method_26204();
                        score += this.scoreBlock(b);
                        if (sy + y >= 0) continue;
                        if (this.lightAnomalies.get().booleanValue() && this.isLightAnomalous(pos, state)) {
                            ++lightAnomaliesFound;
                        }
                        if (this.rotatedDeepslate.get().booleanValue() && this.isRotatedDeepslate(state)) {
                            ++rotatedFound;
                        }
                        if (!this.airAnomalies.get().booleanValue() || b != class_2246.field_10124 || !this.isUnnaturalAir(pos)) continue;
                        ++airPockets;
                    }
                }
            }
        }
        if (lightAnomaliesFound > 10) {
            score += 5;
        }
        if (rotatedFound > 5) {
            score += 4;
        }
        if (airPockets > 20) {
            score += 3;
        }
        return score;
    }

    private boolean isLightAnomalous(class_2338 pos, class_2680 state) {
        if (state.method_26213() > 0) {
            return false;
        }
        if (this.mc.field_1687.method_8314(class_1944.field_9282, pos) < 8) {
            return false;
        }
        for (class_2350 dir : class_2350.values()) {
            class_2680 nState = this.mc.field_1687.method_8320(pos.method_10093(dir));
            if (!nState.method_27852(class_2246.field_10164) && !nState.method_27852(class_2246.field_28411) && !nState.method_27852(class_2246.field_10092)) continue;
            return false;
        }
        return true;
    }

    private boolean isRotatedDeepslate(class_2680 state) {
        boolean isType;
        boolean bl = isType = state.method_27852(class_2246.field_28888) || state.method_27852(class_2246.field_28900) || state.method_27852(class_2246.field_28896);
        if (!isType) {
            return false;
        }
        if (state.method_28498((class_2769)class_2741.field_12496)) {
            return state.method_11654((class_2769)class_2741.field_12496) != class_2350.class_2351.field_11052;
        }
        return state.method_28498((class_2769)class_2741.field_12529);
    }

    private boolean isUnnaturalAir(class_2338 pos) {
        int solidNeighbors = 0;
        for (class_2350 dir : class_2350.values()) {
            if (!this.mc.field_1687.method_8320(pos.method_10093(dir)).method_26212((class_1922)this.mc.field_1687, pos.method_10093(dir))) continue;
            ++solidNeighbors;
        }
        return solidNeighbors >= 5;
    }

    private int scoreBlock(class_2248 b) {
        if (this.detectStorage.get().booleanValue()) {
            if (b == class_2246.field_10034 || b == class_2246.field_10380 || b == class_2246.field_16328) {
                return 4;
            }
            if (b instanceof class_2480) {
                return 5;
            }
            if (b == class_2246.field_10443) {
                return 3;
            }
            if (b == class_2246.field_10312 || b == class_2246.field_10200 || b == class_2246.field_10228) {
                return 3;
            }
        }
        if (this.detectWorkstations.get().booleanValue()) {
            if (b == class_2246.field_9980) {
                return 3;
            }
            if (b == class_2246.field_10181 || b == class_2246.field_16333 || b == class_2246.field_16334) {
                return 3;
            }
            if (b == class_2246.field_10535 || b == class_2246.field_10105 || b == class_2246.field_10414) {
                return 4;
            }
            if (b == class_2246.field_10485) {
                return 4;
            }
            if (b == class_2246.field_10327) {
                return 6;
            }
            if (b == class_2246.field_10333) {
                return 4;
            }
            if (b == class_2246.field_16337 || b == class_2246.field_16329 || b == class_2246.field_10083) {
                return 2;
            }
            if (b instanceof class_2244) {
                return 2;
            }
        }
        if (this.detectFarming.get().booleanValue()) {
            if (b == class_2246.field_10362) {
                return 2;
            }
            if (b == class_2246.field_17563) {
                return 2;
            }
            if (b == class_2246.field_20422 || b == class_2246.field_20421) {
                return 1;
            }
        }
        if (this.detectLighting.get().booleanValue()) {
            if (b == class_2246.field_10336 || b == class_2246.field_10099) {
                return 1;
            }
            if (b == class_2246.field_22092 || b == class_2246.field_22093) {
                return 1;
            }
            if (b == class_2246.field_16541 || b == class_2246.field_22110) {
                return 1;
            }
            if (b == class_2246.field_10174 || b == class_2246.field_10171) {
                return 1;
            }
            if (b == class_2246.field_22122 || b == class_2246.field_10009) {
                return 1;
            }
        }
        if (this.detectPaths.get().booleanValue()) {
            if (b == class_2246.field_10255 || b == class_2246.field_10194) {
                return 1;
            }
            if (b instanceof class_2510 || b instanceof class_2482) {
                return 1;
            }
        }
        if (this.detectNetherBlocks.get().booleanValue()) {
            if (b == class_2246.field_10266 || b == class_2246.field_10364) {
                return 4;
            }
            if (b == class_2246.field_10153 || b == class_2246.field_9978) {
                return 3;
            }
            if (b == class_2246.field_10092) {
                return 2;
            }
            if (b == class_2246.field_10114 || b == class_2246.field_22090) {
                return 2;
            }
        }
        return 0;
    }
}

