package de.blight.game.control;

import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.*;
import com.jme3.math.*;
import com.jme3.renderer.Camera;
import com.jme3.scene.Spatial;

/**
 * Bewegt einen Charakter relativ zur Kamera-Horizontal-Richtung
 * und dreht ihn in Bewegungsrichtung.
 */
public class CharacterControl {

    private static final float MOVE_SPEED  = 8f;
    private static final float ROTATE_SPEED = 5f;

    private final InputManager inputManager;
    private final Camera cam;

    private Spatial character;

    // Eingabezustand
    private boolean forward, backward, left, right;

    public CharacterControl(InputManager inputManager, Camera cam) {
        this.inputManager = inputManager;
        this.cam = cam;
        registerMappings();
    }

    public void setCharacter(Spatial character) {
        this.character = character;
    }

    // -----------------------------------------------------------------------
    // Eingabe-Registrierung
    // -----------------------------------------------------------------------

    private void registerMappings() {
        inputManager.addMapping("Forward",  new KeyTrigger(KeyInput.KEY_W), new KeyTrigger(KeyInput.KEY_UP));
        inputManager.addMapping("Backward", new KeyTrigger(KeyInput.KEY_S), new KeyTrigger(KeyInput.KEY_DOWN));
        inputManager.addMapping("Left",     new KeyTrigger(KeyInput.KEY_A), new KeyTrigger(KeyInput.KEY_LEFT));
        inputManager.addMapping("Right",    new KeyTrigger(KeyInput.KEY_D), new KeyTrigger(KeyInput.KEY_RIGHT));

        ActionListener listener = (name, isPressed, tpf) -> {
            switch (name) {
                case "Forward"  -> forward  = isPressed;
                case "Backward" -> backward = isPressed;
                case "Left"     -> left     = isPressed;
                case "Right"    -> right    = isPressed;
            }
        };

        inputManager.addListener(listener, "Forward", "Backward", "Left", "Right");
    }

    // -----------------------------------------------------------------------
    // Update pro Frame
    // -----------------------------------------------------------------------

    public void update(float tpf) {
        if (character == null) return;

        // Kamerahorizontale Vorwärtsrichtung (Y ignorieren)
        Vector3f camDir = cam.getDirection().clone().setY(0).normalizeLocal();
        Vector3f camLeft = cam.getLeft().clone().setY(0).normalizeLocal();

        Vector3f moveDir = Vector3f.ZERO.clone();
        if (forward)  moveDir.addLocal(camDir);
        if (backward) moveDir.subtractLocal(camDir);
        if (left)     moveDir.addLocal(camLeft);
        if (right)    moveDir.subtractLocal(camLeft);

        if (moveDir.lengthSquared() > 0.001f) {
            moveDir.normalizeLocal();
            character.move(moveDir.mult(MOVE_SPEED * tpf));

            // Charakter zur Bewegungsrichtung drehen
            Quaternion targetRot = new Quaternion();
            targetRot.lookAt(moveDir, Vector3f.UNIT_Y);

            Quaternion current = character.getLocalRotation();
            current.slerp(targetRot, ROTATE_SPEED * tpf);
            character.setLocalRotation(current);
        }
    }
}
