/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */
package net.sf.jaxodraw.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import net.sf.jaxodraw.gui.swing.JaxoTitledBorder;
import net.sf.jaxodraw.util.JaxoLanguage;
import net.sf.jaxodraw.util.JaxoDictionary;


/**
 * A convenience class for user input dialogs.
 * The common 'parent' Component argument is the Component whose Window
 * to use as owner for the dialog. It may be 'null' (history, it was),
 * but this should be avoided in future.
 *
 * @since 2.0
 */
public final class JaxoDialogs {
    /** Empty private constructor to prevent the class from being
     * explicitly instantiated.
     */
    private JaxoDialogs() {
        // empty on purpose
    }

    /**
     * Format a text that is already translated as a window title (usually, adding prefix).
     * @param text The title text.
     * @return The formatted title.
     */

    public static String translatedWindowTitle(final String text) {
        return JaxoLanguage.message("JaxoDraw.windowTitle%0", text);
    }

    /** Like {@link JaxoLanguage#translate(String)},
     * but format as a window title (usually, adding prefix).
     * @param key The key of the title text.
     * @return The formatted title.
     */
    public static String windowTitle(final String key) {
        return translatedWindowTitle(JaxoLanguage.translate(key));
    }

    /** Like {@link JaxoLanguage#message(String,Object[])},
     * but format as a window title (usually, adding prefix).
     * @param key The key of the title text.
     * @param arguments An array of arguments.
     * @return The formatted title.
     */
    public static String windowTitle(final String key, final Object[] arguments) {
        return translatedWindowTitle(JaxoLanguage.message(key, arguments));
    }

    /** Like {@link JaxoDictionary#value(String)},
     * but format as a window title (usually, adding prefix).
     * @param d The dictionary for  the title text.
     * @param key The key of the title text.
     * @return The formatted title.
     */
    public static String windowTitle(final JaxoDictionary d, final String key) {
        return translatedWindowTitle(d.value(key));
    }

    /** Like {@link JaxoDictionary#message(String,Object[])},
     * but format as a window title (usually, adding prefix).
     * @param key The key of the title text.
     * @param d The dictionary for  the title text.
     * @param arguments An array of arguments.
     * @return The formatted title.
     */
    public String windowTitle(final JaxoDictionary d, final String key, final Object[] arguments) {
        return translatedWindowTitle(d.message(key, arguments));
    }

    /**
     * A new JDialog with the first Dialog/Frame ancestor as owner and the
     * given arguments.
     * @param aparent The parent component.
     * @param title The dialog title.
     * @param modal True to make the dialog modal.
     * @return The dialog.
     */
    public static JDialog newDialog(final Component aparent, final String title,
        final boolean modal) {
        Component parent = aparent;
        while (!(
                    (parent == null) || parent instanceof Dialog
                    || parent instanceof Frame
                )) {
            parent = parent.getParent();
        }

        return (parent instanceof Dialog)
        ? new JDialog((Dialog) parent, title, modal)
        : new JDialog((Frame) parent, title, modal);
    }

    /**
     * Show 'contents' in a new modal dialog with title 'title' and owner determined
     * by 'parent'; adding "OK" and "Cancel" buttons. If the user chooses "OK", the
     * ActionListener argument is notified.
     * @param parent The parent component.
     * @param title The title.
     * @param contents The dialog contents.
     * @param l The actionlistener to notify if the dialog is approved. If l is null,
     *      this method returns without bringing up the dialog.
     */
    public static void showMiniDialog(final Component parent, final String title,
        final Object contents, final ActionListener l) {
        if (l == null) {
            return;
        }

        final String[] optionButtonNames =
        {JaxoLanguage.translate("OK"), JaxoLanguage.translate("Cancel")};

        if (JOptionPane.showOptionDialog(parent, contents,
                    translatedWindowTitle(title), JOptionPane.DEFAULT_OPTION,
                    JOptionPane.PLAIN_MESSAGE, null, optionButtonNames,
                    optionButtonNames[0]) == 0) {
            l.actionPerformed(new ActionEvent(JaxoDialogs.class,
                    ActionEvent.ACTION_PERFORMED, null));
        }
    }

    /** Shows a simple MessageDialog to display an error message.
     * @param parent The parent component.
     * @param message The message to display.
     * @param title The window title.
     */
    public static void showErrorDialog(final Component parent, final String message,
        final String title) {
        JOptionPane.showMessageDialog(parent, message,
            title, JOptionPane.ERROR_MESSAGE);
    }

    /** Shows a simple MessageDialog to display an error message.
     * @param parent The parent component.
     * @param message The message to display.
     */
    public static void showErrorDialog(final Component parent, final String message) {
        showErrorDialog(parent, message, JaxoLanguage.translate("Error"));
    }

    /** Shows a simple MessageDialog to display an info message.
     * @param parent The parent component.
     * @param message The message to display.
     * @param title The window title.
     */
    public static void showInfoDialog(final Component parent, final String message,
        final String title) {
        JOptionPane.showMessageDialog(parent, message, title,
            JOptionPane.INFORMATION_MESSAGE);
    }

    /** Shows a simple MessageDialog to display an error message.
     * The actual message is looked up in one of the resource bundles
     * defined by JaxoDraw via the given  messageKey.
     * @param parent The parent component.
     * @param messageKey The ResourceBundle key to look up the message.
     */
    public static void showI18NErrorDialog(final Component parent, final String messageKey) {
        showErrorDialog(parent, JaxoLanguage.translate(messageKey));
    }

    /**
     * Pops up a JOptionPane to allow the user to enter some text.
     * @param parent The parent component.
     * @param oldName The old tab name.
     * @return The entered text string.
     */
    public static String getNewTabName(final Component parent, final String oldName) {
        final String[] text = {""};
        final String msg1 =
            JaxoLanguage.translate("JaxoDialogs.tabName.explanation");
        final JTextField textField = new JTextField(oldName, 20);
        textField.select(0, oldName.length());

        final Object[] array = {msg1, textField};

        showMiniDialog(parent,
            JaxoLanguage.translate("JaxoDialogs.tabName.title"), array,
            new ActionListener() {
                public void actionPerformed(final ActionEvent e) {
                    text[0] = textField.getText();
                }
            });

        return text[0];
    }

    /**
     * Opens a dialog to choose a new description for a graph.
     * @param parent The parent component.
     * @param old The old description.
     * @return The entered text string, or null if the dialog was canceled.
     */
    public static String getDescription(final Component parent, final String old) {
        final String[] result = new String[1];

        final String msg1 =
            JaxoLanguage.translate("JaxoDialogs.graphDescription.explanation1");
        final String msg2 =
            JaxoLanguage.translate("JaxoDialogs.graphDescription.explanation2");
        final JTextField textField = new JTextField(old, 70);
        final Object[] array = {msg1, msg2, textField};

        showMiniDialog(parent,
            JaxoLanguage.translate("JaxoDialogs.graphDescription.title"),
            array,
            new ActionListener() {
                public void actionPerformed(final ActionEvent e) {
                    result[0] = textField.getText();
                }
            });

        return result[0];
    }

    /**
     * Opens a dialog to enter a text.
     * @param parent The parent component.
     * @return The entered text string.
     */
    public static String getText(final Component parent) {
        final String text =
            JOptionPane.showInputDialog(parent,
                JaxoLanguage.translate("JaxoDialogs.text.explanation"),
                windowTitle("JaxoDialogs.text.title"),
                JOptionPane.PLAIN_MESSAGE);

        if (text == null) {
            return "";
        }

        return text;
    }

    /**
     * A new JPanel with LINE_AXIS BoxLayout.
     * @return A new JPanel.
     */
    public static JPanel newLineBoxLayoutPanel() {
        final JPanel result = new JPanel(null, false);

        result.setLayout(new BoxLayout(result, BoxLayout.LINE_AXIS));

        return result;
    }

    /**
     * A new JPanel with PAGE_AXIS BoxLayout.
     * @return A new JPanel.
     */
    public static JPanel newPageBoxLayoutPanel() {
        final JPanel result = new JPanel(null, false);

        result.setLayout(new BoxLayout(result, BoxLayout.PAGE_AXIS));

        return result;
    }

    /**
     * A new JPanel with LINE_AXIS BoxLayout and a titled (translated) border.
     * @param key The key of the title.
     * @return A new JPanel.
     */
    public static JPanel newTitledLineBoxLayoutPanel(final String key) {
        final JPanel result = new JPanel(null, false);

        result.setLayout(new BoxLayout(result, BoxLayout.LINE_AXIS));

        result.setBorder(new JaxoTitledBorder(JaxoLanguage.translate(key)));

        return result;
    }

    /**
     * A new JPanel with PAGE_AXIS BoxLayout and a titled (translated) border.
     * @param key The key of the title.
     * @return A new JPanel.
     */
    public static JPanel newTitledPageBoxLayoutPanel(final String key) {
        final JPanel result = new JPanel(null, false);

        result.setLayout(new BoxLayout(result, BoxLayout.PAGE_AXIS));

        result.setBorder(new JaxoTitledBorder(JaxoLanguage.translate(key)));

        return result;
    }

    /**
     * A new JPanel with FlowLayout and a titled (translated) border.
     * @param key The key of the title.
     * @return A new JPanel.
     */
    public static JPanel newTitledFlowLayoutPanel(final String key) {
        final JPanel result = new JPanel(false);

        result.setBorder(new JaxoTitledBorder(JaxoLanguage.translate(key)));

        return result;
    }

    /**
     * A new JPanel with BorderLayout and a titled (translated) border.
     * @param key The key of the title.
     * @return A new JPanel.
     */
    public static JPanel newTitledBorderLayoutPanel(final String key) {
        final JPanel result = new JPanel(new BorderLayout(), false);

        result.setBorder(new JaxoTitledBorder(JaxoLanguage.translate(key)));

        return result;
    }

    /**
     * A new JPanel with the given layout and a titled (translated) border.
     * @param key The key of the title.
     * @param l The LayoutManager to use.
     * @return A new JPanel.
     */
    public static JPanel newTitledLayoutPanel(final String key, final LayoutManager l) {
        final JPanel result = new JPanel(l, false);

        result.setBorder(new JaxoTitledBorder(JaxoLanguage.translate(key)));

        return result;
    }
}
