package de.duehl.vocabulary.japanese.ui.dialog.vocables.sheet;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;

import de.duehl.basics.collections.CollectionsHelper;
import de.duehl.basics.text.NumberString;
import de.duehl.swing.logic.LongTimeProcessInformer;
import de.duehl.swing.ui.GuiTools;
import de.duehl.swing.ui.components.MultipleElementsPanel;
import de.duehl.swing.ui.dialogs.base.NonModalFrameDialogBase;
import de.duehl.vocabulary.japanese.common.persistence.Options;
import de.duehl.vocabulary.japanese.data.FumikoDataStructures;
import de.duehl.vocabulary.japanese.data.Vocable;
import de.duehl.vocabulary.japanese.ui.components.button.OtherViewButtonPanel;
import de.duehl.vocabulary.japanese.ui.components.button.ViewButtonPressedReactor;
import de.duehl.vocabulary.japanese.ui.data.FumikoUiObjects;
import de.duehl.vocabulary.japanese.ui.tools.VocabularyTrainerUiTools;

/**
 * Diese Klasse zeigt eine Menge von Vokabeln in Form eines Vokabelblattes an.
 *
 * @version 1.01     2025-11-20
 * @author Christian Dühl
 */

public class VocabularySheetDialog extends NonModalFrameDialogBase
        implements ViewButtonPressedReactor {

    private static final Dimension DIALOG_DIMENSION = new Dimension(1500, 900);

    private static final int DEFAULT_NUMBER_OF_VOCABLES_IN_ONE_ROW = 3;

    private static final List<Integer> POSSIBLE_COLUMNS =
            CollectionsHelper.buildListFrom(1, 2, 3, 4);

    //private static final int MAXIMAL_NUMBER_OF_VOCABLES_FOR_COLUMNS_CHANGE = 100;


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

    /**
     * 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.
     */
    private final OtherViewButtonPanel otherViewPanel;

    /** Die ScrollPane um die Vokabeln. */
    private JScrollPane vocablesScrollPane;

    /** Der Panel mit der ScrollPane um die Vokabeln. */
    private final JPanel vocablesJPanel;

    /** Die Anzahl der Spalten für die Darstellung als Vokabelblatt. */
    private int numberOfColumns;

    /** Die Auswahlmöglichkeit der Anzahl an Spalten mit den auf einer Seite angezeigten Daten. */
    private final JComboBox<Integer> numberOfColumnsComboBox;

    /** Der Button mit dem man das Einfärben des Hintergrunds ein- und ausschaltet. */
    private final JButton backgroundChangingButton;

    /** Die Liste mit den Paneln der dargestellten Vokabeln. */
    private final List<Component> vocablePanes;

    /**
     * Konstruktor.
     *
     * @param vocables
     *            Die Liste mit den anzuzeigenden Vokabeln.
     * @param vocablePanes
     *            Die Liste mit den Paneln der dargestellten Vokabeln.
     * @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 informer
     *            Die Oberfläche, welche diese Klasse aufruft, auf der man eine GlassPane anzeigen
     *            kann.
     * @param parentLocation
     *            Position des Rahmens der Oberfläche, vor der dieser Dialog erzeugt wird.
     */
    public VocabularySheetDialog(List<Vocable> vocables, List<Component> vocablePanes,
            String description, FumikoDataStructures dataStructures, FumikoUiObjects uiObjects,
            LongTimeProcessInformer informer, Point parentLocation) {
        super(parentLocation, uiObjects.getProgramImage(),
                createDialogTitle(vocables, description, dataStructures), DIALOG_DIMENSION);
        addEscapeBehaviour();

        this.vocablePanes = vocablePanes;
        this.dataStructures = dataStructures;

        vocablesJPanel = new JPanel();

        otherViewPanel = new OtherViewButtonPanel(vocables, (ViewButtonPressedReactor) this,
                description, dataStructures, uiObjects, informer);
        otherViewPanel.disableVokabelblattDarstellungButton();

        Options options = dataStructures.getOptions();
        numberOfColumns = options.getNumberOfColumnsOfBlattDarstellung();
        if (numberOfColumns < 1) {
            numberOfColumns = DEFAULT_NUMBER_OF_VOCABLES_IN_ONE_ROW;
        }
        numberOfColumnsComboBox = new JComboBox<>();

        backgroundChangingButton = new JButton();

        init();
        rearrangeVocablePart();
        fillDialog();
    }

    private static String createDialogTitle(List<Vocable> vocables, String description,
            FumikoDataStructures dataStructures) {
        String frontTitle = "Anzeige mit den " + NumberString.taupu(vocables.size())
                + " Vokabeln aus " + description;
        return VocabularyTrainerUiTools.generateTitleWithVocabularyTestSuccesss(vocables,
                frontTitle, dataStructures);
    }

    private void init() {
        initVocablesPanel();
        initNumberOfColumnsComboBox();
        initBackgroundChangingButton();
    }

    private void initVocablesPanel() {
        vocablesJPanel.setLayout(new BorderLayout());
    }

    private void initNumberOfColumnsComboBox() {
        numberOfColumnsComboBox.setAlignmentX(JLabel.CENTER);
        numberOfColumnsComboBox.setAlignmentY(JLabel.CENTER);
        ((JLabel) numberOfColumnsComboBox.getRenderer()).setHorizontalAlignment(
                SwingConstants.RIGHT);

        List<Integer> possibleColumns = new ArrayList<>();
        possibleColumns.addAll(POSSIBLE_COLUMNS);
        if (!POSSIBLE_COLUMNS.contains(numberOfColumns)) {
            possibleColumns.add(numberOfColumns);
        }
        for (int value : possibleColumns) {
            numberOfColumnsComboBox.addItem(value);
        }

        numberOfColumnsComboBox.setSelectedItem(numberOfColumns);
        numberOfColumnsComboBox.addActionListener(e -> rearrangePageAfterChangedNumbers());
    }

    private void initBackgroundChangingButton() {
        setBackgroundChangingButtonTitle();
        backgroundChangingButton.addActionListener(e -> toggleBackground());
    }

    private void setBackgroundChangingButtonTitle() {
        Options options = dataStructures.getOptions();
        String buttonText = ""
                + "Hintergrund "
                + (options.isColorVocableDependingOnLastSuccessWhenViewingVocable()
                        ? "aus"
                        : "ein")
                + "schalten";
        backgroundChangingButton.setText(buttonText);
    }

    private void toggleBackground() {
        Options options = dataStructures.getOptions();
        boolean onOrOff = options.isColorVocableDependingOnLastSuccessWhenViewingVocable();
        onOrOff = !onOrOff;
        options.setColorVocableDependingOnLastSuccessWhenViewingVocable(onOrOff);
        setBackgroundChangingButtonTitle();
        rearrangePageAfterChangedNumbers() ;
    }

    private void rearrangePageAfterChangedNumbers() {
        numberOfColumns = (Integer) numberOfColumnsComboBox.getSelectedItem();
        rearrangeVocablePart();
        Options options = dataStructures.getOptions();
        options.setNumberOfColumnsOfBlattDarstellung(numberOfColumns);
    }

    private void rearrangeVocablePart() {
        JPanel panel = new MultipleElementsPanel<Component>(vocablePanes, numberOfColumns, 1);
        vocablesScrollPane = GuiTools.createScrollPane(panel);

        vocablesJPanel.removeAll();
        vocablesJPanel.add(vocablesScrollPane, BorderLayout.CENTER);

        //vocablesScrollPane.repaint();
        vocablesJPanel.repaint();
        vocablesJPanel.validate();
        vocablesJPanel.invalidate();

        GuiTools.scrollScrollbarToMinimumLater(vocablesScrollPane);
    }

    /** Baut die Gui auf. */
    @Override
    protected void populateDialog() {
        add(createUpperPart(), BorderLayout.NORTH);
        add(vocablesJPanel, BorderLayout.CENTER);
        add(createButtonsPart(), BorderLayout.SOUTH);
    }

    private Component createUpperPart() {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        GuiTools.createTitle(panel);

        panel.add(backgroundChangingButton, BorderLayout.WEST);

        // das kann man jetzt lassen, da sie nicht neu erzeugt werden!
        //if (vocablePanes.size() <= MAXIMAL_NUMBER_OF_VOCABLES_FOR_COLUMNS_CHANGE) {
            panel.add(createNumberOfColumnsComboBoxWithTitelPart(), BorderLayout.EAST);
        //}

        return panel;
    }

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

        panel.add(new JLabel("Anzahl Spalten "), BorderLayout.WEST);
        panel.add(numberOfColumnsComboBox, BorderLayout.CENTER);

        return panel;
    }

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

        panel.add(createQuitButton(), BorderLayout.EAST);
        panel.add(GuiTools.centerHorizontal(otherViewPanel.getPanel()), BorderLayout.CENTER);

        return panel;
    }

    private Component createQuitButton() {
        JButton button = new JButton("Beenden");
        button.addActionListener(e -> quit());
        return button;
    }

    private void quit() {
        closeDialog();
    }

    /** Wird aufgerufen, wenn die Vokabeln in einer anderen Ansicht angezeigt werden. */
    @Override
    public void otherViewOpened() {
        closeDialog();
    }

}
