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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

import de.duehl.swing.ui.GuiTools;
import de.duehl.swing.ui.dialogs.base.additional.LocationGetter;
import de.duehl.swing.ui.move.SwitchableVerticalMoveButtons;
import de.duehl.swing.ui.move.data.VerticalMoveButtonsUser;
import de.duehl.vocabulary.japanese.data.FumikoDataStructures;
import de.duehl.vocabulary.japanese.data.symbol.Kanji;
import de.duehl.vocabulary.japanese.ui.data.FumikoUiObjects;
import de.duehl.vocabulary.japanese.ui.dialog.kanji.detail.KanjiDetailDialog;
import de.duehl.vocabulary.japanese.ui.dialog.kanji.kanjiset.KanjiSetEditor;

/**
 * Diese Klasse stellt die grafische Oberfläche der Anzeige eines Kanji im Editor zur Bearbeiten
 * von Kanji-Mengen dar.
 *
 * @version 1.01     2025-11-27
 * @author Christian Dühl
 */

public class KanjiBar implements VerticalMoveButtonsUser {

    /** Das angezeigte Kanji. */
    private final Kanji kanji;

    /** Wird ausgeführt, wenn der Button gedrückt wird. */
    private final Runnable buttonAction;

    /** Der Dialog, in dem die Bars bewegt etc. werden. */
    private final KanjiSetEditor gui;

    /** Die Datenstrukturen des Vokabeltrainers. */
    private final FumikoDataStructures dataStructures;

    /** Die häufig verwendeten Funktionen der grafischen Oberfläche des Vokabeltrainers. */
    private final FumikoUiObjects uiObjects;

    /**
     * Das Objekt, das die aktuelle Position der Oberfläche des nutzenden Dialogs zurück geben
     * kann.
     */
    private final LocationGetter locationGetter;

    /** Der Panel auf dem das Kanji dargestellt wird. */
    private final JPanel panel;

    /** Der Panel auf dem der Schalter und vielleicht auch die CheckBox dargestellt wird. */
    private final JPanel rightPanel;

    /** Das Label, auf dem das Kanji dargestellt wird. */
    private final JLabel kanjiLabel;

    /** CheckBox zur Selektion. */
    private final JCheckBox selectionCheckBox;

    /** Der Button zum Anzeigen der Details des Kanji. */
    private final JButton detailsButton;

    /** Der Multifunktions-Button (Hinzufügen zur Liste oder Löschen aus Liste). */
    private final JButton multifunctionButton;

    /** Der umschaltbare Panel mit Buttons zum Verschieben nach oben und unten. */
    private final SwitchableVerticalMoveButtons switchableMoveButtons;

    /**
     * Konstruktor für den Dialog zur Bearbeitung einer Kanji-Menge (KanjiSetEditor) (rechte oder
     * linke Seite).
     *
     * Diese Klasse wird sowohl in der Kanji-Menge rechts als auch links in der gefilterten Liste
     * aller Kanji genutzt.
     *
     * @param kanji
     *            Das angezeigte Kanji.
     * @param buttonAction
     *            Wird ausgeführt, wenn der Button gedrückt wird.
     * @param gui
     *            Der Dialog, in dem die Bars bewegt etc. werden.
     * @param dataStructures
     *            Die Datenstrukturen des Vokabeltrainers.
     * @param uiObjects
     *            Die häufig verwendeten Funktionen der grafischen Oberfläche des Vokabeltrainers.
     * @param locationGetter
     *            Das Objekt, das die aktuelle Position der Oberfläche des nutzenden Dialogs zurück
     *            geben kann.
     */
    public KanjiBar(Kanji kanji, Runnable buttonAction, KanjiSetEditor gui,
            FumikoDataStructures dataStructures, FumikoUiObjects uiObjects,
            LocationGetter locationGetter) {
        this.kanji = kanji;
        this.buttonAction = buttonAction;
        this.gui = gui;
        this.dataStructures = dataStructures;
        this.uiObjects = uiObjects;
        this.locationGetter = locationGetter;

        panel = new JPanel();
        kanjiLabel = new JLabel();
        rightPanel = new JPanel();
        detailsButton = new JButton();
        multifunctionButton = new JButton();
        selectionCheckBox = new JCheckBox();
        switchableMoveButtons = new SwitchableVerticalMoveButtons((VerticalMoveButtonsUser) this);

        init();
    }

    private void init() {
        initKanjiLabel();
        initButtons();
        initRightPanel();
    }

    private void initKanjiLabel() {
        kanjiLabel.setText(createKanjiText());
        GuiTools.biggerFont(kanjiLabel, 20);
        kanjiLabel.setHorizontalAlignment(JLabel.CENTER);
    }

    private void initButtons() {
        initMultifunctionButton();
        initDetailsButton();
    }

    private void initMultifunctionButton() {
        multifunctionButton.addActionListener(e -> buttonAction.run());
    }

    private void initDetailsButton() {
        detailsButton.setText("?");
        detailsButton.addActionListener(e -> showKanjiDetails());
    }

    private void showKanjiDetails() {
        KanjiDetailDialog dialog = new KanjiDetailDialog(kanji, dataStructures , uiObjects,
                uiObjects.getInformer(), locationGetter.getLocation());
        dialog.setVisible(true);
    }

    private void initRightPanel() {
        rightPanel.setLayout(new BorderLayout());
        rightPanel.add(multifunctionButton, BorderLayout.EAST);
    }

    /**
     * Nutzt den Button im Dialog zur Bearbeitung von Kanji-Mengen auf der linken Seite zum
     * Hinzufügen und zeigt auch die CheckBox zur Auswahl der Kanji an.
     */
    public void useButtonAsAddKanjiToList() {
        multifunctionButton.setText("hinzufügen");
        rightPanel.add(selectionCheckBox, BorderLayout.WEST);
    }

    /**
     * Nutzt den Button im Dialog zur Bearbeitung von Kanji-Mengen auf der rechten Seite zum Löschen.
     * Die CheckBox wird nicht angezeigt.
     */
    public void useButtonAsDeletion() {
        multifunctionButton.setText("entfernen");
    }

    /** Baut die Gui auf. */
    public void createGui() {
        setUpAndDownButtonColorsAndEnabled();
        fillPanel();
    }

    /** Kennzeichnet das Kanji als ausgegraut (es ist bereits in der Liste). */
    public void disable() {
        detailsButton.setEnabled(false);
        multifunctionButton.setEnabled(false);
        selectionCheckBox.setSelected(false);
        selectionCheckBox.setEnabled(false);
        kanjiLabel.setForeground(Color.LIGHT_GRAY);
    }

    /** Kennzeichnet das Kanji als aktiv (es ist nicht in der Liste). */
    public void enable() {
        detailsButton.setEnabled(true);
        multifunctionButton.setEnabled(true);
        selectionCheckBox.setEnabled(true);
        kanjiLabel.setForeground(Color.BLACK);
    }

    /** Gibt an, ob die Bar eines Vokabulars nach oben bewegt werden kann. */
    @Override
    public boolean canMoveButtonsUserMoveUp() {
        return gui.canBarMoveUp(kanji);
    }

    /** Gibt an, ob die Bar eines Vokabulars nach unten bewegt werden kann. */
    @Override
    public boolean canMoveButtonsUserMoveDown() {
        return gui.canBarMoveDown(kanji);
    }

    /** Verschiebt die Bar eines Vokabulars an die erste Stelle. */
    @Override
    public void moveMoveButtonsUserToFirst() {
        gui.moveBarToFirst(kanji);
    }

    /** Verschiebt die Bar eines Vokabulars nach oben. */
    @Override
    public void moveMoveButtonsUserUp() {
        gui.moveBarUp(kanji);
    }

    /** Verschiebt die Bar eines Vokabulars  nach unten. */
    @Override
    public void moveMoveButtonsUserDown() {
        gui.moveBarDown(kanji);
    }

    /** Verschiebt die Bar eines Vokabulars an die letzte Stelle. */
    @Override
    public void moveMoveButtonsUserToLast() {
        gui.moveBarToLast(kanji);
    }

    /**
     * Setzt die Farben und Darstellung der Buttons abhängig davon, ob sie verschoben werden
     * können.
     */
    public void setUpAndDownButtonColorsAndEnabled() {
        switchableMoveButtons.setUpAndDownButtonColorsAndEnabled();
    }

    private void fillPanel() {
        panel.setLayout(new BorderLayout());
        GuiTools.createTitle(panel);

        panel.add(detailsButton, BorderLayout.WEST);
        panel.add(kanjiLabel, BorderLayout.CENTER);
        panel.add(createButtonPart(), BorderLayout.EAST);
    }

    private Component createButtonPart() {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        panel.add(rightPanel, BorderLayout.WEST);
        panel.add(switchableMoveButtons.getPanel(), BorderLayout.EAST);

        return panel;
    }

    private String createKanjiText() {
        return kanji.getCharacter();
    }

    /** Getter für den Panel auf dem das Kanji dargestellt wird. */
    public Component getPanel() {
        return panel;
    }

    /** Setzt das Kanji aus aus- oder nicht ausgewählt. */
    public void setSelected(boolean selected) {
        selectionCheckBox.setSelected(selected);
    }

    /** Gibt an, ob das Kanji ausgewählt ist. */
    public boolean isSelected() {
        return selectionCheckBox.isSelected();
    }

    /** Zeigt die Buttons zum Verschieben an oder blendet wie aus. */
    public void showMoveButtonsOnBars(boolean showMoveButtonsOnBars) {
        switchableMoveButtons.showMoveButtons(showMoveButtonsOnBars);
        panel.repaint();
    }

}
