package de.duehl.vocabulary.japanese.ui.components.display;

import java.awt.Color;

import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

import de.duehl.swing.ui.GuiTools;
import de.duehl.vocabulary.japanese.common.persistence.RomajiAndPronunciationColorOptions;
import de.duehl.vocabulary.japanese.data.Vocable;
import de.duehl.vocabulary.japanese.ui.components.text.RomajiAndPronunciationTextCreator;

/**
 * Diese Klasse erzeugt eine Anzeige für Romaji und Aussprache einer Vokabel.
 *
 * @version 1.01     2025-11-15
 * @author Christian Dühl
 */

public class RomajiAndPronunciationDisplay {

    private static final int FONT_SIZE_BASE = 24;

    /** Die Vokabel, welche angezeigt wird. */
    private final Vocable vocable;

    /** Die TextPane in der die Romaji und Aussprache dargestellt werden. */
    private final JTextPane romajiAndPronunciationPane;

    /** Die Hintergrundfarbe abhängig vom Erfolg der letzten Abfragen. */
    private final Color backgroundColor;

    /** Die Farb-Optionen. */
    private final RomajiAndPronunciationColorOptions options;

    private Style regularStyle;
    private Style romajiStyle;
    private Style pronunciationStyle;

    /** Gibt an, ob die Romaji angezeigt werden sollen. */
    private boolean showRomaji;

    /** Gibt an, ob die Aussprache angezeigt werden soll. */
    private boolean showPronunciation;

    /**
     * Konstruktor.
     *
     * @param vocable
     *            Die Vokabel, welche angezeigt wird.
     * @param kanjiAndKanaPane
     *            Die TextPane in der die Romaji und Aussprache dargestellt werden.
     * @param backgroundColor
     *            Die Hintergrundfarbe abhängig vom Erfolg der letzten Abfragen.
     * @param options
     *            Die Farb-Optionen.
     */
    public RomajiAndPronunciationDisplay(Vocable vocable, JTextPane kanjiAndKanaPane,
            Color backgroundColor, RomajiAndPronunciationColorOptions options) {
        this.vocable = vocable;
        this.romajiAndPronunciationPane = kanjiAndKanaPane;
        this.backgroundColor = backgroundColor;
        this.options = options;

        showRomaji = true;
        showPronunciation = true;
    }

    /** Legt fest, dass die Romaji nicht angezeigt werden sollen. */
    public void hideRomaji() {
        showRomaji = false;
    }

    /** Legt fest, dass die Aussprache nicht angezeigt werden sollen. */
    public void hidePronunciation() {
        showPronunciation = false;
    }

    /** Initialisiert und befüllt die TextPane. */
    public void display() {
        initTextPane();
        createStyles(); // Was passiert, wenn es die schon gibt?
        clearContent();
        fillWithNewText();
    }

    private void initTextPane() {
        romajiAndPronunciationPane.setEditable(false);
        //romajiAndPronunciationPane.setOpaque(true);
        GuiTools.respectTextPaneBackgroundInNimbusLookAndFeel(romajiAndPronunciationPane);
        romajiAndPronunciationPane.setBackground(backgroundColor);
    }

    /** Legt die Stile für die Auszeichnung fest. */
    private void createStyles() {
        StyledDocument document = romajiAndPronunciationPane.getStyledDocument();
        Style defaultStyle = StyleContext.getDefaultStyleContext().
                getStyle(StyleContext.DEFAULT_STYLE);

        regularStyle = document.addStyle("regular", defaultStyle);
        StyleConstants.setForeground(regularStyle, options.getVocableColorStandard());
        StyleConstants.setBackground(regularStyle, backgroundColor);
        StyleConstants.setFontSize(regularStyle, FONT_SIZE_BASE);
        StyleConstants.setSpaceAbove(regularStyle, 1);
        StyleConstants.setSpaceBelow(regularStyle, 1);
        StyleConstants.setLeftIndent(regularStyle, 16);
        StyleConstants.setRightIndent(regularStyle, 16);
        StyleConstants.setFirstLineIndent(regularStyle, 16);
        StyleConstants.setFontFamily(regularStyle, "serif");
        StyleConstants.setAlignment(regularStyle, StyleConstants.ALIGN_LEFT);

        romajiStyle = document.addStyle("romaji", regularStyle);
        StyleConstants.setForeground(romajiStyle, options.getVocableColorRomaji());
        StyleConstants.setBackground(romajiStyle, backgroundColor); // nötig
        StyleConstants.setFontSize(romajiStyle, FONT_SIZE_BASE + 4);
        StyleConstants.setBold(romajiStyle, true);

        pronunciationStyle = document.addStyle("pronunciation", regularStyle);
        StyleConstants.setForeground(pronunciationStyle, options.getVocableColorPronunciation());
        StyleConstants.setBackground(pronunciationStyle, backgroundColor); // nötig
    }

    private void clearContent() {
        try {
            StyledDocument document = romajiAndPronunciationPane.getStyledDocument();
            document.remove(0, document.getLength());
        }
        catch (BadLocationException exception) {
            throw new RuntimeException("Probleme beim Löschen des Inhaltes des Dokument.",
                    exception);
        }
    }

    private void fillWithNewText() {
        try {
            tryToFillWithNewText();
        }
        catch (Exception exception) {
            /*
            GuiTools.informUser("Hier ging etwas schief", "Beim Erzeugen der Texte für Romaji und "
                    + "Aussprache der Vokabel " + vocable.getKana() + " gab es ein Problem.\n"
                    + "Noch einmal versuchen!");
                    */
            throw new RuntimeException("Probleme beim Einfügen eines Stils ins Dokument.",
                    exception);
        }
    }

    private void tryToFillWithNewText() throws BadLocationException {
        RomajiAndPronunciationTextCreator creator = new RomajiAndPronunciationTextCreator(vocable,
                showRomaji, showPronunciation);
        creator.create();
        String firstTextPart = creator.getFirstTextPart();
        String textPartInBrace = creator.getTextPartInBrace();
        boolean braceInOwnLine = creator.isBraceInOwnLine();

        StyledDocument document = romajiAndPronunciationPane.getStyledDocument();

        boolean showFirst = !firstTextPart.isBlank();
        boolean showSecond = !textPartInBrace.isBlank();
        boolean showBoth = !firstTextPart.isBlank() && !textPartInBrace.isBlank();
        if (showFirst) {
            document.insertString(document.getLength(), firstTextPart, romajiStyle);
        }
        if (showBoth) {
            if (braceInOwnLine) {
                document.insertString(document.getLength(), "\n", regularStyle);
            }
            else {
                document.insertString(document.getLength(), " ", regularStyle);
            }
            document.insertString(document.getLength(), "(", regularStyle);
        }
        if (showSecond) {
            document.insertString(document.getLength(), "\"", regularStyle);
            document.insertString(document.getLength(), textPartInBrace, pronunciationStyle);
            document.insertString(document.getLength(), "\"", regularStyle);
        }
        if (showBoth) {
            document.insertString(document.getLength(), ")", regularStyle);
        }
    }

}
