/*
 * Decompiled with CFR 0.152.
 * 
 * Could not load the following classes:
 *  meteordevelopment.orbit.EventHandler
 *  net.minecraft.class_1923
 *  net.minecraft.class_1944
 *  net.minecraft.class_2246
 *  net.minecraft.class_2248
 *  net.minecraft.class_2338
 *  net.minecraft.class_2680
 *  net.minecraft.class_2818
 */
package meteordevelopment.meteorclient.systems.modules.render;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import meteordevelopment.meteorclient.events.render.Render3DEvent;
import meteordevelopment.meteorclient.renderer.ShapeMode;
import meteordevelopment.meteorclient.settings.BoolSetting;
import meteordevelopment.meteorclient.settings.ColorSetting;
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.color.Color;
import meteordevelopment.meteorclient.utils.render.color.SettingColor;
import meteordevelopment.orbit.EventHandler;
import net.minecraft.class_1923;
import net.minecraft.class_1944;
import net.minecraft.class_2246;
import net.minecraft.class_2248;
import net.minecraft.class_2338;
import net.minecraft.class_2680;
import net.minecraft.class_2818;

public class LightESP
extends Module {
    private final SettingGroup sgGeneral;
    private final SettingGroup sgFilter;
    private final SettingGroup sgRender;
    private final Setting<Integer> chunkRadius;
    private final Setting<Integer> minY;
    private final Setting<Integer> maxY;
    private final Setting<Integer> minLightLevel;
    private final Setting<Boolean> onlySourceBlocks;
    private final Setting<Boolean> filterNaturalLight;
    private final Setting<Boolean> showTorches;
    private final Setting<Boolean> showGlowstone;
    private final Setting<Boolean> showRedstone;
    private final Setting<Boolean> showBeacons;
    private final Setting<Boolean> distanceLimit;
    private final Setting<Integer> maxDistance;
    private final Setting<ShapeMode> shapeMode;
    private final Setting<Boolean> thermalColors;
    private final Setting<SettingColor> sideColor;
    private final Setting<SettingColor> lineColor;
    private final Map<class_2338, Integer> lightCache;
    private long lastScanTime;
    private static final long SCAN_INTERVAL = 500L;

    public LightESP() {
        super(Categories.Render, "light-esp", "Improved light source detection");
        this.sgGeneral = this.settings.getDefaultGroup();
        this.sgFilter = this.settings.createGroup("Filters");
        this.sgRender = this.settings.createGroup("Render");
        this.chunkRadius = this.sgGeneral.add(((IntSetting.Builder)((IntSetting.Builder)new IntSetting.Builder().name("chunk-radius")).defaultValue(4)).min(1).max(16).sliderMax(16).build());
        this.minY = this.sgGeneral.add(((IntSetting.Builder)((IntSetting.Builder)new IntSetting.Builder().name("min-y")).defaultValue(-64)).min(-64).max(319).sliderMin(-64).sliderMax(319).build());
        this.maxY = this.sgGeneral.add(((IntSetting.Builder)((IntSetting.Builder)new IntSetting.Builder().name("max-y")).defaultValue(100)).min(-64).max(319).sliderMin(-64).sliderMax(319).build());
        this.minLightLevel = this.sgGeneral.add(((IntSetting.Builder)((IntSetting.Builder)new IntSetting.Builder().name("min-light-level")).defaultValue(8)).min(0).max(15).sliderMax(15).build());
        this.onlySourceBlocks = this.sgFilter.add(((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("only-source-blocks")).defaultValue(true)).build());
        this.filterNaturalLight = this.sgFilter.add(((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("filter-natural-light")).defaultValue(false)).build());
        this.showTorches = this.sgFilter.add(((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("show-torches")).defaultValue(true)).build());
        this.showGlowstone = this.sgFilter.add(((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("show-glowstone")).defaultValue(true)).build());
        this.showRedstone = this.sgFilter.add(((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("show-redstone")).defaultValue(true)).build());
        this.showBeacons = this.sgFilter.add(((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("show-beacons")).defaultValue(true)).build());
        this.distanceLimit = this.sgGeneral.add(((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("distance-limit")).defaultValue(true)).build());
        this.maxDistance = this.sgGeneral.add(((IntSetting.Builder)((IntSetting.Builder)((IntSetting.Builder)new IntSetting.Builder().name("max-distance")).defaultValue(128)).min(16).max(512).sliderMax(512).visible(this.distanceLimit::get)).build());
        this.shapeMode = this.sgRender.add(((EnumSetting.Builder)((EnumSetting.Builder)new EnumSetting.Builder().name("shape-mode")).defaultValue(ShapeMode.Both)).build());
        this.thermalColors = this.sgRender.add(((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("thermal-colors")).defaultValue(true)).build());
        this.sideColor = this.sgRender.add(((ColorSetting.Builder)((ColorSetting.Builder)new ColorSetting.Builder().name("side-color")).defaultValue(new SettingColor(255, 255, 0, 75)).visible(() -> this.thermalColors.get() == false)).build());
        this.lineColor = this.sgRender.add(((ColorSetting.Builder)((ColorSetting.Builder)new ColorSetting.Builder().name("line-color")).defaultValue(new SettingColor(255, 255, 0, 255)).visible(() -> this.thermalColors.get() == false)).build());
        this.lightCache = new ConcurrentHashMap<class_2338, Integer>();
        this.lastScanTime = 0L;
    }

    @Override
    public void onActivate() {
        this.lightCache.clear();
        this.lastScanTime = 0L;
    }

    @Override
    public void onDeactivate() {
        this.lightCache.clear();
    }

    @EventHandler
    private void onRender3D(Render3DEvent event) {
        if (this.mc.field_1687 == null || this.mc.field_1724 == null) {
            return;
        }
        long currentTime = System.currentTimeMillis();
        if (currentTime - this.lastScanTime >= 500L) {
            this.scanForLights();
            this.lastScanTime = currentTime;
        }
        this.renderCachedLights(event);
    }

    private void scanForLights() {
        if (this.mc.field_1687 == null || this.mc.field_1724 == null) {
            return;
        }
        class_1923 playerChunkPos = new class_1923(this.mc.field_1724.method_24515());
        HashMap<class_2338, Integer> newCache = new HashMap<class_2338, Integer>();
        int radius = this.chunkRadius.get();
        for (int chunkX = playerChunkPos.field_9181 - radius; chunkX <= playerChunkPos.field_9181 + radius; ++chunkX) {
            for (int chunkZ = playerChunkPos.field_9180 - radius; chunkZ <= playerChunkPos.field_9180 + radius; ++chunkZ) {
                class_2818 chunk = this.mc.field_1687.method_2935().method_21730(chunkX, chunkZ);
                if (chunk == null) continue;
                this.scanChunk(chunkX, chunkZ, newCache);
            }
        }
        this.lightCache.clear();
        this.lightCache.putAll(newCache);
    }

    private void scanChunk(int chunkX, int chunkZ, Map<class_2338, Integer> cache) {
        int startX = chunkX * 16;
        int startZ = chunkZ * 16;
        for (int x = 0; x < 16; ++x) {
            for (int z = 0; z < 16; ++z) {
                for (int y = this.minY.get().intValue(); y <= this.maxY.get(); ++y) {
                    class_2338 pos = new class_2338(startX + x, y, startZ + z);
                    if (this.distanceLimit.get().booleanValue() && this.mc.field_1724.method_5649((double)pos.method_10263(), (double)pos.method_10264(), (double)pos.method_10260()) > (double)(this.maxDistance.get() * this.maxDistance.get())) continue;
                    int blockLight = this.mc.field_1687.method_8314(class_1944.field_9282, pos);
                    int skyLight = this.mc.field_1687.method_8314(class_1944.field_9284, pos);
                    if (blockLight < this.minLightLevel.get() || blockLight <= skyLight) continue;
                    class_2680 state = this.mc.field_1687.method_8320(pos);
                    class_2248 block = state.method_26204();
                    if (this.onlySourceBlocks.get().booleanValue() && state.method_26213() <= 0 || !this.passesFilters(block)) continue;
                    cache.put(pos, blockLight);
                }
            }
        }
    }

    private boolean passesFilters(class_2248 block) {
        if (this.filterNaturalLight.get().booleanValue() && (block == class_2246.field_10164 || block == class_2246.field_10092 || block == class_2246.field_10036 || block == class_2246.field_22089)) {
            return false;
        }
        if (!(this.showTorches.get().booleanValue() || block != class_2246.field_10336 && block != class_2246.field_10099 && block != class_2246.field_22092 && block != class_2246.field_22093 && block != class_2246.field_16541 && block != class_2246.field_22110)) {
            return false;
        }
        if (!(this.showGlowstone.get().booleanValue() || block != class_2246.field_10171 && block != class_2246.field_10174 && block != class_2246.field_22122)) {
            return false;
        }
        if (!(this.showRedstone.get().booleanValue() || block != class_2246.field_10524 && block != class_2246.field_10523 && block != class_2246.field_10301)) {
            return false;
        }
        return this.showBeacons.get() != false || block != class_2246.field_10327 && block != class_2246.field_10502;
    }

    private void renderCachedLights(Render3DEvent event) {
        for (Map.Entry<class_2338, Integer> entry : this.lightCache.entrySet()) {
            SettingColor lColor;
            SettingColor sColor;
            class_2338 pos = entry.getKey();
            int lightLevel = entry.getValue();
            if (this.thermalColors.get().booleanValue()) {
                float[] thermal = this.getThermalColor(lightLevel);
                sColor = new SettingColor((int)(thermal[0] * 255.0f), (int)(thermal[1] * 255.0f), (int)(thermal[2] * 255.0f), (int)(thermal[3] * 255.0f));
                lColor = new SettingColor((int)(thermal[0] * 255.0f), (int)(thermal[1] * 255.0f), (int)(thermal[2] * 255.0f), 255);
            } else {
                sColor = this.sideColor.get();
                lColor = this.lineColor.get();
            }
            event.renderer.box(pos, (Color)sColor, (Color)lColor, this.shapeMode.get(), 0);
        }
    }

    private float[] getThermalColor(int lightLevel) {
        float[] color = new float[4];
        float normalized = (float)lightLevel / 15.0f;
        color[3] = 0.3f + normalized * 0.7f;
        if (lightLevel <= 5) {
            float t = (float)lightLevel / 5.0f;
            color[0] = 0.0f + t * 0.2f;
            color[1] = 0.0f + t * 0.4f;
            color[2] = 0.4f + t * 0.6f;
        } else if (lightLevel <= 9) {
            float t = (float)(lightLevel - 5) / 4.0f;
            color[0] = 0.2f + t * 0.8f;
            color[1] = 0.4f + t * 0.6f;
            color[2] = 1.0f - t * 0.8f;
        } else if (lightLevel <= 12) {
            float t = (float)(lightLevel - 9) / 3.0f;
            color[0] = 1.0f;
            color[1] = 1.0f - t * 0.5f;
            color[2] = 0.2f - t * 0.2f;
        } else {
            float t = (float)(lightLevel - 12) / 3.0f;
            color[0] = 1.0f;
            color[1] = 0.5f + t * 0.5f;
            color[2] = 0.0f + t * 1.0f;
            color[3] = 0.8f + t * 0.2f;
        }
        return color;
    }
}

