package de.duehl.swing.ui.dialogs;

/*
 * Copyright 2020 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.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;

import de.duehl.swing.ui.dialogs.base.AbstractDialogBase;

/**
 * Diese Klasse bietet Hilfsmethoden für Dialoge und andere Gui-Elemente (JDialog und JFrame) an.
 *
 * @version 1.01     2020-02-04
 * @author Christian Dühl
 */

public class DialogHelper {

    private DialogHelper() {}

    /**
     * Fügt dem Dialog die Tastenkombination Escape hinzu, woraufhin die übergebene Komponente
     * beendet wird.
     *
     * @param dialog
     *            Der Dialog, der sich auf Druck auf die Escape-Taste beenden soll.
     */
    public static void addEscapeBehaviourForJDialog(JDialog dialog) {
        JRootPane rootPane = dialog.getRootPane();
        addEscapeBehaviour(rootPane, dialog);
    }

    /**
     * Fügt dem Frame die Tastenkombination Escape hinzu, woraufhin die übergebene Komponente
     * beendet wird.
     *
     * @param frame
     *            Der Frame, der sich auf Druck auf die Escape-Taste beenden soll.
     */
    public static void addEscapeBehaviourForJFrame(JFrame frame) {
        JRootPane rootPane = frame.getRootPane();
        addEscapeBehaviour(rootPane, frame);
    }

    /**
     * Fügt einer JRootPane die Tastenkombination ESC hinzu.
     *
     * @param rootPane
     *            JRootPane, in die die Tastenkombination eingetragen wird.
     * @param window
     *            Gui-Fenster, dass auf Druck auf die Escape-Taste hin geschlossen wird.
     */
    private static void addEscapeBehaviour(JRootPane rootPane, Window window) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                window.setVisible(false);
                window.dispose();
            }
        };
        addEscapeBehaviour(rootPane, window, runnable);
    }

    /*
     * TODO:
     * Die oberen drei Methoden sind eigentlich veraltete Methoden für Guis, die noch nicht auf die
     * neuen Basisklassen umgestellt wurden.
     *
     * Also sollte man deren verwendenden STellen überarbeiten und sie entfernen!
     */

    /**
     * Fügt dem Frame oder Dialog die Tastenkombination Escape hinzu, woraufhin die übergebene
     * Komponente beendet wird.
     *
     * @param frame
     *            Der Frame, der sich auf Druck auf die Escape-Taste beenden soll.
     */
    public static void addEscapeBehaviourForDialogBase(AbstractDialogBase dialogBase) {
        JRootPane rootPane = dialogBase.getRootPane();
        addEscapeBehaviour(rootPane, dialogBase.getWindow(),
                () -> dialogBase.closeOrCallQuitter());
    }

    /**
     * Fügt einer JRootPane die Tastenkombination ESC hinzu.
     *
     * @param rootPane
     *            JRootPane, in die die Tastenkombination eingetragen wird.
     * @param window
     *            Gui-Fenster, dass auf Druck auf die Escape-Taste hin geschlossen wird.
     * @param runnable
     *            Wird ausgeführt, wenn Escape gedrückt wird.
     */
    private static void addEscapeBehaviour(JRootPane rootPane, Window window, Runnable runnable) {
        InputMap inputMap = rootPane.getInputMap( JComponent.WHEN_IN_FOCUSED_WINDOW);

        KeyStroke escapeStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
        inputMap.put(escapeStroke, "ESCAPE");

        Action escapeAction = new AbstractAction() {
            private static final long serialVersionUID = 1L;
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                runnable.run();
            }
        };

        rootPane.getActionMap().put("ESCAPE", escapeAction);
    }

    // TODO Scrollbindungen für Editor- und HTMLDialog hier rein, Scrollbar halt übergeben.

}
