/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.tools.beans;

import javax.swing.*;

/**
 * Used to display error messages.
 */
public class MessageDialog extends JDialog {
    private JPanel ivjJDialogContentPane = null;
    private JScrollPane ivjMessageScrollPane = null;
    private JTextPane ivjMessageTextPane = null;
    private JButton ivjOKButton = null;
    IvjEventHandler ivjEventHandler = new IvjEventHandler();

    public MessageDialog() {
        super();
        initialize();
    }

    /**
     * MessageDialog constructor comment.
     * @param owner java.awt.Frame
     */
    public MessageDialog(java.awt.Frame owner) {
        super(owner);
    }

    /**
     * MessageDialog constructor comment.
     * @param owner java.awt.Frame
     * @param title java.lang.String
     */
    public MessageDialog(java.awt.Frame owner, String title) {
        super(owner, title);
    }

    /**
     * MessageDialog constructor comment.
     * @param owner java.awt.Frame
     * @param title java.lang.String
     * @param modal boolean
     */
    public MessageDialog(java.awt.Frame owner, String title, boolean modal) {
        super(owner, title, modal);
    }

    /**
     * MessageDialog constructor comment.
     * @param owner java.awt.Frame
     * @param modal boolean
     */
    public MessageDialog(java.awt.Frame owner, boolean modal) {
        super(owner, modal);
    }

    /**
     * Center a component with relation to another component.
     */
    public static void centerComponent(java.awt.Component component,
                                       java.awt.Component parent) {
        while (parent.getParent() != null) {
            parent = parent.getParent();
        }
        java.awt.Dimension parentSize = parent.getSize();
        java.awt.Dimension size = component.getSize();

        int xOffset = parent.getLocation().x;
        int yOffset = parent.getLocation().y;

        parentSize.height = parentSize.height / 2;
        parentSize.width = parentSize.width / 2;

        size.height = size.height / 2;
        size.width = size.width / 2;

        component.setLocation(parentSize.width - size.width + xOffset,
                              parentSize.height - size.height + yOffset);
    }

    /**
     * connEtoM1:  (OKButton.action.actionPerformed(java.awt.event.ActionEvent) --{@literal >} MessageDialog.dispose()V)
     * @param arg1 java.awt.event.ActionEvent
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    void connEtoM1(java.awt.event.ActionEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.dispose();
            // user code begin {2}
            // user code end
        } catch (java.lang.Throwable ivjExc) {
            // user code begin {3}
            // user code end
            handleException(ivjExc);
        }
    }

    /**
     * main entrypoint - starts the part when it is run as an application
     * @param exception java.lang.Throwable
     */
    public static void displayException(Throwable exception) {
        displayMessage(exception.toString());
    }

    /**
     * main entrypoint - starts the part when it is run as an application
     * @param exception java.lang.Throwable
     * @param parent java.awt.Container
     */
    public static void displayException(Throwable exception,
                                        java.awt.Container parent) {
        displayMessage(exception.toString(), parent);
    }

    /**
     * main entrypoint - starts the part when it is run as an application
     * @param message java.lang.String
     */
    public static void displayMessage(String message) {
        try {
            MessageDialog aMessageDialog;
            aMessageDialog = new MessageDialog();
            aMessageDialog.setVisible(true);
            aMessageDialog.setMessage(message);
        } catch (Throwable exception) {
            System.err.println("Exception occurred in main() of javax.swing.JDialog");
            exception.printStackTrace(System.out);
        }
    }

    /**
     * main entrypoint - starts the part when it is run as an application
     * @param message java.lang.String
     * @param parent java.awt.Container
     */
    public static void displayMessage(String message,
                                      java.awt.Container parent) {
        try {
            MessageDialog aMessageDialog;
            aMessageDialog = new MessageDialog();
            centerComponent(aMessageDialog, parent);
            aMessageDialog.setVisible(true);
            aMessageDialog.setMessage(message);
        } catch (Throwable exception) {
            System.err.println("Exception occurred in main() of javax.swing.JDialog");
            exception.printStackTrace(System.out);
        }
    }

    /**
     * Return the JDialogContentPane property value.
     * @return javax.swing.JPanel
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JPanel getJDialogContentPane() {
        if (ivjJDialogContentPane == null) {
            try {
                ivjJDialogContentPane = new javax.swing.JPanel();
                ivjJDialogContentPane.setName("JDialogContentPane");
                ivjJDialogContentPane.setLayout(new java.awt.GridBagLayout());
                ivjJDialogContentPane.setBackground(java.awt.SystemColor.control);

                java.awt.GridBagConstraints constraintsOKButton =
                    new java.awt.GridBagConstraints();
                constraintsOKButton.gridx = 0;
                constraintsOKButton.gridy = 1;
                constraintsOKButton.weightx = 1.0;
                constraintsOKButton.ipadx = 20;
                constraintsOKButton.insets = new java.awt.Insets(0, 0, 4, 0);
                getJDialogContentPane().add(getOKButton(),
                                            constraintsOKButton);

                java.awt.GridBagConstraints constraintsMessageScrollPane =
                    new java.awt.GridBagConstraints();
                constraintsMessageScrollPane.gridx = 0;
                constraintsMessageScrollPane.gridy = 0;
                constraintsMessageScrollPane.fill =
                        java.awt.GridBagConstraints.BOTH;
                constraintsMessageScrollPane.weightx = 1.0;
                constraintsMessageScrollPane.weighty = 1.0;
                constraintsMessageScrollPane.insets =
                        new java.awt.Insets(4, 4, 4, 4);
                getJDialogContentPane().add(getMessageScrollPane(),
                                            constraintsMessageScrollPane);
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjJDialogContentPane;
    }

    public String getMessage() {
        return getMessageTextPane().getText();
    }

    /**
     * Return the MessageScrollPane property value.
     * @return javax.swing.JScrollPane
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JScrollPane getMessageScrollPane() {
        if (ivjMessageScrollPane == null) {
            try {
                ivjMessageScrollPane = new javax.swing.JScrollPane();
                ivjMessageScrollPane.setName("MessageScrollPane");
                getMessageScrollPane().setViewportView(getMessageTextPane());
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjMessageScrollPane;
    }

    /**
     * Return the MessageTextPane property value.
     * @return javax.swing.JTextPane
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JTextPane getMessageTextPane() {
        if (ivjMessageTextPane == null) {
            try {
                ivjMessageTextPane = new javax.swing.JTextPane();
                ivjMessageTextPane.setName("MessageTextPane");
                ivjMessageTextPane.setBounds(0, 0, 10, 10);
                ivjMessageTextPane.setEnabled(false);
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjMessageTextPane;
    }

    /**
     * Return the OKButton property value.
     * @return javax.swing.JButton
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JButton getOKButton() {
        if (ivjOKButton == null) {
            try {
                ivjOKButton = new javax.swing.JButton();
                ivjOKButton.setName("OKButton");
                ivjOKButton.setText("OK");
                ivjOKButton.setBackground(java.awt.SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjOKButton;
    }

    /**
     * Called whenever the part throws an exception.
     * @param exception java.lang.Throwable
     */
    private void handleException(Throwable exception) {
        /* Uncomment the following lines to print uncaught exceptions to stdout */
        exception.printStackTrace();
    }

    /**
     * Initializes connections
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    void initConnections() throws java.lang.Exception {
        // user code begin {1}
        // user code end
        getOKButton().addActionListener(ivjEventHandler);
    }

    /**
     * Initialize the class.
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    void initialize() {
        try {
            // user code begin {1}
            // user code end
            setName("MessageDialog");
            setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
            setSize(500, 300);
            setTitle("Message");
            setContentPane(getJDialogContentPane());
            initConnections();
        } catch (java.lang.Throwable ivjExc) {
            handleException(ivjExc);
        }

        // user code begin {2}
        // user code end
    }

    public void setMessage(String message) {
        getMessageTextPane().setText(message);
    }

    class IvjEventHandler implements java.awt.event.ActionListener {
        @Override
        public void actionPerformed(java.awt.event.ActionEvent e) {
            if (e.getSource() == MessageDialog.this.getOKButton()) {
                connEtoM1(e);
            }
        }
    }
}
