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

import java.awt.Component;
import java.awt.GridLayout;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JPanel;

import de.duehl.basics.text.NumberString;
import de.duehl.swing.logic.LongTimeProcessInformer;
import de.duehl.swing.ui.GuiTools;
import de.duehl.vocabulary.japanese.data.FumikoDataStructures;
import de.duehl.vocabulary.japanese.data.Vocable;
import de.duehl.vocabulary.japanese.ui.data.FumikoUiObjects;
import de.duehl.vocabulary.japanese.ui.dialog.vocables.lister.VocabularyListerDialog;
import de.duehl.vocabulary.japanese.ui.dialog.vocables.sheet.VocableSheetsCreator;
import de.duehl.vocabulary.japanese.ui.dialog.vocables.sheet.VocabularySheetDialog;
import de.duehl.vocabulary.japanese.ui.dialog.vocables.single.SingleVocableVocabularyViewerDialog;

/**
 * Diese Klasse zeigt drei Buttons an, mit denen man eine Menge von Vokabeln in Form einer
 * Einzeldarstellung, in Form einer Liste und in Form eines Vokabelblattes anzeigen lassen kann.
 *
 * @version 1.01     2025-11-20
 * @author Christian Dühl
 */

public class OtherViewButtonPanel {

    /** Die Liste mit den anzuzeigenden Vokabeln. */
    private final List<Vocable> vocables;

    /**
     * Der OtherViewButtonPanel anzeigende Dialog, der die eigene Anzeige beendet, wenn in dieser
     * Klasse eine andere Anzeige aufgerufen wurde.
     */
    private final ViewButtonPressedReactor reactor;

    /** Die Beschreibung der Menge von Vokabeln. */
    private final String description;

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

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

    /** Die Oberfläche, welche diese Klasse aufruft, auf der man eine GlassPane anzeigen kann. */
    private final LongTimeProcessInformer informer;

    /** Der Panel mit den drei Buttons. */
    private final JPanel panel;

    /** Der Button zur Ansicht der Einzeldarstellung. */
    private final JButton einzeldarstellungButton;

    /** Der Button zur Ansicht als Liste. */
    private final JButton listenDarstellungButton;

    /** Der Button zur Ansicht als Vokabelblatt. */
    private final JButton blattDarstellungButton;

    /**
     * Konstruktor.
     *
     * @param vocables
     *            Die Liste mit den anzuzeigenden Vokabeln.
     * @param reactor
     *            Der OtherViewButtonPanel anzeigende Dialog, der die eigene Anzeige beendet, wenn
     *            in dieser Klasse eine andere Anzeige aufgerufen wurde.
     * @param description
     *            Die Beschreibung der Menge von Vokabeln.
     * @param dataStructures
     *            Die Datenstrukturen des Vokabeltrainers.
     * @param uiObjects
     *            Die häufig verwendeten Funktionen der grafischen Oberfläche des Vokabeltrainers.
     * @param longTimeProcessInformer
     *            Die Oberfläche, welche diese Klasse aufruft, auf der man eine GlassPane anzeigen
     *            kann.
     */
    public OtherViewButtonPanel(List<Vocable> vocables, ViewButtonPressedReactor reactor,
            String description, FumikoDataStructures dataStructures, FumikoUiObjects uiObjects,
            LongTimeProcessInformer informer) {
        this.vocables = vocables;
        this.reactor = reactor;
        this.description = description;
        this.dataStructures = dataStructures;
        this.uiObjects = uiObjects;
        this.informer = informer;

        panel = new JPanel();
        einzeldarstellungButton = new JButton();
        listenDarstellungButton = new JButton();
        blattDarstellungButton = new JButton();

        createGui();
    }

    private void createGui() {
        initPanel();
        initEinzeldarstellungButton();
        initListenDarstellungButton();
        initVokabelblattDarstellungButton();

        fillPanel();
    }

    private void initPanel() {
        panel.setLayout(new GridLayout(0, 3, 5, 5));
    }

    private void initEinzeldarstellungButton() {
        einzeldarstellungButton.setText("Einzeldarstellung");
        einzeldarstellungButton.addActionListener(e -> einzeldarstellung());
    }

    private void einzeldarstellung() {
        closeOldViewer();

        SingleVocableVocabularyViewerDialog dialog = new SingleVocableVocabularyViewerDialog(
                vocables, description, dataStructures, uiObjects);
        dialog.setVisible(true);
    }

    private void closeOldViewer() {
        reactor.otherViewOpened();
    }

    private void initListenDarstellungButton() {
        listenDarstellungButton.setText("Liste");
        listenDarstellungButton.addActionListener(e -> listenDarstellung());
    }

    private void listenDarstellung() {
        closeOldViewer();

        VocabularyListerDialog dialog = new VocabularyListerDialog(vocables, description,
                dataStructures, uiObjects, uiObjects.getGuiLocation(), uiObjects.getInformer());
        dialog.setVisible(true);
    }

    private void initVokabelblattDarstellungButton() {
        blattDarstellungButton.setText("Blatt");
        blattDarstellungButton.addActionListener(e -> vokabelblattDarstellung());
    }

    private void vokabelblattDarstellung() {
        closeOldViewer();
        informer.startLongTimeProcess(
                "Öffne Blattdarstellung mit " + NumberString.taupu(vocables.size()) + " Vokabeln");
        new Thread(() -> listVocabularyAsSheetInOwnThread()).start();
    }

    private void listVocabularyAsSheetInOwnThread() {
        try {
            tryToListVocabularyAsSheetInOwnThread();
        }
        catch (Exception exception) {
            GuiTools.informUser("Hier ging etwas schief", "Bei der Erzeugng der Panel für die "
                    + "Blattdarstellung gab es ein Problem.");
            informer.endLongTimeProcess();
        }
    }

    private void tryToListVocabularyAsSheetInOwnThread() {
        VocableSheetsCreator creator = new VocableSheetsCreator(
                vocables, dataStructures, uiObjects,
                (vocables, vocablePanes) -> listVocabularyAsSheetInEdt(vocables, vocablePanes),
                uiObjects.getGuiLocation());
        creator.create();
    }

    private void listVocabularyAsSheetInEdt(List<Vocable> vocables, List<Component> vocablePanes) {
        try {
            tryToListVocabularyAsSheetInEdt(vocables, vocablePanes);
        }
        catch (Exception exception) {
            GuiTools.informUser("Hier ging etwas schief", "Bei der Anzeige der Blattdarstellung "
                    + "gab es ein Problem.");
            informer.endLongTimeProcess();
        }
    }

    private void tryToListVocabularyAsSheetInEdt(List<Vocable> vocables,
            List<Component> vocablePanes) {
        VocabularySheetDialog dialog = new VocabularySheetDialog(vocables, vocablePanes,
                description, dataStructures, uiObjects, informer, uiObjects.getGuiLocation());
        dialog.setVisible(true);
        dialog.requestFocus();
        informer.endLongTimeProcess();
    }

    private void fillPanel() {
        panel.add(einzeldarstellungButton);
        panel.add(listenDarstellungButton);
        panel.add(blattDarstellungButton);
    }

    /** Deaktiviert den Button zur Ansicht der Einzeldarstellung. */
    public void disableEinzeldarstellungButton() {
        einzeldarstellungButton.setEnabled(false);
    }

    /** Deaktiviert den Button zur Ansicht als Liste. */
    public void disableListenDarstellungButton() {
        listenDarstellungButton.setEnabled(false);
    }

    /** Deaktiviert den Button zur Ansicht als Vokabelblatt. */
    public void disableVokabelblattDarstellungButton() {
        blattDarstellungButton.setEnabled(false);
    }

    /** Getter für den Panel mit den drei Buttons. */
    public JPanel getPanel() {
        return panel;
    }

}
