package de.duehl.swing.ui.components.selections.base;

/*
 * Copyright 2019 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.Component;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.FocusListener;
import java.awt.event.KeyListener;

import de.duehl.basics.text.Text;
import de.duehl.swing.ui.colors.Colorizer;
import de.duehl.swing.ui.components.elements.TextFieldWithChangeButtonAndTitle;

/**
 * Diese Klasse stellt die abstrakte Basis für eine Auswahl einer Datei oder eines Verzeichnisses
 * etwa in einem Optionendialog dar.
 *
 * @version 1.01     2019-08-13
 * @author Christian Dühl
 */

public abstract class FileOrPathSelection {

    /** Überschrift, Textfeld und Änderungs-Schalter. */
    private final TextFieldWithChangeButtonAndTitle elements;

    private boolean weHaveActionAfterButtonPressed;
    private Runnable actionAfterButtonPressed;

    /** Das Startverzeichnis, das verwendet wird, wenn noch kein Text eingegeben wurde. */
    private String startDirForEmptyText;

    /**
     * Konstruktor.
     *
     * @param title
     *            Überschrift für die Wahl dieser Datei oder dieses Verzeichnisses.
     */
    public FileOrPathSelection(String title) {
        weHaveActionAfterButtonPressed = false;
        startDirForEmptyText = "";
        elements = new TextFieldWithChangeButtonAndTitle(title);
        elements.addButtonActionListener(e -> changeDirectory());
    }

    /** Legt das Startverzeichnis fest, das verwendet wird, wenn noch kein Text eingegeben wurde. */
    public void setStartDirForEmptyText(String startDirForEmptyText) {
        this.startDirForEmptyText = startDirForEmptyText;
    }

    /** Wird aufgerufen, wenn der Button zum Ändern des Pfades gedrückt wird. */
    private void changeDirectory() {
        String startDir = getText();
        if (startDir.isEmpty()) {
            startDir = startDirForEmptyText;
        }

        String selection = openPath(startDir);
        if (!selection.isEmpty()) {
            setText(selection);
            if (weHaveActionAfterButtonPressed) {
                actionAfterButtonPressed.run();
            }
        }
    }

    /**
     * Der Benutzer wählt die Datei oder das Verzeichnis aus.
     *
     * @param startDir
     *            Startverzeichnis.
     * @return Ausgewählte Benutzereingabe oder null bei Abbruch durch den Benutzer.
     */
    abstract protected String openPath(String startDir);

    /** Getter für das Panel mit Überschrift, Pfad und Änderungsbutton. */
    public Component getPanel() {
        return elements.getPanel();
    }

    /** Färbt alle Komponenten mit dem übergebenen Colorizer ein. */
    public void colorize(Colorizer colorizer) {
        elements.colorize(colorizer);
    }

    /** Getter für den (getrimmten) Text des Textfeldes. */
    public String getText() {
        return elements.getText();
    }

    /** Setzt den Text des Textfeldes. */
    public void setText(String text) {
        elements.setText(Text.nicePath(text));
    }

    /** Fügt einen KeyListener zum Textfeld hinzu. */
    public void addKeyListener(KeyListener keyListener) {
        elements.addKeyListener(keyListener);
    }

    /** Fügt einen KeyListener zum Textfeld hinzu, der bei Return den Button auslöst. */
    public void addReturnKeyClickButtonListener() {
        elements.addReturnKeyClickButtonListener();
    }

    /** Fügt einen FocusListener zum Textfeld hinzu. */
    public void addFocusListener(FocusListener focusListener) {
        elements.addFocusListener(focusListener);
    }

    /** Fügt einen ActionListener zum Textfeld hinzu. */
    public void addTextFieldActionListener(ActionListener actionListener) {
        elements.addTextFieldActionListener(actionListener);
    }

    /** Fügt eine Aktion hinzu, die nach dem erfolgreichen Ändern über den Button ausgeführt wird. */
    public void addActionToButton(Runnable runnable) {
        weHaveActionAfterButtonPressed = true;
        actionAfterButtonPressed = runnable;
    }

    /** Setzt den Tooltip. */
    public void setToolTipText(String tooltip) {
        elements.setToolTipText(tooltip);
    }

    /** Setter für den auf dem Änderungsbutton angezeigten Text. */
    public void setButtonText(String title) {
        elements.setButtonText(title);
    }

    /** Setter für die gewünschte Größe des Textfeldes. */
    public void setPreferredSize(Dimension preferredSize) {
        elements.setPreferredSize(preferredSize);
    }

}
