package de.renew.fa.figures;

import java.awt.event.MouseEvent;

import CH.ifa.draw.figures.ConnectedTextTool;
import CH.ifa.draw.figures.TextFigure;
import CH.ifa.draw.framework.ChildFigure;
import CH.ifa.draw.framework.ParentFigure;
import de.renew.draw.storables.ontology.Figure;
import de.renew.draw.ui.ontology.DrawingEditor;
import de.renew.faformalism.util.FAAutomatonModelEnum;
import de.renew.faformalism.util.SimulationSettingsManager;

/**
 * Tool for creating and connecting {@link CH.ifa.draw.figures.TextFigure} labels
 * in finite-automata drawings.
 * <p>
 * This tool extends {@link CH.ifa.draw.figures.ConnectedTextTool} so that newly
 * created text figures are immediately connected to a compatible {@link CH.ifa.draw.framework.ParentFigure}
 * when the user clicks on it. It also provides sensible default text snippets
 * depending on the currently selected automaton model (see
 * {@link de.renew.faformalism.util.SimulationSettingsManager#getAutomatonModel()}).
 * </p>
 *
 * <p>Supported types:</p>
 * <ul>
 *   <li>{@link #FA_TOOL_TYPE_WORD} – general text/word labels</li>
 *   <li>{@link #FA_TOOL_TYPE_INSCRIPTION} – transition/state inscriptions</li>
 * </ul>
 *
 * <p>
 * Note: This file has been annotated with documentation-only comments.
 * No behavior has been changed.
 * </p>
 *
 * @author 7kraft
 */
public class FATextFigureCreationTool extends ConnectedTextTool {
    /** Constant denoting the "word" label tool type. */
    public final static int FA_TOOL_TYPE_WORD = 0;
    /** Constant denoting the "inscription" (e.g., transition/state) label tool type. */
    public final static int FA_TOOL_TYPE_INSCRIPTION = 1;
    /** Selected tool type; see {@link #FA_TOOL_TYPE_WORD} and {@link #FA_TOOL_TYPE_INSCRIPTION}. */
    private final int _type;

    /**
     * Creates a new tool for adding connected text figures.
     *
     * @param editor    the hosting drawing editor
     * @param prototype the {@link TextFigure} prototype to clone when creating a new label
     * @param type      the label type to create (see {@link #FA_TOOL_TYPE_WORD} and
     *                  {@link #FA_TOOL_TYPE_INSCRIPTION})
     */
    public FATextFigureCreationTool(DrawingEditor editor, TextFigure prototype, int type) {
        super(editor, prototype);
        _type = type;
    }

    /**
     * Handles a mouse press. If the user clicks on a compatible {@link ParentFigure},
     * the prototype text figure is connected to it and editing starts immediately.
     * Otherwise, falls back to the default behavior from {@link ConnectedTextTool}.
     *
     * <p>The method also pre-fills the text figure with a model-specific default,
     * see {@link #getTextForModel}.</p>
     *
     * @param e the original mouse event
     * @param x the x coordinate in drawing space
     * @param y the y coordinate in drawing space
     */
    @Override
    public void mouseDown(MouseEvent e, int x, int y) {
        if (!super._connected && !isTypingActive()) {
            Figure pressedFigure = drawing().findFigureInside(x, y);

            if (pressedFigure instanceof ParentFigure
                && ((ChildFigure) getPrototype()).canBeParent((ParentFigure) pressedFigure)) {
                super.mouseDown(e, x, y);
                if (createdFigure() instanceof TextFigure textFigure) {
                    textFigure.setText(
                        getTextForModel(_type, SimulationSettingsManager.getAutomatonModel()));
                    beginEdit(textFigure);
                }
            } else {
                super.mouseDown(e, x, y);
            }
        } else {
            super.mouseDown(e, x, y);
        }
    }

    /**
     * Returns an initial text snippet appropriate for the current tool type and automaton model.
     * <ul>
     *   <li>For {@link #FA_TOOL_TYPE_INSCRIPTION} and models {@code NFA}, {@code BUECHI}, or {@code NET},
     *       returns {@code "a"}.</li>
     *   <li>For {@link #FA_TOOL_TYPE_INSCRIPTION} and model {@code PDA},
     *       returns {@code "a, -> X"} (input, stack action).</li>
     *   <li>Otherwise returns the empty string.</li>
     * </ul>
     *
     * @param type              Selected tool type
     * @param automatonModel    Selected automaton model
     *
     * @return the default text to place into a newly created label
     */
    public static String getTextForModel(int type, FAAutomatonModelEnum automatonModel) {
        if (type == FA_TOOL_TYPE_WORD) {
            switch (automatonModel) {
                case NFA, NET -> {
                    return "a*+b^+";
                }
                case BUECHI -> {
                    return "a*+b^°";
                }
                case PDA -> {
                    return "abc";
                }
            }
        }
        if (type == FA_TOOL_TYPE_INSCRIPTION) {
            switch (automatonModel) {
                case NFA, BUECHI, NET -> {
                    return "a";
                }
                case PDA -> {
                    return "a, -> X";
                }
            }
        }
        return "";
    }
}