package de.blight.game.config;

import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.BaseAppState;
import com.jme3.font.BitmapFont;
import com.jme3.font.BitmapText;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Quad;

public class PauseMenu extends BaseAppState {

    private static final ColorRGBA COL_BG       = new ColorRGBA(0.05f, 0.05f, 0.08f, 0.88f);
    private static final ColorRGBA COL_PANEL     = new ColorRGBA(0.10f, 0.10f, 0.16f, 1.00f);
    private static final ColorRGBA COL_BTN       = new ColorRGBA(0.18f, 0.18f, 0.28f, 1.00f);
    private static final ColorRGBA COL_BTN_DIS   = new ColorRGBA(0.12f, 0.12f, 0.18f, 1.00f);
    private static final ColorRGBA COL_BTN_QUIT  = new ColorRGBA(0.38f, 0.10f, 0.10f, 1.00f);
    private static final ColorRGBA COL_TEXT      = ColorRGBA.White;
    private static final ColorRGBA COL_TEXT_DIS  = new ColorRGBA(0.40f, 0.40f, 0.40f, 1.00f);
    private static final ColorRGBA COL_TEXT_SUB  = new ColorRGBA(0.35f, 0.35f, 0.35f, 1.00f);

    private static final int BTN_GRAFIK    = 0;
    private static final int BTN_AUDIO     = 1;
    private static final int BTN_STEUERUNG = 2;
    private static final int BTN_BEENDEN   = 3;

    private SimpleApplication app;
    private Node guiNode;
    private BitmapFont font;
    private Node panel;

    private Runnable onGraphics;
    private Runnable onControls;

    // [x, y, w, h] per button
    private final float[][] btnBounds = new float[4][4];

    public PauseMenu(Runnable onGraphics, Runnable onControls) {
        this.onGraphics = onGraphics;
        this.onControls = onControls;
    }

    @Override
    protected void initialize(Application app) {
        this.app     = (SimpleApplication) app;
        this.guiNode = this.app.getGuiNode();
        this.font    = app.getAssetManager().loadFont("Interface/Fonts/Default.fnt");
    }

    @Override
    protected void onEnable() {
        buildUI();
        app.getInputManager().setCursorVisible(true);
        app.getInputManager().addMapping("_PauseClick", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
        app.getInputManager().addListener(clickListener, "_PauseClick");
    }

    @Override
    protected void onDisable() {
        if (panel != null) { guiNode.detachChild(panel); panel = null; }
        app.getInputManager().deleteMapping("_PauseClick");
        app.getInputManager().setCursorVisible(false);
    }

    @Override protected void cleanup(Application app) {}

    private void buildUI() {
        float sw = app.getCamera().getWidth();
        float sh = app.getCamera().getHeight();
        panel = new Node("pause-panel");
        addQuad(panel, 0, 0, sw, sh, COL_BG, -2);

        float pw = 320, ph = 360;
        float px = (sw - pw) / 2f, py = (sh - ph) / 2f;
        addQuad(panel, px, py, pw, ph, COL_PANEL, -1);

        BitmapText title = txt("PAUSE", 26, COL_TEXT);
        centerText(title, px, py + ph - 48, pw);
        panel.attachChild(title);

        String[]  labels  = {"Grafik", "Audio", "Steuerung", "Beenden"};
        boolean[] enabled = {true, false, true, true};
        float bw = 260, bh = 52;
        float bx = px + (pw - bw) / 2f;
        float startY = py + ph - 112;
        float step   = 62;

        for (int i = 0; i < 4; i++) {
            float by = startY - i * step;
            ColorRGBA bgCol = !enabled[i] ? COL_BTN_DIS : (i == BTN_BEENDEN ? COL_BTN_QUIT : COL_BTN);
            ColorRGBA txCol = enabled[i] ? COL_TEXT : COL_TEXT_DIS;

            addQuad(panel, bx, by, bw, bh, bgCol, 0);

            BitmapText lbl = txt(labels[i], 18, txCol);
            if (!enabled[i]) {
                // Center label in upper portion, show hint below
                lbl.setLocalTranslation(bx + (bw - lbl.getLineWidth()) / 2f, by + bh - 12, 1);
                BitmapText hint = txt("Bald verfügbar", 12, COL_TEXT_SUB);
                hint.setLocalTranslation(bx + (bw - hint.getLineWidth()) / 2f, by + 14, 1);
                panel.attachChild(hint);
            } else {
                centerText(lbl, bx, by + bh - 16, bw);
            }
            panel.attachChild(lbl);

            btnBounds[i][0] = bx; btnBounds[i][1] = by;
            btnBounds[i][2] = bw; btnBounds[i][3] = bh;
        }

        guiNode.attachChild(panel);
    }

    private final ActionListener clickListener = (name, isPressed, tpf) -> {
        if (!isPressed) return;
        Vector2f c = app.getInputManager().getCursorPosition();

        for (int i = 0; i < 4; i++) {
            if (!hits(c, btnBounds[i][0], btnBounds[i][1], btnBounds[i][2], btnBounds[i][3])) continue;
            switch (i) {
                case BTN_GRAFIK    -> { if (onGraphics != null) onGraphics.run(); }
                case BTN_AUDIO     -> { /* Bald verfügbar */ }
                case BTN_STEUERUNG -> { if (onControls != null) onControls.run(); }
                case BTN_BEENDEN   -> app.stop();
            }
            return;
        }
    };

    // -----------------------------------------------------------------------

    private Geometry addQuad(Node parent, float x, float y, float w, float h, ColorRGBA color, float z) {
        Geometry geo = new Geometry("q", new Quad(w, h));
        Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", color.clone());
        if (color.a < 1f) {
            mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
            geo.setQueueBucket(RenderQueue.Bucket.Transparent);
        }
        geo.setMaterial(mat);
        geo.setLocalTranslation(x, y, z);
        parent.attachChild(geo);
        return geo;
    }

    private BitmapText txt(String s, int size, ColorRGBA color) {
        BitmapText t = new BitmapText(font, false);
        t.setSize(size); t.setColor(color); t.setText(s);
        return t;
    }

    private void centerText(BitmapText t, float x, float y, float width) {
        t.setLocalTranslation(x + (width - t.getLineWidth()) / 2f, y, 1);
    }

    private boolean hits(Vector2f p, float x, float y, float w, float h) {
        return p.x >= x && p.x <= x + w && p.y >= y && p.y <= y + h;
    }
}
