/*
 * 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.sessionconsole;

import javax.swing.*;

import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.tools.beans.*;

/**
 * Generic login dialog.
 */
public class LoginEditorDialog extends JDialog {
    private boolean wasCanceled = true;
    private JButton ivjCancelButton = null;
    private LoginEditorPanel ivjLoginEditorPanel1 = null;
    private JPanel ivjMainPanel = null;
    private JButton ivjOKButton = null;
    IvjEventHandler ivjEventHandler = new IvjEventHandler();

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

    public LoginEditorDialog(java.awt.Frame owner) {
        super(owner);
    }

    public LoginEditorDialog(java.awt.Frame owner, String title) {
        super(owner, title);
    }

    public LoginEditorDialog(java.awt.Frame owner, String title,
                             boolean modal) {
        super(owner, title, modal);
    }

    public LoginEditorDialog(java.awt.Frame owner, boolean modal) {
        super(owner, modal);
    }

    /**
     * Center a component in the middle of the screen.
     */
    public static void centerComponent(java.awt.Component component) {
        java.awt.Dimension screenSize =
            java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        java.awt.Dimension size = component.getSize();

        screenSize.height = screenSize.height / 2;
        screenSize.width = screenSize.width / 2;

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

        component.setLocation(screenSize.width - size.width,
                              screenSize.height - size.height);
    }

    /**
     * connEtoC1:  (CancelButton.action.actionPerformed(java.awt.event.ActionEvent) --{@literal >} LoginEditorDialog.markCanceled()V)
     * @param arg1 java.awt.event.ActionEvent
     */
    private void connEtoC1(java.awt.event.ActionEvent arg1) {
        try {
            this.markCanceled();
        } catch (java.lang.Throwable ivjExc) {
            handleException(ivjExc);
        }
    }

    /**
     * connEtoC2:  (OKButton.action. --{@literal >} LoginEditorDialog.loginOK()V)
     */
    private void connEtoC2() {
        try {
            // user code begin {1}
            // user code end
            this.loginOK();
            // user code begin {2}
            // user code end
        } catch (java.lang.Throwable ivjExc) {
            // user code begin {3}
            // user code end
            handleException(ivjExc);
        }
    }

    /**
     * Return the CancelButton property value.
     * @return javax.swing.JButton
     */
    private javax.swing.JButton getCancelButton() {
        if (ivjCancelButton == null) {
            try {
                ivjCancelButton = new javax.swing.JButton();
                ivjCancelButton.setName("CancelButton");
                ivjCancelButton.setText("Cancel");
                ivjCancelButton.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 ivjCancelButton;
    }

    public DatabaseLogin getLogin() {
        return getLoginEditorPanel1().getLogin();
    }

    /**
     * Return the LoginEditorPanel1 property value.
     * @return LoginEditorPanel
     */
    private LoginEditorPanel getLoginEditorPanel1() {
        if (ivjLoginEditorPanel1 == null) {
            try {
                ivjLoginEditorPanel1 =
                        new org.eclipse.persistence.tools.sessionconsole.LoginEditorPanel();
                ivjLoginEditorPanel1.setName("LoginEditorPanel1");
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjLoginEditorPanel1;
    }

    /**
     * Return the MainPanel property value.
     * @return javax.swing.JPanel
     */
    private javax.swing.JPanel getMainPanel() {
        if (ivjMainPanel == null) {
            try {
                ivjMainPanel = new javax.swing.JPanel();
                ivjMainPanel.setName("MainPanel");
                ivjMainPanel.setLayout(new java.awt.GridBagLayout());
                ivjMainPanel.setBackground(java.awt.SystemColor.control);

                java.awt.GridBagConstraints constraintsLoginEditorPanel1 =
                    new java.awt.GridBagConstraints();
                constraintsLoginEditorPanel1.gridx = 0;
                constraintsLoginEditorPanel1.gridy = 0;
                constraintsLoginEditorPanel1.fill =
                        java.awt.GridBagConstraints.BOTH;
                constraintsLoginEditorPanel1.weightx = 1.0;
                constraintsLoginEditorPanel1.weighty = 1.0;
                getMainPanel().add(getLoginEditorPanel1(),
                                   constraintsLoginEditorPanel1);

                java.awt.GridBagConstraints constraintsOKButton =
                    new java.awt.GridBagConstraints();
                constraintsOKButton.gridx = 0;
                constraintsOKButton.gridy = 0;
                constraintsOKButton.anchor = java.awt.GridBagConstraints.WEST;
                constraintsOKButton.ipadx = 20;
                constraintsOKButton.insets = new java.awt.Insets(0, 2, 2, 0);
                getMainPanel().add(getOKButton(), constraintsOKButton);

                java.awt.GridBagConstraints constraintsCancelButton =
                    new java.awt.GridBagConstraints();
                constraintsCancelButton.gridx = 0;
                constraintsCancelButton.gridy = 0;
                constraintsCancelButton.gridheight = 2;
                constraintsCancelButton.fill =
                        java.awt.GridBagConstraints.VERTICAL;
                constraintsCancelButton.anchor =
                        java.awt.GridBagConstraints.EAST;
                constraintsCancelButton.insets =
                        new java.awt.Insets(0, 0, 2, 2);
                getMainPanel().add(getCancelButton(), constraintsCancelButton);
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjMainPanel;
    }

    /**
     * Return the OKButton property value.
     * @return javax.swing.JButton
     */
    private 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) {
        MessageDialog.displayException(exception, this);
    }

    /**
     * Initializes connections
     */
    private void initConnections() throws java.lang.Exception {
        // user code begin {1}
        // user code end
        getCancelButton().addActionListener(ivjEventHandler);
        getOKButton().addActionListener(ivjEventHandler);
    }

    /**
     * Initialize the class.
     */
    private void initialize() {
        try {
            // user code begin {1}
            // user code end
            setName("LoginEditorDialog");
            setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
            setSize(609, 387);
            setModal(false);
            setTitle("TopLink Login Editor");
            setContentPane(getMainPanel());
            initConnections();
        } catch (java.lang.Throwable ivjExc) {
            handleException(ivjExc);
        }

        // user code begin {2}
        centerComponent(this);
        // user code end
    }

    public static DatabaseLogin launch(java.awt.Frame parent,
                                       DatabaseLogin login) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            LoginEditorDialog aLoginEditorDialog;
            aLoginEditorDialog = new LoginEditorDialog();
            aLoginEditorDialog.getLoginEditorPanel1().setLogin(login);
            aLoginEditorDialog.setModal(true);
            aLoginEditorDialog.setVisible(true);

            if (aLoginEditorDialog.wasCanceled()) {
                return null;
            } else {
                return aLoginEditorDialog.getLogin();
            }
        } catch (Throwable exception) {
            System.err.println("Exception occurred in main() of javax.swing.JDialog");
            exception.printStackTrace(System.out);
        }
        return null;
    }

    public void loginOK() {
        setWasCanceled(false);
        dispose();
    }

    public void markCanceled() {
        setWasCanceled(true);
        dispose();
    }

    protected void setWasCanceled(boolean wasCanceled) {
        this.wasCanceled = wasCanceled;
    }

    public boolean wasCanceled() {
        return wasCanceled;
    }

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