package de.duehl.swing.ui.dialogs.lists;

/*
 * Copyright 2021 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;

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

import de.duehl.swing.ui.GuiTools;
import de.duehl.swing.ui.dialogs.lists.logic.LogicalEditableList;
import de.duehl.swing.ui.dialogs.lists.logic.LogicalEditableListElement;
import de.duehl.swing.ui.dialogs.lists.ui.EditableListElement;

/**
 * Diese Klasse erlaubt die Auswahl aus einer Liste, die mit dem EditableListDialog bearbeitet
 * werden kann.
 *
 * @version 1.02     2021-11-17
 * @author Christian Dühl
 */

public abstract class SelectFromEditableListDialog<Element extends LogicalEditableListElement>
        extends EditableListDialogBase<Element> {

    /** Gibt an, ob der Benutzer eine Auswahl getroffen hat. */
    private boolean userHasSelected;

    /** Vom Benutzer ausgewähltes Element. */
    private Element userSelectedElement;

    /**
     * Konstruktor.
     *
     * Die abgeleitete Klasse muss <code>fillDialog()</code> aufrufen.
     *
     * @param dialogDimension
     *            Größe des Dialogfensters.
     * @param parentLocation
     *            Position des Rahmens der Oberfläche, vor der dieser Dialog erzeugt wird.
     * @param programImage
     *            Icon für das Programm.
     * @param dialogTitle
     *            Titel des Dialogs.
     * @param logicalList
     *            Liste mit den logischen Elementen, welche dargestellt werden
     */
    public SelectFromEditableListDialog(Dimension dialogDimension, Point parentLocation,
            Image programImage, String dialogTitle, LogicalEditableList<Element> logicalList) {
        super(dialogDimension, parentLocation, programImage, dialogTitle, logicalList);

        userHasSelected = false;
        userSelectedElement = null;
    }

    /** Erzeugt den Hauptbereich des Dialogs. */
    @Override
    protected final Component createMainPart() {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        panel.add(getElementsPanel(), BorderLayout.CENTER);

        return panel;
    }

    /** Erzeugt die Darstellung für das übergebene Element. */
    @Override
    protected Component createRealElementPart(Element element) {
        EditableListElement<Element> uiElement = createUiElement(element);
        JButton button = uiElement.createSelectButton();
        GuiTools.biggerFont(button, 3);
        button.addActionListener(e -> selectElement(element));
        return button;
    }

    private void selectElement(Element element) {
        userSelectedElement = element;
        userHasSelected = true;
        closeDialog();
    }

    /**
     * Gibt an, ob der Benutzer eine Auswahl per Klick auf einen der Buttons getroffen hat. Falls
     * der Dialog über den Button unten oder das x geschlossen wurde, wird false zurückgegeben.
     */
    public final boolean hasUserSelected() {
        return userHasSelected;
    }

    /**
     * Gibt das vom Benutzer ausgewählte Element zurück.
     *
     * Es sollte vorher mit hasUserSelected() überprüft werden, ob eins ausgewählt wurde.
     *
     * Falls keines ausgewählt wurde, wird eine Ausnahme geworfen.
     */
    public final Element getUserSelection() {
        if (!hasUserSelected()) {
            throw new RuntimeException("Kein Element ausgewählt! Der Aufruf von getUserSelection() "
                    + "muss vorher durch hasUserSelected() überprüft werden!");
        }
        if (null == userSelectedElement) {
            throw new RuntimeException("Interner Fehler: Der Benutzer hat ausgewählt, das Objekt "
                    + "ist aber nicht definiert!");
        }

        return userSelectedElement;
    }

}
