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.KanjiAndKanaColorOptions;
import de.duehl.vocabulary.japanese.data.Vocable;
import de.duehl.vocabulary.japanese.ui.components.text.KanjiAndKanaTextCreator;

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

public class KanjiAndKanaDisplay {

    private static final int FONT_SIZE_BASE = 28;


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

    /** Die TextPane in der die Kanji und Kana dargestellt werden. */
    private final JTextPane kanjiAndKanaPane;

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

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

    /** Gibt an, ob die Kana dargestellt werden sollen. */
    private boolean showKana;

    /** Gibt an, ob die Kanji dargestellt werden sollen. */
    private boolean showKanji;

    private Style regularStyle;
    private Style kanjiStyle;
    private Style kanaStyle;
    private Style braceStyle;

    /** Gibt an, ob die Kana genauso groß dargestellt werden, wie die Kanji. */
    private boolean showKanaInKanjiSize;

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

        showKana = true;
        showKanji = true;
        showKanaInKanjiSize = false;
    }

    /** Legt fest, dass die Kana nicht dargestellt werden sollen. */
    public void hideKana() {
        showKana = false;
    }

    /** Legt fest, dass die Kanji nicht dargestellt werden sollen. */
    public void hideKanji() {
        showKanji = false;
    }

    /** Legt fest, dass die Kana genauso groß dargestellt werden, wie die Kanji. */
    public void showKanaInKanjiSize() {
        showKanaInKanjiSize = true;
    }

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

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

    /** Legt die Stile für die Auszeichnung fest. */
    private void createStyles() {
        StyledDocument document = kanjiAndKanaPane.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);

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

        kanaStyle = document.addStyle("kana", regularStyle);
        StyleConstants.setForeground(kanaStyle, options.getVocableColorKana());
        StyleConstants.setBackground(kanaStyle, backgroundColor); // nötig
        if (showKanaInKanjiSize) {
            StyleConstants.setFontSize(kanaStyle, FONT_SIZE_BASE + 4);
            StyleConstants.setBold(kanaStyle, true);
        }

        braceStyle = document.addStyle("brace", regularStyle);
        if (showKanaInKanjiSize) {
            StyleConstants.setFontSize(braceStyle, FONT_SIZE_BASE + 4);
        }
    }

    private void clearContent() {
        try {
            StyledDocument document = kanjiAndKanaPane.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 die "
                    + "Kanji und Kana 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 {
        /*
         * TODO will man irgendwann die Kana anders darstellen ohne Kanji,
         * kann man hier den anderen Style nutzen.
         */
        KanjiAndKanaTextCreator creator = new KanjiAndKanaTextCreator(vocable, showKana, showKanji);
        creator.create();
        String firstTextPart = creator.getFirstTextPart();
        String textPartInBrace = creator.getTextPartInBrace();
        boolean braceInOwnLine = creator.isBraceInOwnLine();

        StyledDocument document = kanjiAndKanaPane.getStyledDocument();
        document.insertString(document.getLength(), firstTextPart, kanjiStyle);
        if (braceInOwnLine) {
            document.insertString(document.getLength(), "\n", regularStyle);
        }
        if (!textPartInBrace.isBlank()) {
            document.insertString(document.getLength(), " (", braceStyle);
            document.insertString(document.getLength(), textPartInBrace, kanaStyle);
            document.insertString(document.getLength(), ")", braceStyle);
        }
    }

}
