/*
 * Decompiled with CFR 0.152.
 * 
 * Could not load the following classes:
 *  meteordevelopment.orbit.EventHandler
 *  net.minecraft.class_332
 *  net.minecraft.class_3532
 *  org.joml.Matrix3x2fStack
 *  org.lwjgl.glfw.GLFW
 */
package meteordevelopment.meteorclient.systems.modules.render;

import java.awt.Color;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import meteordevelopment.meteorclient.events.render.Render2DEvent;
import meteordevelopment.meteorclient.systems.modules.Categories;
import meteordevelopment.meteorclient.systems.modules.Module;
import meteordevelopment.orbit.EventHandler;
import net.minecraft.class_332;
import net.minecraft.class_3532;
import org.joml.Matrix3x2fStack;
import org.lwjgl.glfw.GLFW;

public class RegionMap
extends Module {
    private static final int MAP_SIZE = 9;
    private static final int CELL_SIZE = 10;
    private static final int CELL_GAP = 1;
    private static final int MAP_PIXELS = 98;
    private static final int MAP_PADDING = 4;
    private static final int MAP_PANEL_SIZE = 106;
    private static final int LEGEND_GAP = 4;
    private static final int LEGEND_WIDTH = 78;
    private static final int LEGEND_PADDING = 4;
    private static final int LEGEND_ROW_HEIGHT = 8;
    private static final float LEGEND_TEXT_SCALE = 0.55f;
    private static final float INFO_TEXT_SCALE = 0.55f;
    private static final float CELL_NUMBER_SCALE = 0.5f;
    private static final double REGION_SIZE = 50000.0;
    private static final double MAP_OFFSET = 225000.0;
    private static final String[] REGION_TYPE_NAMES = new String[]{"EU Central", "EU West", "NA East", "NA West", "Asia", "Oceania"};
    private static final Color[] REGION_TYPE_COLORS = new Color[]{new Color(159, 206, 99), new Color(0, 166, 99), new Color(79, 173, 234), new Color(47, 110, 186), new Color(245, 194, 66), new Color(252, 136, 3)};
    private static final int[][] REGION_LAYOUT = new int[][]{{82, 5}, {100, 3}, {101, 3}, {102, 3}, {103, 2}, {104, 2}, {105, 2}, {106, 2}, {91, 2}, {83, 5}, {44, 3}, {75, 3}, {42, 3}, {41, 2}, {40, 2}, {39, 2}, {38, 2}, {92, 2}, {84, 5}, {45, 3}, {14, 3}, {13, 3}, {12, 2}, {11, 2}, {10, 2}, {37, 2}, {93, 2}, {85, 5}, {46, 5}, {74, 5}, {3, 3}, {2, 2}, {1, 2}, {25, 2}, {36, 2}, {94, 2}, {86, 4}, {47, 4}, {72, 4}, {71, 4}, {5, 2}, {4, 2}, {24, 2}, {35, 2}, {95, 2}, {87, 4}, {51, 1}, {17, 1}, {9, 0}, {8, 0}, {7, 0}, {23, 0}, {34, 0}, {96, 2}, {88, 4}, {54, 1}, {18, 1}, {61, 0}, {62, 0}, {21, 0}, {22, 0}, {33, 0}, {97, 0}, {89, 0}, {26, 1}, {27, 0}, {28, 0}, {29, 0}, {30, 0}, {59, 0}, {32, 0}, {98, 0}, {90, 0}, {107, 1}, {108, 1}, {109, 1}, {110, 1}, {111, 1}, {112, 1}, {113, 1}, {99, 0}};
    private static final Map<Integer, RegionInfo> REGION_MAP = RegionMap.createRegionMap();
    private int panelX = 12;
    private int panelY = 148;
    private boolean dragging;
    private int dragOffsetX;
    private int dragOffsetY;
    private boolean leftMouseDownLast;
    private UiInteraction uiInteraction = UiInteraction.NONE;

    public RegionMap() {
        super(Categories.Render, "region-map", "Renders a draggable world region map");
    }

    @Override
    public void onDeactivate() {
        this.dragging = false;
        this.leftMouseDownLast = false;
        this.uiInteraction = UiInteraction.NONE;
        super.onDeactivate();
    }

    @EventHandler
    private void onRender2D(Render2DEvent event) {
        if (this.mc != null && this.mc.field_1724 != null && this.mc.field_1687 != null) {
            int dragW = this.getPanelTotalWidth();
            int dragH = this.getPanelTotalHeight();
            this.handleDragInput(this.panelX, this.panelY, dragW, dragH);
            this.ensurePanelInBounds(dragW, dragH);
            this.renderPanel(event.drawContext);
        }
    }

    private int getLegendHeight() {
        return 15 + REGION_TYPE_NAMES.length * 8 + 5 + 16;
    }

    private int getPanelTotalWidth() {
        return 188;
    }

    private int getPanelTotalHeight() {
        return Math.max(106, this.getLegendHeight());
    }

    private void handleDragInput(int panelX, int panelY, int panelW, int panelH) {
        if (this.mc.field_1755 == null) {
            boolean mouseInPanel;
            long window = this.mc.method_22683().method_4490();
            double scale = this.mc.method_22683().method_4495();
            double mouseX = this.mc.field_1729.method_1603() / scale;
            double mouseY = this.mc.field_1729.method_1604() / scale;
            boolean leftDown = GLFW.glfwGetMouseButton((long)window, (int)0) == 1;
            boolean justPressed = leftDown && !this.leftMouseDownLast;
            boolean justReleased = !leftDown && this.leftMouseDownLast;
            boolean bl = mouseInPanel = mouseX >= (double)panelX && mouseX <= (double)(panelX + panelW) && mouseY >= (double)panelY && mouseY <= (double)(panelY + panelH);
            if (justPressed && mouseInPanel && this.uiInteraction == UiInteraction.NONE) {
                this.uiInteraction = UiInteraction.DRAGGING;
                this.dragOffsetX = (int)(mouseX - (double)panelX);
                this.dragOffsetY = (int)(mouseY - (double)panelY);
            }
            if (leftDown && this.uiInteraction == UiInteraction.DRAGGING) {
                this.dragging = true;
                int sw = this.mc.method_22683().method_4486();
                int sh = this.mc.method_22683().method_4502();
                this.panelX = Math.max(0, Math.min((int)mouseX - this.dragOffsetX, sw - panelW));
                this.panelY = Math.max(0, Math.min((int)mouseY - this.dragOffsetY, sh - panelH));
            }
            if (justReleased) {
                this.dragging = false;
                this.uiInteraction = UiInteraction.NONE;
            }
            this.leftMouseDownLast = leftDown;
        }
    }

    private void ensurePanelInBounds(int panelW, int panelH) {
        int sw = this.mc.method_22683().method_4486();
        int sh = this.mc.method_22683().method_4502();
        this.panelX = class_3532.method_15340((int)this.panelX, (int)0, (int)Math.max(0, sw - panelW));
        this.panelY = class_3532.method_15340((int)this.panelY, (int)0, (int)Math.max(0, sh - panelH));
    }

    private void renderPanel(class_332 context) {
        int row;
        int gridRgb;
        int mapX = this.panelX;
        int mapY = this.panelY;
        int cellStartX = mapX + 4;
        int cellStartY = mapY + 4;
        int legendX = mapX + 106 + 4;
        int legendH = this.getLegendHeight();
        Color accent = new Color(120, 180, 255, 255);
        int alphaBase = 200;
        Color panel = new Color(22, 26, 34, alphaBase);
        Color border = new Color(accent.getRed(), accent.getGreen(), accent.getBlue(), 140);
        Color grid = new Color(100, 100, 100, 88);
        context.method_25294(mapX, mapY, mapX + 106, mapY + 106, panel.getRGB());
        for (gridRgb = 0; gridRgb < 9; ++gridRgb) {
            for (row = 0; row < 9; ++row) {
                RegionInfo cell = REGION_MAP.get(gridRgb * 9 + row);
                if (cell == null) continue;
                int cx = cellStartX + row * 11;
                int cy = cellStartY + gridRgb * 11;
                Color rc = REGION_TYPE_COLORS[class_3532.method_15340((int)cell.regionType, (int)0, (int)(REGION_TYPE_COLORS.length - 1))];
                context.method_25294(cx, cy, cx + 10, cy + 10, new Color(rc.getRed(), rc.getGreen(), rc.getBlue(), 214).getRGB());
            }
        }
        gridRgb = grid.getRGB();
        for (row = 1; row < 9; ++row) {
            int col = cellStartX + row * 11 - 1;
            context.method_25294(col, cellStartY, col + 1, cellStartY + 98, gridRgb);
        }
        for (row = 1; row < 9; ++row) {
            int col = cellStartY + row * 11 - 1;
            context.method_25294(cellStartX, col, cellStartX + 98, col + 1, gridRgb);
        }
        for (row = 0; row < 9; ++row) {
            for (int col = 0; col < 9; ++col) {
                RegionInfo cell = REGION_MAP.get(row * 9 + col);
                if (cell == null) continue;
                this.renderCellNumber(context, Integer.toString(cell.regionId), cellStartX + col * 11, cellStartY + row * 11);
            }
        }
        this.renderPlayerIndicator(context, cellStartX, cellStartY);
        this.renderLegend(context, legendX, mapY, legendH);
    }

    private void renderCellNumber(class_332 context, String value, int cellX, int cellY) {
        int baseWidth = Math.max(1, this.mc.field_1772.method_1727(value));
        Objects.requireNonNull(this.mc.field_1772);
        int baseHeight = Math.max(1, 9);
        float invScale = 2.0f;
        int scaledCell = Math.round(10.0f * invScale);
        int drawX = Math.round((float)cellX * invScale + (float)(scaledCell - baseWidth) * 0.5f);
        int drawY = Math.round((float)cellY * invScale + (float)(scaledCell - baseHeight) * 0.5f);
        Matrix3x2fStack matrices = context.method_51448();
        matrices.pushMatrix();
        matrices.scale(0.5f, 0.5f);
        context.method_51433(this.mc.field_1772, value, drawX, drawY, new Color(10, 12, 16, 255).getRGB(), false);
        matrices.popMatrix();
    }

    private void drawScaledUiText(class_332 context, String text, float x, float y, float scale, int color) {
        Matrix3x2fStack matrices = context.method_51448();
        matrices.pushMatrix();
        matrices.translate(x, y);
        matrices.scale(scale, scale);
        context.method_51433(this.mc.field_1772, text, 0, 0, color, false);
        matrices.popMatrix();
    }

    private void renderLegend(class_332 context, int legendX, int legendY, int legendH) {
        int y = legendY + 4 + 1;
        this.drawScaledUiText(context, "Regions", legendX + 4, y, 0.58f, new Color(225, 231, 242, 250).getRGB());
        y += 8;
        for (int i = 0; i < REGION_TYPE_NAMES.length; ++i) {
            int regId = y + 1;
            context.method_25294(legendX + 4, regId, legendX + 4 + 5, regId + 5, REGION_TYPE_COLORS[i].getRGB());
            String regName = this.trimLegendText(REGION_TYPE_NAMES[i], 61, 0.55f);
            this.drawScaledUiText(context, regName, legendX + 4 + 8, y, 0.55f, new Color(230, 236, 245, 245).getRGB());
            y += 8;
        }
        context.method_25294(legendX + 4, y += 2, legendX + 78 - 4, y + 1, new Color(255, 255, 255, 36).getRGB());
        y += 3;
        double px = this.mc.field_1724.method_23317();
        double pz = this.mc.field_1724.method_23321();
        int regIdValue = RegionMap.getRegionIdAt(px, pz);
        String regNameValue = RegionMap.getRegionTypeName(px, pz);
        String var10000 = String.valueOf(regIdValue >= 0 ? Integer.valueOf(regIdValue) : "?");
        String line1 = "R:" + var10000 + " " + regNameValue;
        String line2 = "X:" + (int)Math.floor(px) + " Z:" + (int)Math.floor(pz);
        this.drawScaledUiText(context, this.trimLegendText(line1, 70, 0.55f), legendX + 4, y, 0.55f, new Color(220, 226, 238, 245).getRGB());
        this.drawScaledUiText(context, this.trimLegendText(line2, 70, 0.55f), legendX + 4, y += 8, 0.55f, new Color(220, 226, 238, 245).getRGB());
    }

    private String trimLegendText(String text, int maxWidth, float scale) {
        int rawWidth = Math.max(1, (int)((float)maxWidth / Math.max(0.1f, scale)));
        if (this.mc.field_1772.method_1727(text) <= rawWidth) {
            return text;
        }
        String ellipsis = "...";
        int ellipsisW = this.mc.field_1772.method_1727(ellipsis);
        if (ellipsisW >= rawWidth) {
            return this.mc.field_1772.method_27523(text, rawWidth);
        }
        String var10000 = this.mc.field_1772.method_27523(text, rawWidth - ellipsisW);
        return var10000 + ellipsis;
    }

    private void renderPlayerIndicator(class_332 context, int mapX, int mapY) {
        double rawGridX = (this.mc.field_1724.method_23317() + 225000.0) / 50000.0;
        double rawGridZ = (this.mc.field_1724.method_23321() + 225000.0) / 50000.0;
        double clampedX = class_3532.method_15350((double)rawGridX, (double)0.0, (double)8.99);
        double clampedZ = class_3532.method_15350((double)rawGridZ, (double)0.0, (double)8.99);
        int px = (int)((double)mapX + clampedX * 11.0);
        int py = (int)((double)mapY + clampedZ * 11.0);
        context.method_25294(px, py, px + 5, py + 5, new Color(255, 255, 255, 255).getRGB());
    }

    private static int[] worldToGrid(double x, double z) {
        return new int[]{(int)Math.floor((x + 225000.0) / 50000.0), (int)Math.floor((z + 225000.0) / 50000.0)};
    }

    private static Map<Integer, RegionInfo> createRegionMap() {
        HashMap<Integer, RegionInfo> map = new HashMap<Integer, RegionInfo>();
        for (int i = 0; i < REGION_LAYOUT.length; ++i) {
            map.put(i, new RegionInfo(REGION_LAYOUT[i][0], class_3532.method_15340((int)REGION_LAYOUT[i][1], (int)0, (int)(REGION_TYPE_NAMES.length - 1))));
        }
        return map;
    }

    private static int getRegionIdAt(double x, double z) {
        int[] gp = RegionMap.worldToGrid(x, z);
        if (gp[0] >= 0 && gp[0] < 9 && gp[1] >= 0 && gp[1] < 9) {
            RegionInfo info = REGION_MAP.get(gp[1] * 9 + gp[0]);
            return info != null ? info.regionId : -1;
        }
        return -1;
    }

    private static String getRegionTypeName(double x, double z) {
        int[] gp = RegionMap.worldToGrid(x, z);
        if (gp[0] >= 0 && gp[0] < 9 && gp[1] >= 0 && gp[1] < 9) {
            RegionInfo info = REGION_MAP.get(gp[1] * 9 + gp[0]);
            return info != null ? REGION_TYPE_NAMES[info.regionType] : "Unknown";
        }
        return "Unknown";
    }

    private static enum UiInteraction {
        NONE,
        DRAGGING;

    }

    private static final class RegionInfo {
        final int regionId;
        final int regionType;

        RegionInfo(int id, int type) {
            this.regionId = id;
            this.regionType = type;
        }
    }
}

