/*
 * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package sun.swing;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.text.MessageFormat;
import java.util.concurrent.atomic.AtomicBoolean;
import java.lang.reflect.InvocationTargetException;

/**
 * The {@code PrintingStatus} provides a dialog that displays progress
 * of the printing job and provides a way to abort it
 * <p>
 * Methods of these class are thread safe, although most Swing methods
 * are not. Please see
 * <A HREF="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency
 * in Swing</A> for more information.
 *
 * @author Alexander Potochkin
 * @since 1.6
 */

public class PrintingStatus {

    private final PrinterJob job;
    private final Component parent;
    private JDialog abortDialog;

    private JButton abortButton;
    private JLabel statusLabel;
    private MessageFormat statusFormat;
    private final AtomicBoolean isAborted = new AtomicBoolean(false);

    // the action that will abort printing
    private final Action abortAction = new AbstractAction() {
        public void actionPerformed(ActionEvent ae) {
            if (!isAborted.get()) {
                isAborted.set(true);

                // update the status abortDialog to indicate aborting
                abortButton.setEnabled(false);
                abortDialog.setTitle(
                    UIManager.getString("PrintingDialog.titleAbortingText"));
                statusLabel.setText(
                    UIManager.getString("PrintingDialog.contentAbortingText"));

                // cancel the PrinterJob
                job.cancel();
            }
        }
    };

    private final WindowAdapter closeListener = new WindowAdapter() {
        public void windowClosing(WindowEvent we) {
            abortAction.actionPerformed(null);
        }
    };

    /**
     * Creates PrintingStatus instance
     *
     * @param parent a <code>Component</code> object to be used
     *               as parent component for PrintingStatus dialog
     * @param job    a <code>PrinterJob</code> object to be cancelled
     *               using this <code>PrintingStatus</code> dialog
     * @return a <code>PrintingStatus</code> object
     */
    public static PrintingStatus
            createPrintingStatus(Component parent, PrinterJob job) {
        return new PrintingStatus(parent, job);
    }

    protected PrintingStatus(Component parent, PrinterJob job) {
        this.job = job;
        this.parent = parent;
    }

    private void init() {
        // prepare the status JOptionPane
        String progressTitle =
            UIManager.getString("PrintingDialog.titleProgressText");

        String dialogInitialContent =
            UIManager.getString("PrintingDialog.contentInitialText");

        // this one's a MessageFormat since it must include the page
        // number in its text
        statusFormat = new MessageFormat(
            UIManager.getString("PrintingDialog.contentProgressText"));

        String abortText =
            UIManager.getString("PrintingDialog.abortButtonText");
        String abortTooltip =
            UIManager.getString("PrintingDialog.abortButtonToolTipText");
        int abortMnemonic =
            getInt("PrintingDialog.abortButtonMnemonic", -1);
        int abortMnemonicIndex =
            getInt("PrintingDialog.abortButtonDisplayedMnemonicIndex", -1);

        abortButton = new JButton(abortText);
        abortButton.addActionListener(abortAction);

        abortButton.setToolTipText(abortTooltip);
        if (abortMnemonic != -1) {
            abortButton.setMnemonic(abortMnemonic);
        }
        if (abortMnemonicIndex != -1) {
            abortButton.setDisplayedMnemonicIndex(abortMnemonicIndex);
        }
        statusLabel = new JLabel(dialogInitialContent);
        JOptionPane abortPane = new JOptionPane(statusLabel,
            JOptionPane.INFORMATION_MESSAGE,
            JOptionPane.DEFAULT_OPTION,
            null, new Object[]{abortButton},
            abortButton);
        abortPane.getActionMap().put("close", abortAction);

        // The dialog should be centered over the viewport if the table is in one
        if (parent != null && parent.getParent() instanceof JViewport) {
            abortDialog =
                    abortPane.createDialog(parent.getParent(), progressTitle);
        } else {
            abortDialog = abortPane.createDialog(parent, progressTitle);
        }
        // clicking the X button should not hide the dialog
        abortDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
        abortDialog.addWindowListener(closeListener);
    }

    /**
     * Shows PrintingStatus dialog.
     * if dialog is modal this method returns only
     * after <code>dispose()</code> was called otherwise returns immediately
     *
     * @param isModal <code>true</code> this dialog should be modal;
     *                <code>false</code> otherwise.
     * @see #dispose
     */
    public void showModal(final boolean isModal) {
        if (SwingUtilities.isEventDispatchThread()) {
            showModalOnEDT(isModal);
        } else {
            try {
                SwingUtilities.invokeAndWait(new Runnable() {
                    public void run() {
                        showModalOnEDT(isModal);
                    }
                });
            } catch(InterruptedException e) {
                throw new RuntimeException(e);
            } catch(InvocationTargetException e) {
                Throwable cause = e.getCause();
                if (cause instanceof RuntimeException) {
                   throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                   throw (Error) cause;
                } else {
                   throw new RuntimeException(cause);
                }
            }
        }
    }

    /**
     * The EDT part of the showModal method.
     *
     * This method is to be called on the EDT only.
     */
    private void showModalOnEDT(boolean isModal) {
        assert SwingUtilities.isEventDispatchThread();
        init();
        abortDialog.setModal(isModal);
        abortDialog.setVisible(true);
    }

    /**
     * Disposes modal PrintingStatus dialog
     *
     * @see #showModal(boolean)
     */
    public void dispose() {
        if (SwingUtilities.isEventDispatchThread()) {
            disposeOnEDT();
        } else {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    disposeOnEDT();
                }
            });
        }
    }

    /**
     * The EDT part of the dispose method.
     *
     * This method is to be called on the EDT only.
     */
    private void disposeOnEDT() {
        assert SwingUtilities.isEventDispatchThread();
        if (abortDialog != null) {
            abortDialog.removeWindowListener(closeListener);
            abortDialog.dispose();
            abortDialog = null;
        }
    }

    /**
     * Returns whether the printing was aborted using this PrintingStatus
     *
     * @return whether the printing was aborted using this PrintingStatus
     */
    public boolean isAborted() {
        return isAborted.get();
    }

    /**
     * Returns printable which is used to track the current page being
     * printed in this PrintingStatus
     *
     * @param printable to be used to create notification printable
     * @return printable which is used to track the current page being
     *         printed in this PrintingStatus
     * @throws NullPointerException if <code>printable</code> is <code>null</code>
     */
    public Printable createNotificationPrintable(Printable printable) {
        return new NotificationPrintable(printable);
    }

    private class NotificationPrintable implements Printable {
        private final Printable printDelegatee;

        public NotificationPrintable(Printable delegatee) {
            if (delegatee == null) {
                throw new NullPointerException("Printable is null");
            }
            this.printDelegatee = delegatee;
        }

        public int print(final Graphics graphics,
                         final PageFormat pageFormat, final int pageIndex)
                throws PrinterException {

            final int retVal =
                printDelegatee.print(graphics, pageFormat, pageIndex);
            if (retVal != NO_SUCH_PAGE && !isAborted()) {
                if (SwingUtilities.isEventDispatchThread()) {
                    updateStatusOnEDT(pageIndex);
                } else {
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            updateStatusOnEDT(pageIndex);
                        }
                    });
                }
            }
            return retVal;
        }

        /**
         * The EDT part of the print method.
         *
         * This method is to be called on the EDT only.
         */
        private void updateStatusOnEDT(int pageIndex) {
            assert SwingUtilities.isEventDispatchThread();
            Object[] pageNumber = new Object[]{
                pageIndex + 1};
            statusLabel.setText(statusFormat.format(pageNumber));
        }
    }

    /**
     * Duplicated from UIManager to make it visible
     */
    static int getInt(Object key, int defaultValue) {
        Object value = UIManager.get(key);
        if (value instanceof Integer) {
            return ((Integer) value).intValue();
        }
        if (value instanceof String) {
            try {
                return Integer.parseInt((String) value);
            } catch(NumberFormatException nfe) {
            }
        }
        return defaultValue;
    }
}
