package de.duehl.vocabulary.japanese.ui.dialog.grammar.subdialogs;

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

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

import de.duehl.swing.ui.GuiTools;
import de.duehl.swing.ui.dialogs.base.ModalDialogBase;
import de.duehl.swing.ui.layout.VerticalLayout;
import de.duehl.swing.ui.move.data.MovingGui;
import de.duehl.vocabulary.japanese.data.Vocable;
import de.duehl.vocabulary.japanese.ui.data.FumikoUiObjects;
import de.duehl.vocabulary.japanese.ui.dialog.grammar.subdialogs.bar.MovableGrammarBaseFormBar;

/**
 * Diese Klasse erzeugt die grafische Oberfläche des Dialoges zur manuellen Sortierung der
 * ermittelten und zuvor vom Benutzer ausgewählten Grundformen von den Verben oder Adjektiven bei
 * der Erstellung von grammatikalischen Tabellen von Verben bzw. Adjektiven.
 *
 * @version 1.01     2025-11-27
 * @author Christian Dühl
 */

public class GrammarTableBaseFormUserSortDialog extends ModalDialogBase
        implements MovingGui<MovableGrammarBaseFormBar>{

    private static final Dimension DIALOG_DIMENSION = new Dimension(800, 600);


    /**
     * Die anzuzeigenden Vokabeln in ihrer Wörterbuch-/Grundform.
     *
     * Diese werden hier bearbeitet.
     */
    private final List<Vocable> baseFormVocables;

    /** Der Panel, auf dem die Bars dargestellt werden. */
    private final JPanel vocablesPanel;

    /** Gibt an, ob der Dialog mit OK beendet wurde. */
    private boolean applied;

    /**
     * Konstruktor.
     *
     * @param dataStructures
     *            Die Datenstrukturen des Vokabeltrainers.
     * @param uiObjects
     *            Die häufig verwendeten Funktionen der grafischen Oberfläche des Vokabeltrainers.
     */
    public GrammarTableBaseFormUserSortDialog(List<Vocable> baseFormVocables,
            FumikoUiObjects uiObjects) {
        super(uiObjects.getGuiLocation(), uiObjects.getProgramImage(),
                "Manuelle Sotierung der Grundformen für die Tabelle", DIALOG_DIMENSION);

        this.baseFormVocables = baseFormVocables;

        vocablesPanel = new JPanel();
        applied = false;

        init();
        populateVocablesPanel();
        fillDialog();
    }

    private void init() {
        initVocablesPanel();
    }

    private void initVocablesPanel() {
        vocablesPanel.setLayout(new VerticalLayout(3, VerticalLayout.BOTH));
    }

    private void populateVocablesPanel() {
        vocablesPanel.removeAll();

        List<MovableGrammarBaseFormBar> bars = new ArrayList<>();
        for (int index = 0; index < baseFormVocables.size(); ++index) {
            MovableGrammarBaseFormBar bar = new MovableGrammarBaseFormBar(
                    (MovingGui<MovableGrammarBaseFormBar>) this,
                    baseFormVocables.get(index),
                    index);
            bars.add(bar);
            vocablesPanel.add(bar.getPanel());
        }

        for (MovableGrammarBaseFormBar bar : bars) { // geht nur hinterher!
            bar.setUpAndDownButtonColorsAndEnabled();
        }

        repaint();
        validate();
        invalidate();

    }

    /** Gibt an, ob die Vokabel auf der übergebenen Bar nach oben bewegt werden kann. */
    @Override
    public boolean canBarMoveUp(MovableGrammarBaseFormBar bar) {
        int index = bar.getIndex();
        return index > 0;
    }

    /** Gibt an, ob die Vokabel auf der übergebenen Bar nach unten bewegt werden kann. */
    @Override
    public boolean canBarMoveDown(MovableGrammarBaseFormBar bar) {
        int index = bar.getIndex();
        return index < baseFormVocables.size() - 1;
    }

    /** Verschiebt die Vokabel auf der übergebene Bar an die erste Stelle. */
    @Override
    public void moveBarToFirst(MovableGrammarBaseFormBar bar) {
        int index = bar.getIndex();
        Vocable vocable = baseFormVocables.remove(index);
        baseFormVocables.add(0, vocable);
        populateVocablesPanel();
    }

    /** Verschiebt die Vokabel auf der übergebene Bar nach oben. */
    @Override
    public void moveBarUp(MovableGrammarBaseFormBar bar) {
        int index = bar.getIndex();
        Vocable vocable = baseFormVocables.remove(index);
        baseFormVocables.add(index - 1, vocable);
        populateVocablesPanel();
    }

    /** Verschiebt die Vokabel auf der übergebene Bar nach unten. */
    @Override
    public void moveBarDown(MovableGrammarBaseFormBar bar) {
        int index = bar.getIndex();
        Vocable vocable = baseFormVocables.remove(index);
        baseFormVocables.add(index + 1 , vocable);
        populateVocablesPanel();
    }

    /** Verschiebt die Vokabel auf der übergebene Bar an die letzte Stelle. */
    @Override
    public void moveBarToLast(MovableGrammarBaseFormBar bar) {
        int index = bar.getIndex();
        Vocable vocable = baseFormVocables.remove(index);
        baseFormVocables.add(vocable);
        populateVocablesPanel();
    }

    /** Baut die Gui auf. */
    @Override
    protected void populateDialog() {
        add(GuiTools.createScrollPane(vocablesPanel), BorderLayout.CENTER);
        add(createButtonPart(), BorderLayout.SOUTH);

        pack();
    }

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

        panel.add(createQuitButton(), BorderLayout.WEST);
        panel.add(createOkButton(), BorderLayout.EAST);

        return panel;
    }

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

    private Component createOkButton() {
        JButton button = new JButton("Auswahl bestätigen");
        button.addActionListener(e -> apply());
        return button;
    }

    private void apply() {
        applied = true;
        closeDialog();
    }

    /** Gibt an, ob der Dialog mit OK beendet wurde. */
    public boolean isApplied() {
        return applied;
    }

}
