/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.openide;

import org.openide.util.Utilities;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import javax.swing.*;
import org.openide.util.ImageUtilities;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;


/** Permits dialogs to be displayed.
 * @author Jesse Glick
 * @since 3.14
 */
public abstract class DialogDisplayer {
    /** Subclass constructor. */
    protected DialogDisplayer() {
    }

    /** Get the default dialog displayer.
     * @return the default instance from lookup
     */
    public static DialogDisplayer getDefault() {
        DialogDisplayer dd = Lookup.getDefault ().lookup (DialogDisplayer.class);

        if (dd == null) {
            dd = new Trivial();
        }

        return dd;
    }

    /** Notify the user of something in a message box, possibly with feedback.
     * <p>To support both GUI and non-GUI use, this method may be called
     * from any thread (providing you are not holding any locks), and
     * will block the caller's thread. In GUI mode, it will be run in the AWT
     * event thread automatically. If you wish to hold locks, or do not
     * need the result object immediately or at all, please make this call
     * asynchronously (e.g. from the request processor).
     * @param descriptor description of the notification
     * @return the option that caused the message box to be closed
     */
    public abstract Object notify(NotifyDescriptor descriptor);

    /** Notify the user of something in a message box, possibly with feedback,
     * this method method may be called
     * from any thread. The thread will return immediately and
     * the dialog will be shown <q>later</q>, usually when AWT thread
     * is empty and can handle the request.
     * 
     * <p class="non-normative">
     * Implementation note: Since version 7.3, implementation improved to work
     * also before main window is opened. For example: When method is called
     * from ModuleInstall.restored, then modal dialog is opened and blocks main
     * window until dialog is closed. Typical use case is login dialog.
     * </p>
     *
     * @param descriptor description of the notification
     * @since 7.0
     */
    public void notifyLater(final NotifyDescriptor descriptor) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                DialogDisplayer.this.notify(descriptor);
            }
        });
    }

    /** Get a new standard dialog.
     * The dialog is designed and created as specified in the parameter.
     * Anyone who wants a dialog with standard buttons and
     * standard behavior should use this method.
     * <p><strong>Do not cache</strong> the resulting dialog if it
     * is modal and try to reuse it! Always create a new dialog
     * using this method if you need to show a dialog again.
     * Otherwise previously closed windows can reappear.
     * @param descriptor general description of the dialog
     * @return the new dialog
     */
    public abstract Dialog createDialog(DialogDescriptor descriptor);
    
    /**
     * Same as #createDialog(org.openide.DialogDescriptor) except that it's possible
     * to specify dialog's parent Frame window. When a document window is floated
     * and has focus then new dialog window will use it as a parent window by default.
     * That means non-modal dialogs will close when that document window is closed.
     * To avoid such situation pass WindowManager.getDefault().getMainWindow() as
     * dialog parent window.
     * @param descriptor general description of the dialog
     * @param parent Dialgo parent frame.
     * @return New dialog
     * @since 7.38
     */
    public Dialog createDialog(DialogDescriptor descriptor, Frame parent) {
        return createDialog(descriptor);
    }

    /**
     * Minimal implementation suited for standalone usage.
     * @see "#30031"
     */
    private static final class Trivial extends DialogDisplayer {
        public Object notify(NotifyDescriptor nd) {
            JDialog dialog = new StandardDialog(nd.getTitle(), true, nd, null, null);
            dialog.setVisible(true);

            return (nd.getValue() != null) ? nd.getValue() : NotifyDescriptor.CLOSED_OPTION;
        }

        public Dialog createDialog(final DialogDescriptor dd) {
            final StandardDialog dialog = new StandardDialog(
                    dd.getTitle(), dd.isModal(), dd, dd.getClosingOptions(), dd.getButtonListener()
                );
            dd.addPropertyChangeListener(new DialogUpdater(dialog, dd));

            return dialog;
        }

        /**
         * Given a message object, create a displayable component from it.
         */
        private static Component message2Component(Object message) {
            if (message instanceof Component) {
                return (Component) message;
            } else if (message instanceof Object[]) {
                Object[] sub = (Object[]) message;
                JPanel panel = new JPanel();
                panel.setLayout(new FlowLayout());

                for (int i = 0; i < sub.length; i++) {
                    panel.add(message2Component(sub[i]));
                }

                return panel;
            } else if (message instanceof Icon) {
                return new JLabel((Icon) message);
            } else {
                // bugfix #35742, used JTextArea to correctly word-wrapping
                String text = message.toString();
                JTextArea area = new JTextArea(text);
                Color c = UIManager.getColor("Label.background"); // NOI18N

                if (c != null) {
                    area.setBackground(c);
                }

                area.setLineWrap(true);
                area.setWrapStyleWord(true);
                area.setEditable(false);
                area.setTabSize(4); // looks better for module sys messages than 8

                area.setColumns(40);

                if (text.indexOf('\n') != -1) {
                    // Complex multiline message.
                    return new JScrollPane(area);
                } else {
                    // Simple message.
                    return area;
                }
            }
        }

        private static Component option2Button(Object option, NotifyDescriptor nd, ActionListener l, JRootPane rp) {
            if (option instanceof AbstractButton) {
                AbstractButton b = (AbstractButton) option;
                removeOldListeners(b);
                b.addActionListener(l);

                return b;
            } else if (option instanceof Component) {
                return (Component) option;
            } else if (option instanceof Icon) {
                return new JLabel((Icon) option);
            } else {
                String text;
                boolean defcap;

                if (option == NotifyDescriptor.OK_OPTION) {
                    text = NbBundle.getMessage(DialogDisplayer.class, "CTL_OK");
                    defcap = true;
                } else if (option == NotifyDescriptor.CANCEL_OPTION) {
                    text = NbBundle.getMessage(DialogDisplayer.class, "CTL_CANCEL");
                    defcap = false;
                } else if (option == NotifyDescriptor.YES_OPTION) {
                    text = NbBundle.getMessage(DialogDisplayer.class, "CTL_YES");
                    defcap = true;
                } else if (option == NotifyDescriptor.NO_OPTION) {
                    text = NbBundle.getMessage(DialogDisplayer.class, "CTL_NO");
                    defcap = false;
                } else if (option == NotifyDescriptor.CLOSED_OPTION) {
                    throw new IllegalArgumentException();
                } else {
                    text = option.toString();
                    defcap = false;
                }

                JButton b = new JButton(text);

                if (defcap && (rp.getDefaultButton() == null)) {
                    rp.setDefaultButton(b);
                }

                // added a simple accessible name to buttons
                b.getAccessibleContext().setAccessibleName(text);
                b.addActionListener(l);

                return b;
            }
        }

        private static void removeOldListeners( AbstractButton button ) {
            ArrayList<ActionListener> toRem = new ArrayList<ActionListener>();
            for( ActionListener al : button.getActionListeners() ) {
                if( al instanceof StandardDialog.ButtonListener ) {
                    toRem.add( al );
                }
            }
            for( ActionListener al : toRem ) {
                button.removeActionListener( al );
            }
                            }

        private static final class StandardDialog extends JDialog {
            final NotifyDescriptor nd;
            private Component messageComponent;
            private final JPanel buttonPanel;
            private final Object[] closingOptions;
            private final ActionListener buttonListener;
            private boolean haveFinalValue = false;
            private Color nbErrorForeground;
            private Color nbWarningForeground;
            private Color nbInfoForeground;
            private JLabel notificationLine;
            private static final int MSG_TYPE_ERROR = 1;
            private static final int MSG_TYPE_WARNING = 2;
            private static final int MSG_TYPE_INFO = 3;


            public StandardDialog(
                String title, boolean modal, NotifyDescriptor nd, Object[] closingOptions, ActionListener buttonListener
            ) {
                super((Frame) null, title, modal);
                this.nd = nd;
                this.closingOptions = closingOptions;
                this.buttonListener = buttonListener;
                getContentPane().setLayout(new BorderLayout());
                setDefaultCloseOperation(nd.isNoDefaultClose()
                        ? WindowConstants.DO_NOTHING_ON_CLOSE
                        : WindowConstants.DISPOSE_ON_CLOSE);
                updateMessage();
                buttonPanel = new JPanel();
                buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
                updateOptions();
                getContentPane().add(buttonPanel, BorderLayout.SOUTH, 1);

                KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
                Object actionKey = "cancel"; // NOI18N
                getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(k, actionKey);

                Action cancelAction = new AbstractAction() {
                        @Override
                        public void actionPerformed(ActionEvent ev) {
                            if( !StandardDialog.this.nd.isNoDefaultClose() )
                                cancel();
                        }
                    };

                getRootPane().getActionMap().put(actionKey, cancelAction);
                addWindowListener(
                    new WindowAdapter() {
                        public void windowClosing(WindowEvent ev) {
                            if (!haveFinalValue) {
                                StandardDialog.this.nd.setValue(NotifyDescriptor.CLOSED_OPTION);
                            }
                        }
                    }
                );
                pack();

                Rectangle r = Utilities.getUsableScreenBounds();
                int maxW = (r.width * 9) / 10;
                int maxH = (r.height * 9) / 10;
                Dimension d = getPreferredSize();
                d.width = Math.min(d.width, maxW);
                d.height = Math.min(d.height, maxH);
                setBounds(Utilities.findCenterBounds(d));
            }

            private void cancel() {
                nd.setValue(NotifyDescriptor.CANCEL_OPTION);
                haveFinalValue = true;
                dispose();
            }

            public void updateMessage() {
                if (messageComponent != null) {
                    getContentPane().remove(messageComponent);
                }

                //System.err.println("updateMessage: " + nd.getMessage());
                messageComponent = message2Component(nd.getMessage());
                if (! (nd instanceof WizardDescriptor) && nd.getNotificationLineSupport () != null) {
                    JComponent toAdd = new JPanel (new BorderLayout ());
                    toAdd.add (messageComponent, BorderLayout.CENTER);

                    nbErrorForeground = UIManager.getColor("nb.errorForeground"); //NOI18N
                    if (nbErrorForeground == null) {
                        //nbErrorForeground = new Color(89, 79, 191); // RGB suggested by Bruce in #28466
                        nbErrorForeground = new Color(255, 0, 0); // RGB suggested by jdinga in #65358
                    }

                    nbWarningForeground = UIManager.getColor("nb.warningForeground"); //NOI18N
                    if (nbWarningForeground == null) {
                        nbWarningForeground = new Color(51, 51, 51); // Label.foreground
                    }

                    nbInfoForeground = UIManager.getColor("nb.warningForeground"); //NOI18N
                    if (nbInfoForeground == null) {
                        nbInfoForeground = UIManager.getColor("Label.foreground"); //NOI18N
                    }

                    notificationLine = new FixedHeightLabel ();
                    NotificationLineSupport nls = nd.getNotificationLineSupport ();
                    if (nls.getInformationMessage () != null) {
                        updateNotificationLine (this, MSG_TYPE_INFO, nls.getInformationMessage ());
                    } else if (nls.getWarningMessage () != null) {
                        updateNotificationLine (this, MSG_TYPE_WARNING, nls.getWarningMessage ());
                    } else if (nls.getErrorMessage () != null) {
                        updateNotificationLine (this, MSG_TYPE_ERROR, nls.getErrorMessage ());
                    }
                    toAdd.add (notificationLine, BorderLayout.SOUTH);
                    messageComponent = toAdd;
                }
                getContentPane().add(messageComponent, BorderLayout.CENTER);
            }

            public void updateOptions() {
                Set<Object> addedOptions = new HashSet<Object>(5);
                Object[] options = nd.getOptions();

                if (options == null) {
                    switch (nd.getOptionType()) {
                    case NotifyDescriptor.DEFAULT_OPTION:
                    case NotifyDescriptor.OK_CANCEL_OPTION:
                        if (!Utilities.isMac()) {
                            // Windows UI Guidelines
                            options = new Object[] { NotifyDescriptor.OK_OPTION, NotifyDescriptor.CANCEL_OPTION, };
                        } else {
                            // see http://netbeans.org/bugzilla/show_bug.cgi?id=202784 - according to
                            // Apple HIG guidelines 'Cancel' should be on the left
                            // http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AppleHIGuidelines/Windows/Windows.html#//apple_ref/doc/uid/20000961-TP9
                            options = new Object[] { NotifyDescriptor.CANCEL_OPTION, NotifyDescriptor.OK_OPTION, };
                        }
                        break;

                    case NotifyDescriptor.YES_NO_OPTION:
                        if (!Utilities.isMac()) {
                            // Windows UI Guidelines
                            options = new Object[] { NotifyDescriptor.YES_OPTION, NotifyDescriptor.NO_OPTION, };
                        } else {
                            // see http://netbeans.org/bugzilla/show_bug.cgi?id=202784 - according to
                            // Apple HIG guidelines 'Cancel' should be on the left
                            // http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AppleHIGuidelines/Windows/Windows.html#//apple_ref/doc/uid/20000961-TP9
                            options = new Object[] { NotifyDescriptor.NO_OPTION, NotifyDescriptor.YES_OPTION, };
                        }

                        break;

                    case NotifyDescriptor.YES_NO_CANCEL_OPTION:
                        if (!Utilities.isMac()) {
                            // Windows UI Guidelines
                            options = new Object[] {
                                NotifyDescriptor.YES_OPTION, NotifyDescriptor.NO_OPTION, NotifyDescriptor.CANCEL_OPTION,
                            };
                        } else {
                            // see http://netbeans.org/bugzilla/show_bug.cgi?id=202784 - according to
                            // Apple HIG guidelines 'Cancel' should be on the left
                            // http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AppleHIGuidelines/Windows/Windows.html#//apple_ref/doc/uid/20000961-TP9
                            options = new Object[] {
                                NotifyDescriptor.NO_OPTION, NotifyDescriptor.CANCEL_OPTION, NotifyDescriptor.YES_OPTION,
                            };
                        }

                        break;

                    default:
                        throw new IllegalArgumentException();
                    }
                }

                //System.err.println("prep: " + Arrays.asList(options) + " " + Arrays.asList(closingOptions) + " " + buttonListener);
                buttonPanel.removeAll();

                JRootPane rp = getRootPane();

                for (int i = 0; i < options.length; i++) {
                    addedOptions.add(options[i]);
                    buttonPanel.add(option2Button(options[i], nd, makeListener(options[i]), rp));
                }

                options = nd.getAdditionalOptions();

                if (options != null) {
                    for (int i = 0; i < options.length; i++) {
                        addedOptions.add(options[i]);
                        buttonPanel.add(option2Button(options[i], nd, makeListener(options[i]), rp));
                    }
                }

                if (closingOptions != null) {
                    for (int i = 0; i < closingOptions.length; i++) {
                        if (addedOptions.add(closingOptions[i])) {
                            ActionListener l = makeListener(closingOptions[i]);
                            attachActionListener(closingOptions[i], l);
                        }
                    }
                }
            }

            private void attachActionListener(Object comp, ActionListener l) {
                // on JButtons attach simply by method call
                if (comp instanceof JButton) {
                    JButton b = (JButton) comp;
                    b.addActionListener(l);

                    return;
                } else {
                    // we will have to use dynamic method invocation to add the action listener
                    // to generic component (and we succeed only if it has the addActionListener method)
                    java.lang.reflect.Method m;

                    try {
                        m = comp.getClass().getMethod("addActionListener", new Class[] { ActionListener.class }); // NOI18N

                        try {
                            m.setAccessible(true);
                        } catch (SecurityException se) {
                            m = null; // no jo, we cannot make accessible
                        }
                    } catch (NoSuchMethodException e) {
                        m = null; // no jo, we cannot attach ActionListener to this Component
                    } catch (SecurityException e2) {
                        m = null; // no jo, we cannot attach ActionListener to this Component
                    }

                    if (m != null) {
                        try {
                            m.invoke(comp, new Object[] { l });
                        } catch (Exception e) {
                            // not succeeded, so give up
                        }
                    }
                }
            }

            private ActionListener makeListener(final Object option) {
                return new ButtonListener( option );
            }
            
            private class ButtonListener implements ActionListener {

                private final Object option;
                
                public ButtonListener( Object option ) {
                    this.option = option;
                }
                
                @Override
                public void actionPerformed( ActionEvent e ) {
                    nd.setValue(option);

                    if (buttonListener != null) {
                        // #34485: some listeners expect that the action source is the option, not the button
                        ActionEvent e2 = new ActionEvent(
                                option, e.getID(), e.getActionCommand(), e.getWhen(), e.getModifiers()
                            );
                        buttonListener.actionPerformed(e2);
                    }

                    if ((closingOptions == null) || Arrays.asList(closingOptions).contains(option)) {
                        haveFinalValue = true;
                        setVisible(false);
                    }
                }
            }     
        }

        private static class DialogUpdater implements PropertyChangeListener {

            private StandardDialog dialog;

            private DialogDescriptor dd;

            public DialogUpdater(StandardDialog dialog, DialogDescriptor dd) {
                super();
                this.dialog = dialog;
                this.dd = dd;
            }

            public void propertyChange(final PropertyChangeEvent ev) {
                if( !SwingUtilities.isEventDispatchThread() ) {
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            propertyChange(ev);
                        }
                    });
                    return;
                }
                String pname = ev.getPropertyName();
                if (NotifyDescriptor.PROP_TITLE.equals(pname)) {
                    dialog.setTitle(dd.getTitle());
                } else if (NotifyDescriptor.PROP_NO_DEFAULT_CLOSE.equals(pname)) {
                    dialog.setDefaultCloseOperation(dd.isNoDefaultClose() ? JDialog.DO_NOTHING_ON_CLOSE : JDialog.DISPOSE_ON_CLOSE);
                } else
                    if (NotifyDescriptor.PROP_MESSAGE.equals(pname)) {
                        dialog.updateMessage();
                        dialog.validate();
                        dialog.repaint();
                    } else
                        if (NotifyDescriptor.PROP_OPTIONS.equals(pname) || NotifyDescriptor.PROP_OPTION_TYPE.equals(pname)) {
                            dialog.updateOptions();
                            dialog.validate();
                            dialog.repaint();
                    } else if (NotifyDescriptor.PROP_INFO_NOTIFICATION.equals (ev.getPropertyName ())) {
                        updateNotificationLine (dialog, StandardDialog.MSG_TYPE_INFO, ev.getNewValue ());
                    } else if (NotifyDescriptor.PROP_WARNING_NOTIFICATION.equals (ev.getPropertyName ())) {
                        updateNotificationLine (dialog, StandardDialog.MSG_TYPE_WARNING, ev.getNewValue ());
                    } else if (NotifyDescriptor.PROP_ERROR_NOTIFICATION.equals (ev.getPropertyName ())) {
                        updateNotificationLine (dialog, StandardDialog.MSG_TYPE_ERROR, ev.getNewValue ());
                    }
            }
        }

        private static void updateNotificationLine (StandardDialog dialog, int msgType, Object o) {
            String msg = o == null ? null : o.toString ();
            if (msg != null && msg.trim().length() > 0) {
                switch (msgType) {
                    case StandardDialog.MSG_TYPE_ERROR:
                        prepareMessage(dialog.notificationLine, ImageUtilities.loadImageIcon("org/netbeans/modules/dialogs/error.gif", false), //NOI18N
                            dialog.nbErrorForeground);
                        break;
                    case StandardDialog.MSG_TYPE_WARNING:
                        prepareMessage(dialog.notificationLine, ImageUtilities.loadImageIcon("org/netbeans/modules/dialogs/warning.gif", false), //NOI18N
                            dialog.nbWarningForeground);
                        break;
                    case StandardDialog.MSG_TYPE_INFO:
                        prepareMessage(dialog.notificationLine, ImageUtilities.loadImageIcon("org/netbeans/modules/dialogs/info.png", false), //NOI18N
                            dialog.nbInfoForeground);
                        break;
                    default:
                }
                dialog.notificationLine.setToolTipText (msg);
            } else {
                prepareMessage(dialog.notificationLine, null, null);
                dialog.notificationLine.setToolTipText (null);
            }
            dialog.notificationLine.setText(msg);
        }

        private static void prepareMessage(JLabel label, ImageIcon icon, Color fgColor) {
            label.setIcon(icon);
            label.setForeground(fgColor);
        }

        private static final class FixedHeightLabel extends JLabel {

            private static final int ESTIMATED_HEIGHT = 16;

            public FixedHeightLabel () {
                super ();
            }

            @Override
            public Dimension getPreferredSize() {
                Dimension preferredSize = super.getPreferredSize();
                assert ESTIMATED_HEIGHT == ImageUtilities.loadImage ("org/netbeans/modules/dialogs/warning.gif").getHeight (null) : "Use only 16px icon."; //NOI18N
                preferredSize.height = Math.max (ESTIMATED_HEIGHT, preferredSize.height);
                return preferredSize;
            }
        }

    }
}
