/*
 * Copyright (c) 2000, 2008, 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.print;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Vector;
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.text.NumberFormatter;
import sun.print.SunPageSelection;
import java.awt.event.KeyEvent;
import java.net.URISyntaxException;


/**
 * A class which implements a cross-platform print dialog.
 *
 * @author  Chris Campbell
 */
public class ServiceDialog extends JDialog implements ActionListener {

    /**
     * Waiting print status (user response pending).
     */
    public final static int WAITING = 0;

    /**
     * Approve print status (user activated "Print" or "OK").
     */
    public final static int APPROVE = 1;

    /**
     * Cancel print status (user activated "Cancel");
     */
    public final static int CANCEL = 2;

    private static final String strBundle = "sun.print.resources.serviceui";
    private static final Insets panelInsets = new Insets(6, 6, 6, 6);
    private static final Insets compInsets = new Insets(3, 6, 3, 6);

    private static ResourceBundle messageRB;
    private JTabbedPane tpTabs;
    private JButton btnCancel, btnApprove;
    private PrintService[] services;
    private int defaultServiceIndex;
    private PrintRequestAttributeSet asOriginal;
    private HashPrintRequestAttributeSet asCurrent;
    private PrintService psCurrent;
    private DocFlavor docFlavor;
    private int status;

    private ValidatingFileChooser jfc;

    private GeneralPanel pnlGeneral;
    private PageSetupPanel pnlPageSetup;
    private AppearancePanel pnlAppearance;

    private boolean isAWT = false;


    static {
        initResource();
    }


    /**
     * Constructor for the "standard" print dialog (containing all relevant
     * tabs)
     */
    public ServiceDialog(GraphicsConfiguration gc,
                         int x, int y,
                         PrintService[] services,
                         int defaultServiceIndex,
                         DocFlavor flavor,
                         PrintRequestAttributeSet attributes,
                         Dialog dialog)
    {
        super(dialog, getMsg("dialog.printtitle"), true, gc);
        initPrintDialog(x, y, services, defaultServiceIndex,
                        flavor, attributes);
    }



    /**
     * Constructor for the "standard" print dialog (containing all relevant
     * tabs)
     */
    public ServiceDialog(GraphicsConfiguration gc,
                         int x, int y,
                         PrintService[] services,
                         int defaultServiceIndex,
                         DocFlavor flavor,
                         PrintRequestAttributeSet attributes,
                         Frame frame)
    {
        super(frame, getMsg("dialog.printtitle"), true, gc);
        initPrintDialog(x, y, services, defaultServiceIndex,
                        flavor, attributes);
    }


    /**
     * Initialize print dialog.
     */
    void initPrintDialog(int x, int y,
                         PrintService[] services,
                         int defaultServiceIndex,
                         DocFlavor flavor,
                         PrintRequestAttributeSet attributes)
    {
        this.services = services;
        this.defaultServiceIndex = defaultServiceIndex;
        this.asOriginal = attributes;
        this.asCurrent = new HashPrintRequestAttributeSet(attributes);
        this.psCurrent = services[defaultServiceIndex];
        this.docFlavor = flavor;
        SunPageSelection pages =
            (SunPageSelection)attributes.get(SunPageSelection.class);
        if (pages != null) {
            isAWT = true;
        }

        Container c = getContentPane();
        c.setLayout(new BorderLayout());

        tpTabs = new JTabbedPane();
        tpTabs.setBorder(new EmptyBorder(5, 5, 5, 5));

        String gkey = getMsg("tab.general");
        int gmnemonic = getVKMnemonic("tab.general");
        pnlGeneral = new GeneralPanel();
        tpTabs.add(gkey, pnlGeneral);
        tpTabs.setMnemonicAt(0, gmnemonic);

        String pkey = getMsg("tab.pagesetup");
        int pmnemonic = getVKMnemonic("tab.pagesetup");
        pnlPageSetup = new PageSetupPanel();
        tpTabs.add(pkey, pnlPageSetup);
        tpTabs.setMnemonicAt(1, pmnemonic);

        String akey = getMsg("tab.appearance");
        int amnemonic = getVKMnemonic("tab.appearance");
        pnlAppearance = new AppearancePanel();
        tpTabs.add(akey, pnlAppearance);
        tpTabs.setMnemonicAt(2, amnemonic);

        c.add(tpTabs, BorderLayout.CENTER);

        updatePanels();

        JPanel pnlSouth = new JPanel(new FlowLayout(FlowLayout.TRAILING));
        btnApprove = createExitButton("button.print", this);
        pnlSouth.add(btnApprove);
        getRootPane().setDefaultButton(btnApprove);
        btnCancel = createExitButton("button.cancel", this);
        handleEscKey(btnCancel);
        pnlSouth.add(btnCancel);
        c.add(pnlSouth, BorderLayout.SOUTH);

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent event) {
                dispose(CANCEL);
            }
        });

        getAccessibleContext().setAccessibleDescription(getMsg("dialog.printtitle"));
        setResizable(false);
        setLocation(x, y);
        pack();
    }

   /**
     * Constructor for the solitary "page setup" dialog
     */
    public ServiceDialog(GraphicsConfiguration gc,
                         int x, int y,
                         PrintService ps,
                         DocFlavor flavor,
                         PrintRequestAttributeSet attributes,
                         Dialog dialog)
    {
        super(dialog, getMsg("dialog.pstitle"), true, gc);
        initPageDialog(x, y, ps, flavor, attributes);
    }

    /**
     * Constructor for the solitary "page setup" dialog
     */
    public ServiceDialog(GraphicsConfiguration gc,
                         int x, int y,
                         PrintService ps,
                         DocFlavor flavor,
                         PrintRequestAttributeSet attributes,
                         Frame frame)
    {
        super(frame, getMsg("dialog.pstitle"), true, gc);
        initPageDialog(x, y, ps, flavor, attributes);
    }


    /**
     * Initialize "page setup" dialog
     */
    void initPageDialog(int x, int y,
                         PrintService ps,
                         DocFlavor flavor,
                         PrintRequestAttributeSet attributes)
    {
        this.psCurrent = ps;
        this.docFlavor = flavor;
        this.asOriginal = attributes;
        this.asCurrent = new HashPrintRequestAttributeSet(attributes);

        Container c = getContentPane();
        c.setLayout(new BorderLayout());

        pnlPageSetup = new PageSetupPanel();
        c.add(pnlPageSetup, BorderLayout.CENTER);

        pnlPageSetup.updateInfo();

        JPanel pnlSouth = new JPanel(new FlowLayout(FlowLayout.TRAILING));
        btnApprove = createExitButton("button.ok", this);
        pnlSouth.add(btnApprove);
        getRootPane().setDefaultButton(btnApprove);
        btnCancel = createExitButton("button.cancel", this);
        handleEscKey(btnCancel);
        pnlSouth.add(btnCancel);
        c.add(pnlSouth, BorderLayout.SOUTH);

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent event) {
                dispose(CANCEL);
            }
        });

        getAccessibleContext().setAccessibleDescription(getMsg("dialog.pstitle"));
        setResizable(false);
        setLocation(x, y);
        pack();
    }

    /**
     * Performs Cancel when Esc key is pressed.
     */
    private void handleEscKey(JButton btnCancel) {
        Action cancelKeyAction = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                dispose(CANCEL);
            }
        };
        KeyStroke cancelKeyStroke =
            KeyStroke.getKeyStroke((char)KeyEvent.VK_ESCAPE, 0);
        InputMap inputMap =
            btnCancel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap actionMap = btnCancel.getActionMap();

        if (inputMap != null && actionMap != null) {
            inputMap.put(cancelKeyStroke, "cancel");
            actionMap.put("cancel", cancelKeyAction);
        }
    }


    /**
     * Returns the current status of the dialog (whether the user has selected
     * the "Print" or "Cancel" button)
     */
    public int getStatus() {
        return status;
    }

    /**
     * Returns an AttributeSet based on whether or not the user cancelled the
     * dialog.  If the user selected "Print" we return their new selections,
     * otherwise we return the attributes that were passed in initially.
     */
    public PrintRequestAttributeSet getAttributes() {
        if (status == APPROVE) {
            return asCurrent;
        } else {
            return asOriginal;
        }
    }

    /**
     * Returns a PrintService based on whether or not the user cancelled the
     * dialog.  If the user selected "Print" we return the user's selection
     * for the PrintService, otherwise we return null.
     */
    public PrintService getPrintService() {
        if (status == APPROVE) {
            return psCurrent;
        } else {
            return null;
        }
    }

    /**
     * Sets the current status flag for the dialog and disposes it (thus
     * returning control of the parent frame back to the user)
     */
    public void dispose(int status) {
        this.status = status;

        super.dispose();
    }

    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        boolean approved = false;

        if (source == btnApprove) {
            approved = true;

            if (pnlGeneral != null) {
                if (pnlGeneral.isPrintToFileRequested()) {
                    approved = showFileChooser();
                } else {
                    asCurrent.remove(Destination.class);
                }
            }
        }

        dispose(approved ? APPROVE : CANCEL);
    }

    /**
     * Displays a JFileChooser that allows the user to select the destination
     * for "Print To File"
     */
    private boolean showFileChooser() {
        Class dstCategory = Destination.class;

        Destination dst = (Destination)asCurrent.get(dstCategory);
        if (dst == null) {
            dst = (Destination)asOriginal.get(dstCategory);
            if (dst == null) {
                dst = (Destination)psCurrent.getDefaultAttributeValue(dstCategory);
                // "dst" should not be null. The following code
                // is only added to safeguard against a possible
                // buggy implementation of a PrintService having a
                // null default Destination.
                if (dst == null) {
                    try {
                        dst = new Destination(new URI("file:out.prn"));
                    } catch (URISyntaxException e) {
                    }
                }
            }
        }

        File fileDest;
        if (dst != null) {
            try {
                fileDest = new File(dst.getURI());
            } catch (Exception e) {
                // all manner of runtime exceptions possible
                fileDest = new File("out.prn");
            }
        } else {
            fileDest = new File("out.prn");
        }

        ValidatingFileChooser jfc = new ValidatingFileChooser();
        jfc.setApproveButtonText(getMsg("button.ok"));
        jfc.setDialogTitle(getMsg("dialog.printtofile"));
        jfc.setSelectedFile(fileDest);

        int returnVal = jfc.showDialog(this, null);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            fileDest = jfc.getSelectedFile();

            try {
                asCurrent.add(new Destination(fileDest.toURI()));
            } catch (Exception e) {
                asCurrent.remove(dstCategory);
            }
        } else {
            asCurrent.remove(dstCategory);
        }

        return (returnVal == JFileChooser.APPROVE_OPTION);
    }

    /**
     * Updates each of the top level panels
     */
    private void updatePanels() {
        pnlGeneral.updateInfo();
        pnlPageSetup.updateInfo();
        pnlAppearance.updateInfo();
    }

    /**
     * Initialize ResourceBundle
     */
    public static void initResource() {
        java.security.AccessController.doPrivileged(
            new java.security.PrivilegedAction() {
                public Object run() {
                    try {
                        messageRB = ResourceBundle.getBundle(strBundle);
                        return null;
                    } catch (java.util.MissingResourceException e) {
                        throw new Error("Fatal: Resource for ServiceUI " +
                                        "is missing");
                    }
                }
            }
        );
    }

    /**
     * Returns message string from resource
     */
    public static String getMsg(String key) {
        try {
            return messageRB.getString(key);
        } catch (java.util.MissingResourceException e) {
            throw new Error("Fatal: Resource for ServiceUI is broken; " +
                            "there is no " + key + " key in resource");
        }
    }

    /**
     * Returns mnemonic character from resource
     */
    private static char getMnemonic(String key) {
        String str = getMsg(key + ".mnemonic");
        if ((str != null) && (str.length() > 0)) {
            return str.charAt(0);
        } else {
            return (char)0;
        }
    }

    /**
     * Returns the mnemonic as a KeyEvent.VK constant from the resource.
     */
    private static int getVKMnemonic(String key) {
        String str = getMsg(key + ".vkMnemonic");
        if ((str != null) && (str.length() > 0)) {
            try {
                return Integer.parseInt(str);
            } catch (NumberFormatException nfe) {}
        }
        return 0;
    }

    /**
     * Returns URL for image resource
     */
    private static URL getImageResource(final String key) {
        URL url = (URL)java.security.AccessController.doPrivileged(
                       new java.security.PrivilegedAction() {
                public Object run() {
                    URL url = ServiceDialog.class.getResource(
                                                  "resources/" + key);
                    return url;
                }
        });

        if (url == null) {
            throw new Error("Fatal: Resource for ServiceUI is broken; " +
                            "there is no " + key + " key in resource");
        }

        return url;
    }

    /**
     * Creates a new JButton and sets its text, mnemonic, and ActionListener
     */
    private static JButton createButton(String key, ActionListener al) {
        JButton btn = new JButton(getMsg(key));
        btn.setMnemonic(getMnemonic(key));
        btn.addActionListener(al);

        return btn;
    }

    /**
     * Creates a new JButton and sets its text, and ActionListener
     */
    private static JButton createExitButton(String key, ActionListener al) {
        String str = getMsg(key);
        JButton btn = new JButton(str);
        btn.addActionListener(al);
        btn.getAccessibleContext().setAccessibleDescription(str);
        return btn;
    }

    /**
     * Creates a new JCheckBox and sets its text, mnemonic, and ActionListener
     */
    private static JCheckBox createCheckBox(String key, ActionListener al) {
        JCheckBox cb = new JCheckBox(getMsg(key));
        cb.setMnemonic(getMnemonic(key));
        cb.addActionListener(al);

        return cb;
    }

    /**
     * Creates a new JRadioButton and sets its text, mnemonic,
     * and ActionListener
     */
    private static JRadioButton createRadioButton(String key,
                                                  ActionListener al)
    {
        JRadioButton rb = new JRadioButton(getMsg(key));
        rb.setMnemonic(getMnemonic(key));
        rb.addActionListener(al);

        return rb;
    }

  /**
   * Creates a  pop-up dialog for "no print service"
   */
    public static void showNoPrintService(GraphicsConfiguration gc)
    {
        Frame dlgFrame = new Frame(gc);
        JOptionPane.showMessageDialog(dlgFrame,
                                      getMsg("dialog.noprintermsg"));
        dlgFrame.dispose();
    }

    /**
     * Sets the constraints for the GridBagLayout and adds the Component
     * to the given Container
     */
    private static void addToGB(Component comp, Container cont,
                                GridBagLayout gridbag,
                                GridBagConstraints constraints)
    {
        gridbag.setConstraints(comp, constraints);
        cont.add(comp);
    }

    /**
     * Adds the AbstractButton to both the given ButtonGroup and Container
     */
    private static void addToBG(AbstractButton button, Container cont,
                                ButtonGroup bg)
    {
        bg.add(button);
        cont.add(button);
    }




    /**
     * The "General" tab.  Includes the controls for PrintService,
     * PageRange, and Copies/Collate.
     */
    private class GeneralPanel extends JPanel {

        private PrintServicePanel pnlPrintService;
        private PrintRangePanel pnlPrintRange;
        private CopiesPanel pnlCopies;

        public GeneralPanel() {
            super();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            setLayout(gridbag);

            c.fill = GridBagConstraints.BOTH;
            c.insets = panelInsets;
            c.weightx = 1.0;
            c.weighty = 1.0;

            c.gridwidth = GridBagConstraints.REMAINDER;
            pnlPrintService = new PrintServicePanel();
            addToGB(pnlPrintService, this, gridbag, c);

            c.gridwidth = GridBagConstraints.RELATIVE;
            pnlPrintRange = new PrintRangePanel();
            addToGB(pnlPrintRange, this, gridbag, c);

            c.gridwidth = GridBagConstraints.REMAINDER;
            pnlCopies = new CopiesPanel();
            addToGB(pnlCopies, this, gridbag, c);
        }

        public boolean isPrintToFileRequested() {
            return (pnlPrintService.isPrintToFileSelected());
        }

        public void updateInfo() {
            pnlPrintService.updateInfo();
            pnlPrintRange.updateInfo();
            pnlCopies.updateInfo();
        }
    }

    private class PrintServicePanel extends JPanel
        implements ActionListener, ItemListener, PopupMenuListener
    {
        private final String strTitle = getMsg("border.printservice");
        private FilePermission printToFilePermission;
        private JButton btnProperties;
        private JCheckBox cbPrintToFile;
        private JComboBox cbName;
        private JLabel lblType, lblStatus, lblInfo;
        private ServiceUIFactory uiFactory;
        private boolean changedService = false;
        private boolean filePermission;

        public PrintServicePanel() {
            super();

            uiFactory = psCurrent.getServiceUIFactory();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            setLayout(gridbag);
            setBorder(BorderFactory.createTitledBorder(strTitle));

            String[] psnames = new String[services.length];
            for (int i = 0; i < psnames.length; i++) {
                psnames[i] = services[i].getName();
            }
            cbName = new JComboBox(psnames);
            cbName.setSelectedIndex(defaultServiceIndex);
            cbName.addItemListener(this);
            cbName.addPopupMenuListener(this);

            c.fill = GridBagConstraints.BOTH;
            c.insets = compInsets;

            c.weightx = 0.0;
            JLabel lblName = new JLabel(getMsg("label.psname"), JLabel.TRAILING);
            lblName.setDisplayedMnemonic(getMnemonic("label.psname"));
            lblName.setLabelFor(cbName);
            addToGB(lblName, this, gridbag, c);
            c.weightx = 1.0;
            c.gridwidth = GridBagConstraints.RELATIVE;
            addToGB(cbName, this, gridbag, c);
            c.weightx = 0.0;
            c.gridwidth = GridBagConstraints.REMAINDER;
            btnProperties = createButton("button.properties", this);
            addToGB(btnProperties, this, gridbag, c);

            c.weighty = 1.0;
            lblStatus = addLabel(getMsg("label.status"), gridbag, c);
            lblStatus.setLabelFor(null);

            lblType = addLabel(getMsg("label.pstype"), gridbag, c);
            lblType.setLabelFor(null);

            c.gridwidth = 1;
            addToGB(new JLabel(getMsg("label.info"), JLabel.TRAILING),
                    this, gridbag, c);
            c.gridwidth = GridBagConstraints.RELATIVE;
            lblInfo = new JLabel();
            lblInfo.setLabelFor(null);

            addToGB(lblInfo, this, gridbag, c);

            c.gridwidth = GridBagConstraints.REMAINDER;
            cbPrintToFile = createCheckBox("checkbox.printtofile", this);
            addToGB(cbPrintToFile, this, gridbag, c);

            filePermission = allowedToPrintToFile();
        }

        public boolean isPrintToFileSelected() {
            return cbPrintToFile.isSelected();
        }

        private JLabel addLabel(String text,
                                GridBagLayout gridbag, GridBagConstraints c)
        {
            c.gridwidth = 1;
            addToGB(new JLabel(text, JLabel.TRAILING), this, gridbag, c);

            c.gridwidth = GridBagConstraints.REMAINDER;
            JLabel label = new JLabel();
            addToGB(label, this, gridbag, c);

            return label;
        }

        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();

            if (source == btnProperties) {
                if (uiFactory != null) {
                    JDialog dialog = (JDialog)uiFactory.getUI(
                                               ServiceUIFactory.MAIN_UIROLE,
                                               ServiceUIFactory.JDIALOG_UI);

                    if (dialog != null) {
                        dialog.show();
                    } else {
                        // REMIND: may want to notify the user why we're
                        //         disabling the button
                        btnProperties.setEnabled(false);
                    }
                }
            }
        }

        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                int index = cbName.getSelectedIndex();

                if ((index >= 0) && (index < services.length)) {
                    if (!services[index].equals(psCurrent)) {
                        psCurrent = services[index];
                        uiFactory = psCurrent.getServiceUIFactory();
                        changedService = true;

                        Destination dest =
                            (Destination)asOriginal.get(Destination.class);
                        // to preserve the state of Print To File
                        if ((dest != null || isPrintToFileSelected())
                            && psCurrent.isAttributeCategorySupported(
                                                        Destination.class)) {

                            if (dest != null) {
                                asCurrent.add(dest);
                            } else {
                                dest = (Destination)psCurrent.
                                    getDefaultAttributeValue(Destination.class);
                                // "dest" should not be null. The following code
                                // is only added to safeguard against a possible
                                // buggy implementation of a PrintService having a
                                // null default Destination.
                                if (dest == null) {
                                    try {
                                        dest =
                                            new Destination(new URI("file:out.prn"));
                                    } catch (URISyntaxException ue) {
                                    }
                                }

                                if (dest != null) {
                                    asCurrent.add(dest);
                                }
                            }
                        } else {
                            asCurrent.remove(Destination.class);
                        }
                    }
                }
            }
        }

        public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
            changedService = false;
        }

        public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
            if (changedService) {
                changedService = false;
                updatePanels();
            }
        }

        public void popupMenuCanceled(PopupMenuEvent e) {
        }

        /**
         * We disable the "Print To File" checkbox if this returns false
         */
        private boolean allowedToPrintToFile() {
            try {
                throwPrintToFile();
                return true;
            } catch (SecurityException e) {
                return false;
            }
        }

        /**
         * Break this out as it may be useful when we allow API to
         * specify printing to a file. In that case its probably right
         * to throw a SecurityException if the permission is not granted.
         */
        private void throwPrintToFile() {
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                if (printToFilePermission == null) {
                    printToFilePermission =
                        new FilePermission("<<ALL FILES>>", "read,write");
                }
                security.checkPermission(printToFilePermission);
            }
        }

        public void updateInfo() {
            Class dstCategory = Destination.class;
            boolean dstSupported = false;
            boolean dstSelected = false;
            boolean dstAllowed = filePermission ?
                allowedToPrintToFile() : false;

            // setup Destination (print-to-file) widgets
            if (psCurrent.isAttributeCategorySupported(dstCategory)) {
                dstSupported = true;
            }
            Destination dst = (Destination)asCurrent.get(dstCategory);
            if (dst != null) {
                dstSelected = true;
            }
            cbPrintToFile.setEnabled(dstSupported && dstAllowed);
            cbPrintToFile.setSelected(dstSelected && dstAllowed
                                      && dstSupported);

            // setup PrintService information widgets
            Attribute type = psCurrent.getAttribute(PrinterMakeAndModel.class);
            if (type != null) {
                lblType.setText(type.toString());
            }
            Attribute status =
                psCurrent.getAttribute(PrinterIsAcceptingJobs.class);
            if (status != null) {
                lblStatus.setText(getMsg(status.toString()));
            }
            Attribute info = psCurrent.getAttribute(PrinterInfo.class);
            if (info != null) {
                lblInfo.setText(info.toString());
            }
            btnProperties.setEnabled(uiFactory != null);
        }
    }

    private class PrintRangePanel extends JPanel
        implements ActionListener, FocusListener
    {
        private final String strTitle = getMsg("border.printrange");
        private final PageRanges prAll = new PageRanges(1, Integer.MAX_VALUE);
        private JRadioButton rbAll, rbPages, rbSelect;
        private JFormattedTextField tfRangeFrom, tfRangeTo;
        private JLabel lblRangeTo;
        private boolean prSupported;

        public PrintRangePanel() {
            super();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            setLayout(gridbag);
            setBorder(BorderFactory.createTitledBorder(strTitle));

            c.fill = GridBagConstraints.BOTH;
            c.insets = compInsets;
            c.gridwidth = GridBagConstraints.REMAINDER;

            ButtonGroup bg = new ButtonGroup();
            JPanel pnlTop = new JPanel(new FlowLayout(FlowLayout.LEADING));
            rbAll = createRadioButton("radiobutton.rangeall", this);
            rbAll.setSelected(true);
            bg.add(rbAll);
            pnlTop.add(rbAll);
            addToGB(pnlTop, this, gridbag, c);

            // Selection never seemed to work so I'm commenting this part.
            /*
            if (isAWT) {
                JPanel pnlMiddle  =
                    new JPanel(new FlowLayout(FlowLayout.LEADING));
                rbSelect =
                    createRadioButton("radiobutton.selection", this);
                bg.add(rbSelect);
                pnlMiddle.add(rbSelect);
                addToGB(pnlMiddle, this, gridbag, c);
            }
            */

            JPanel pnlBottom = new JPanel(new FlowLayout(FlowLayout.LEADING));
            rbPages = createRadioButton("radiobutton.rangepages", this);
            bg.add(rbPages);
            pnlBottom.add(rbPages);
            DecimalFormat format = new DecimalFormat("####0");
            format.setMinimumFractionDigits(0);
            format.setMaximumFractionDigits(0);
            format.setMinimumIntegerDigits(0);
            format.setMaximumIntegerDigits(5);
            format.setParseIntegerOnly(true);
            format.setDecimalSeparatorAlwaysShown(false);
            NumberFormatter nf = new NumberFormatter(format);
            nf.setMinimum(new Integer(1));
            nf.setMaximum(new Integer(Integer.MAX_VALUE));
            nf.setAllowsInvalid(true);
            nf.setCommitsOnValidEdit(true);
            tfRangeFrom = new JFormattedTextField(nf);
            tfRangeFrom.setColumns(4);
            tfRangeFrom.setEnabled(false);
            tfRangeFrom.addActionListener(this);
            tfRangeFrom.addFocusListener(this);
            tfRangeFrom.setFocusLostBehavior(
                JFormattedTextField.PERSIST);
            tfRangeFrom.getAccessibleContext().setAccessibleName(
                                          getMsg("radiobutton.rangepages"));
            pnlBottom.add(tfRangeFrom);
            lblRangeTo = new JLabel(getMsg("label.rangeto"));
            lblRangeTo.setEnabled(false);
            pnlBottom.add(lblRangeTo);
            NumberFormatter nfto;
            try {
                nfto = (NumberFormatter)nf.clone();
            } catch (CloneNotSupportedException e) {
                nfto = new NumberFormatter();
            }
            tfRangeTo = new JFormattedTextField(nfto);
            tfRangeTo.setColumns(4);
            tfRangeTo.setEnabled(false);
            tfRangeTo.addFocusListener(this);
            tfRangeTo.getAccessibleContext().setAccessibleName(
                                          getMsg("label.rangeto"));
            pnlBottom.add(tfRangeTo);
            addToGB(pnlBottom, this, gridbag, c);
        }

        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();
            SunPageSelection select = SunPageSelection.ALL;

            setupRangeWidgets();

            if (source == rbAll) {
                asCurrent.add(prAll);
            } else if (source == rbSelect) {
                select = SunPageSelection.SELECTION;
            } else if (source == rbPages ||
                       source == tfRangeFrom ||
                       source == tfRangeTo) {
                updateRangeAttribute();
                select = SunPageSelection.RANGE;
            }

            if (isAWT) {
                asCurrent.add(select);
            }
        }

        public void focusLost(FocusEvent e) {
            Object source = e.getSource();

            if ((source == tfRangeFrom) || (source == tfRangeTo)) {
                updateRangeAttribute();
            }
        }

        public void focusGained(FocusEvent e) {}

        private void setupRangeWidgets() {
            boolean rangeEnabled = (rbPages.isSelected() && prSupported);
            tfRangeFrom.setEnabled(rangeEnabled);
            tfRangeTo.setEnabled(rangeEnabled);
            lblRangeTo.setEnabled(rangeEnabled);
        }

        private void updateRangeAttribute() {
            String strFrom = tfRangeFrom.getText();
            String strTo = tfRangeTo.getText();

            int min;
            int max;

            try {
                min = Integer.parseInt(strFrom);
            } catch (NumberFormatException e) {
                min = 1;
            }

            try {
                max = Integer.parseInt(strTo);
            } catch (NumberFormatException e) {
                max = min;
            }

            if (min < 1) {
                min = 1;
                tfRangeFrom.setValue(new Integer(1));
            }

            if (max < min) {
                max = min;
                tfRangeTo.setValue(new Integer(min));
            }

            PageRanges pr = new PageRanges(min, max);
            asCurrent.add(pr);
        }

        public void updateInfo() {
            Class prCategory = PageRanges.class;
            prSupported = false;

            if (psCurrent.isAttributeCategorySupported(prCategory) ||
                   isAWT) {
                prSupported = true;
            }

            SunPageSelection select = SunPageSelection.ALL;
            int min = 1;
            int max = 1;

            PageRanges pr = (PageRanges)asCurrent.get(prCategory);
            if (pr != null) {
                if (!pr.equals(prAll)) {
                    select = SunPageSelection.RANGE;

                    int[][] members = pr.getMembers();
                    if ((members.length > 0) &&
                        (members[0].length > 1)) {
                        min = members[0][0];
                        max = members[0][1];
                    }
                }
            }

            if (isAWT) {
                select = (SunPageSelection)asCurrent.get(
                                                SunPageSelection.class);
            }

            if (select == SunPageSelection.ALL) {
                rbAll.setSelected(true);
            } else if (select == SunPageSelection.SELECTION) {
                // Comment this for now -  rbSelect is not initialized
                // because Selection button is not added.
                // See PrintRangePanel above.

                //rbSelect.setSelected(true);
            } else { // RANGE
                rbPages.setSelected(true);
            }
            tfRangeFrom.setValue(new Integer(min));
            tfRangeTo.setValue(new Integer(max));
            rbAll.setEnabled(prSupported);
            rbPages.setEnabled(prSupported);
            setupRangeWidgets();
        }
    }

    private class CopiesPanel extends JPanel
        implements ActionListener, ChangeListener
    {
        private final String strTitle = getMsg("border.copies");
        private SpinnerNumberModel snModel;
        private JSpinner spinCopies;
        private JLabel lblCopies;
        private JCheckBox cbCollate;
        private boolean scSupported;

        public CopiesPanel() {
            super();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            setLayout(gridbag);
            setBorder(BorderFactory.createTitledBorder(strTitle));

            c.fill = GridBagConstraints.HORIZONTAL;
            c.insets = compInsets;

            lblCopies = new JLabel(getMsg("label.numcopies"), JLabel.TRAILING);
            lblCopies.setDisplayedMnemonic(getMnemonic("label.numcopies"));
            lblCopies.getAccessibleContext().setAccessibleName(
                                             getMsg("label.numcopies"));
            addToGB(lblCopies, this, gridbag, c);

            snModel = new SpinnerNumberModel(1, 1, 999, 1);
            spinCopies = new JSpinner(snModel);
            lblCopies.setLabelFor(spinCopies);
            // REMIND
            ((JSpinner.NumberEditor)spinCopies.getEditor()).getTextField().setColumns(3);
            spinCopies.addChangeListener(this);
            c.gridwidth = GridBagConstraints.REMAINDER;
            addToGB(spinCopies, this, gridbag, c);

            cbCollate = createCheckBox("checkbox.collate", this);
            cbCollate.setEnabled(false);
            addToGB(cbCollate, this, gridbag, c);
        }

        public void actionPerformed(ActionEvent e) {
            if (cbCollate.isSelected()) {
                asCurrent.add(SheetCollate.COLLATED);
            } else {
                asCurrent.add(SheetCollate.UNCOLLATED);
            }
        }

        public void stateChanged(ChangeEvent e) {
            updateCollateCB();

            asCurrent.add(new Copies(snModel.getNumber().intValue()));
        }

        private void updateCollateCB() {
            int num = snModel.getNumber().intValue();
            if (isAWT) {
                cbCollate.setEnabled(true);
            } else {
                cbCollate.setEnabled((num > 1) && scSupported);
            }
        }

        public void updateInfo() {
            Class cpCategory = Copies.class;
            Class csCategory = CopiesSupported.class;
            Class scCategory = SheetCollate.class;
            boolean cpSupported = false;
            scSupported = false;

            // setup Copies spinner
            if (psCurrent.isAttributeCategorySupported(cpCategory)) {
                cpSupported = true;
            }
            CopiesSupported cs =
                (CopiesSupported)psCurrent.getSupportedAttributeValues(
                                                       cpCategory, null, null);
            if (cs == null) {
                cs = new CopiesSupported(1, 999);
            }
            Copies cp = (Copies)asCurrent.get(cpCategory);
            if (cp == null) {
                cp = (Copies)psCurrent.getDefaultAttributeValue(cpCategory);
                if (cp == null) {
                    cp = new Copies(1);
                }
            }
            spinCopies.setEnabled(cpSupported);
            lblCopies.setEnabled(cpSupported);

            int[][] members = cs.getMembers();
            int min, max;
            if ((members.length > 0) && (members[0].length > 0)) {
                min = members[0][0];
                max = members[0][1];
            } else {
                min = 1;
                max = Integer.MAX_VALUE;
            }
            snModel.setMinimum(new Integer(min));
            snModel.setMaximum(new Integer(max));

            int value = cp.getValue();
            if ((value < min) || (value > max)) {
                value = min;
            }
            snModel.setValue(new Integer(value));

            // setup Collate checkbox
            if (psCurrent.isAttributeCategorySupported(scCategory)) {
                scSupported = true;
            }
            SheetCollate sc = (SheetCollate)asCurrent.get(scCategory);
            if (sc == null) {
                sc = (SheetCollate)psCurrent.getDefaultAttributeValue(scCategory);
                if (sc == null) {
                    sc = SheetCollate.UNCOLLATED;
                }
            }
            cbCollate.setSelected(sc == SheetCollate.COLLATED);
            updateCollateCB();
        }
    }




    /**
     * The "Page Setup" tab.  Includes the controls for MediaSource/MediaTray,
     * OrientationRequested, and Sides.
     */
    private class PageSetupPanel extends JPanel {

        private MediaPanel pnlMedia;
        private OrientationPanel pnlOrientation;
        private MarginsPanel pnlMargins;

        public PageSetupPanel() {
            super();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            setLayout(gridbag);

            c.fill = GridBagConstraints.BOTH;
            c.insets = panelInsets;
            c.weightx = 1.0;
            c.weighty = 1.0;

            c.gridwidth = GridBagConstraints.REMAINDER;
            pnlMedia = new MediaPanel();
            addToGB(pnlMedia, this, gridbag, c);

            pnlOrientation = new OrientationPanel();
            c.gridwidth = GridBagConstraints.RELATIVE;
            addToGB(pnlOrientation, this, gridbag, c);

            pnlMargins = new MarginsPanel();
            pnlOrientation.addOrientationListener(pnlMargins);
            pnlMedia.addMediaListener(pnlMargins);
            c.gridwidth = GridBagConstraints.REMAINDER;
            addToGB(pnlMargins, this, gridbag, c);
        }

        public void updateInfo() {
            pnlMedia.updateInfo();
            pnlOrientation.updateInfo();
            pnlMargins.updateInfo();
        }
    }

    private class MarginsPanel extends JPanel
                               implements ActionListener, FocusListener {

        private final String strTitle = getMsg("border.margins");
        private JFormattedTextField leftMargin, rightMargin,
                                    topMargin, bottomMargin;
        private JLabel lblLeft, lblRight, lblTop, lblBottom;
        private int units = MediaPrintableArea.MM;
        // storage for the last margin values calculated, -ve is uninitialised
        private float lmVal = -1f,rmVal = -1f, tmVal = -1f, bmVal = -1f;
        // storage for margins as objects mapped into orientation for display
        private Float lmObj,rmObj,tmObj,bmObj;

        public MarginsPanel() {
            super();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();
            c.fill = GridBagConstraints.HORIZONTAL;
            c.weightx = 1.0;
            c.weighty = 0.0;
            c.insets = compInsets;

            setLayout(gridbag);
            setBorder(BorderFactory.createTitledBorder(strTitle));

            String unitsKey = "label.millimetres";
            String defaultCountry = Locale.getDefault().getCountry();
            if (defaultCountry != null &&
                (defaultCountry.equals("") ||
                 defaultCountry.equals(Locale.US.getCountry()) ||
                 defaultCountry.equals(Locale.CANADA.getCountry()))) {
                unitsKey = "label.inches";
                units = MediaPrintableArea.INCH;
            }
            String unitsMsg = getMsg(unitsKey);

            DecimalFormat format;
            if (units == MediaPrintableArea.MM) {
                format = new DecimalFormat("###.##");
                format.setMaximumIntegerDigits(3);
            } else {
                format = new DecimalFormat("##.##");
                format.setMaximumIntegerDigits(2);
            }

            format.setMinimumFractionDigits(1);
            format.setMaximumFractionDigits(2);
            format.setMinimumIntegerDigits(1);
            format.setParseIntegerOnly(false);
            format.setDecimalSeparatorAlwaysShown(true);
            NumberFormatter nf = new NumberFormatter(format);
            nf.setMinimum(new Float(0.0f));
            nf.setMaximum(new Float(999.0f));
            nf.setAllowsInvalid(true);
            nf.setCommitsOnValidEdit(true);

            leftMargin = new JFormattedTextField(nf);
            leftMargin.addFocusListener(this);
            leftMargin.addActionListener(this);
            leftMargin.getAccessibleContext().setAccessibleName(
                                              getMsg("label.leftmargin"));
            rightMargin = new JFormattedTextField(nf);
            rightMargin.addFocusListener(this);
            rightMargin.addActionListener(this);
            rightMargin.getAccessibleContext().setAccessibleName(
                                              getMsg("label.rightmargin"));
            topMargin = new JFormattedTextField(nf);
            topMargin.addFocusListener(this);
            topMargin.addActionListener(this);
            topMargin.getAccessibleContext().setAccessibleName(
                                              getMsg("label.topmargin"));
            topMargin = new JFormattedTextField(nf);
            bottomMargin = new JFormattedTextField(nf);
            bottomMargin.addFocusListener(this);
            bottomMargin.addActionListener(this);
            bottomMargin.getAccessibleContext().setAccessibleName(
                                              getMsg("label.bottommargin"));
            topMargin = new JFormattedTextField(nf);
            c.gridwidth = GridBagConstraints.RELATIVE;
            lblLeft = new JLabel(getMsg("label.leftmargin") + " " + unitsMsg,
                                 JLabel.LEADING);
            lblLeft.setDisplayedMnemonic(getMnemonic("label.leftmargin"));
            lblLeft.setLabelFor(leftMargin);
            addToGB(lblLeft, this, gridbag, c);

            c.gridwidth = GridBagConstraints.REMAINDER;
            lblRight = new JLabel(getMsg("label.rightmargin") + " " + unitsMsg,
                                  JLabel.LEADING);
            lblRight.setDisplayedMnemonic(getMnemonic("label.rightmargin"));
            lblRight.setLabelFor(rightMargin);
            addToGB(lblRight, this, gridbag, c);

            c.gridwidth = GridBagConstraints.RELATIVE;
            addToGB(leftMargin, this, gridbag, c);

            c.gridwidth = GridBagConstraints.REMAINDER;
            addToGB(rightMargin, this, gridbag, c);

            // add an invisible spacing component.
            addToGB(new JPanel(), this, gridbag, c);

            c.gridwidth = GridBagConstraints.RELATIVE;
            lblTop = new JLabel(getMsg("label.topmargin") + " " + unitsMsg,
                                JLabel.LEADING);
            lblTop.setDisplayedMnemonic(getMnemonic("label.topmargin"));
            lblTop.setLabelFor(topMargin);
            addToGB(lblTop, this, gridbag, c);

            c.gridwidth = GridBagConstraints.REMAINDER;
            lblBottom = new JLabel(getMsg("label.bottommargin") +
                                   " " + unitsMsg, JLabel.LEADING);
            lblBottom.setDisplayedMnemonic(getMnemonic("label.bottommargin"));
            lblBottom.setLabelFor(bottomMargin);
            addToGB(lblBottom, this, gridbag, c);

            c.gridwidth = GridBagConstraints.RELATIVE;
            addToGB(topMargin, this, gridbag, c);

            c.gridwidth = GridBagConstraints.REMAINDER;
            addToGB(bottomMargin, this, gridbag, c);

        }

        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();
            updateMargins(source);
        }

        public void focusLost(FocusEvent e) {
            Object source = e.getSource();
            updateMargins(source);
        }

        public void focusGained(FocusEvent e) {}

        /* Get the numbers, use to create a MPA.
         * If its valid, accept it and update the attribute set.
         * If its not valid, then reject it and call updateInfo()
         * to re-establish the previous entries.
         */
        public void updateMargins(Object source) {
            if (!(source instanceof JFormattedTextField)) {
                return;
            } else {
                JFormattedTextField tf = (JFormattedTextField)source;
                Float val = (Float)tf.getValue();
                if (val == null) {
                    return;
                }
                if (tf == leftMargin && val.equals(lmObj)) {
                    return;
                }
                if (tf == rightMargin && val.equals(rmObj)) {
                    return;
                }
                if (tf == topMargin && val.equals(tmObj)) {
                    return;
                }
                if (tf == bottomMargin && val.equals(bmObj)) {
                    return;
                }
            }

            Float lmTmpObj = (Float)leftMargin.getValue();
            Float rmTmpObj = (Float)rightMargin.getValue();
            Float tmTmpObj = (Float)topMargin.getValue();
            Float bmTmpObj = (Float)bottomMargin.getValue();

            float lm = lmTmpObj.floatValue();
            float rm = rmTmpObj.floatValue();
            float tm = tmTmpObj.floatValue();
            float bm = bmTmpObj.floatValue();

            /* adjust for orientation */
            Class orCategory = OrientationRequested.class;
            OrientationRequested or =
                (OrientationRequested)asCurrent.get(orCategory);

            if (or == null) {
                or = (OrientationRequested)
                     psCurrent.getDefaultAttributeValue(orCategory);
            }

            float tmp;
            if (or == OrientationRequested.REVERSE_PORTRAIT) {
                tmp = lm; lm = rm; rm = tmp;
                tmp = tm; tm = bm; bm = tmp;
            } else if (or == OrientationRequested.LANDSCAPE) {
                tmp = lm;
                lm = tm;
                tm = rm;
                rm = bm;
                bm = tmp;
            } else if (or == OrientationRequested.REVERSE_LANDSCAPE) {
                tmp = lm;
                lm = bm;
                bm = rm;
                rm = tm;
                tm = tmp;
            }
            MediaPrintableArea mpa;
            if ((mpa = validateMargins(lm, rm, tm, bm)) != null) {
                asCurrent.add(mpa);
                lmVal = lm;
                rmVal = rm;
                tmVal = tm;
                bmVal = bm;
                lmObj = lmTmpObj;
                rmObj = rmTmpObj;
                tmObj = tmTmpObj;
                bmObj = bmTmpObj;
            } else {
                if (lmObj == null || rmObj == null ||
                    tmObj == null || rmObj == null) {
                    return;
                } else {
                    leftMargin.setValue(lmObj);
                    rightMargin.setValue(rmObj);
                    topMargin.setValue(tmObj);
                    bottomMargin.setValue(bmObj);

                }
            }
        }

        /*
         * This method either accepts the values and creates a new
         * MediaPrintableArea, or does nothing.
         * It should not attempt to create a printable area from anything
         * other than the exact values passed in.
         * But REMIND/TBD: it would be user friendly to replace margins the
         * user entered but are out of bounds with the minimum.
         * At that point this method will need to take responsibility for
         * updating the "stored" values and the UI.
         */
        private MediaPrintableArea validateMargins(float lm, float rm,
                                                   float tm, float bm) {

            Class mpaCategory = MediaPrintableArea.class;
            MediaPrintableArea mpa;
            MediaPrintableArea mpaMax = null;
            MediaSize mediaSize = null;

            Media media = (Media)asCurrent.get(Media.class);
            if (media == null || !(media instanceof MediaSizeName)) {
                media = (Media)psCurrent.getDefaultAttributeValue(Media.class);
            }
            if (media != null && (media instanceof MediaSizeName)) {
                MediaSizeName msn = (MediaSizeName)media;
                mediaSize = MediaSize.getMediaSizeForName(msn);
            }
            if (mediaSize == null) {
                mediaSize = new MediaSize(8.5f, 11f, Size2DSyntax.INCH);
            }

            if (media != null) {
                PrintRequestAttributeSet tmpASet =
                    new HashPrintRequestAttributeSet(asCurrent);
                tmpASet.add(media);

                Object values =
                    psCurrent.getSupportedAttributeValues(mpaCategory,
                                                          docFlavor,
                                                          tmpASet);
                if (values instanceof MediaPrintableArea[] &&
                    ((MediaPrintableArea[])values).length > 0) {
                    mpaMax = ((MediaPrintableArea[])values)[0];

                }
            }
            if (mpaMax == null) {
                mpaMax = new MediaPrintableArea(0f, 0f,
                                                mediaSize.getX(units),
                                                mediaSize.getY(units),
                                                units);
            }

            float wid = mediaSize.getX(units);
            float hgt = mediaSize.getY(units);
            float pax = lm;
            float pay = tm;
            float paw = wid - lm - rm;
            float pah = hgt - tm - bm;

            if (paw <= 0f || pah <= 0f || pax < 0f || pay < 0f ||
                pax < mpaMax.getX(units) || paw > mpaMax.getWidth(units) ||
                pay < mpaMax.getY(units) || pah > mpaMax.getHeight(units)) {
                return null;
            } else {
                return new MediaPrintableArea(lm, tm, paw, pah, units);
            }
        }

        /* This is complex as a MediaPrintableArea is valid only within
         * a particular context of media size.
         * So we need a MediaSize as well as a MediaPrintableArea.
         * MediaSize can be obtained from MediaSizeName.
         * If the application specifies a MediaPrintableArea, we accept it
         * to the extent its valid for the Media they specify. If they
         * don't specify a Media, then the default is assumed.
         *
         * If an application doesn't define a MediaPrintableArea, we need to
         * create a suitable one, this is created using the specified (or
         * default) Media and default 1 inch margins. This is validated
         * against the paper in case this is too large for tiny media.
         */
        public void updateInfo() {

            if (isAWT) {
                leftMargin.setEnabled(false);
                rightMargin.setEnabled(false);
                topMargin.setEnabled(false);
                bottomMargin.setEnabled(false);
                lblLeft.setEnabled(false);
                lblRight.setEnabled(false);
                lblTop.setEnabled(false);
                lblBottom.setEnabled(false);
                return;
            }

            Class mpaCategory = MediaPrintableArea.class;
            MediaPrintableArea mpa =
                 (MediaPrintableArea)asCurrent.get(mpaCategory);
            MediaPrintableArea mpaMax = null;
            MediaSize mediaSize = null;

            Media media = (Media)asCurrent.get(Media.class);
            if (media == null || !(media instanceof MediaSizeName)) {
                media = (Media)psCurrent.getDefaultAttributeValue(Media.class);
            }
            if (media != null && (media instanceof MediaSizeName)) {
                MediaSizeName msn = (MediaSizeName)media;
                mediaSize = MediaSize.getMediaSizeForName(msn);
            }
            if (mediaSize == null) {
                mediaSize = new MediaSize(8.5f, 11f, Size2DSyntax.INCH);
            }

            if (media != null) {
                PrintRequestAttributeSet tmpASet =
                    new HashPrintRequestAttributeSet(asCurrent);
                tmpASet.add(media);

                Object values =
                    psCurrent.getSupportedAttributeValues(mpaCategory,
                                                          docFlavor,
                                                          tmpASet);
                if (values instanceof MediaPrintableArea[] &&
                    ((MediaPrintableArea[])values).length > 0) {
                    mpaMax = ((MediaPrintableArea[])values)[0];

                } else if (values instanceof MediaPrintableArea) {
                    mpaMax = (MediaPrintableArea)values;
                }
            }
            if (mpaMax == null) {
                mpaMax = new MediaPrintableArea(0f, 0f,
                                                mediaSize.getX(units),
                                                mediaSize.getY(units),
                                                units);
            }

            /*
             * At this point we now know as best we can :-
             * - the media size
             * - the maximum corresponding printable area
             * - the media printable area specified by the client, if any.
             * The next step is to create a default MPA if none was specified.
             * 1" margins are used unless they are disproportionately
             * large compared to the size of the media.
             */

            float wid = mediaSize.getX(MediaPrintableArea.INCH);
            float hgt = mediaSize.getY(MediaPrintableArea.INCH);
            float maxMarginRatio = 5f;
            float xMgn, yMgn;
            if (wid > maxMarginRatio) {
                xMgn = 1f;
            } else {
                xMgn = wid / maxMarginRatio;
            }
            if (hgt > maxMarginRatio) {
                yMgn = 1f;
            } else {
                yMgn = hgt / maxMarginRatio;
            }

            if (mpa == null) {
                mpa = new MediaPrintableArea(xMgn, yMgn,
                                             wid-(2*xMgn), hgt-(2*yMgn),
                                             MediaPrintableArea.INCH);
                asCurrent.add(mpa);
            }
            float pax = mpa.getX(units);
            float pay = mpa.getY(units);
            float paw = mpa.getWidth(units);
            float pah = mpa.getHeight(units);
            float paxMax = mpaMax.getX(units);
            float payMax = mpaMax.getY(units);
            float pawMax = mpaMax.getWidth(units);
            float pahMax = mpaMax.getHeight(units);


            boolean invalid = false;

            // If the paper is set to something which is too small to
            // accommodate a specified printable area, perhaps carried
            // over from a larger paper, the adjustment that needs to be
            // performed should seem the most natural from a user's viewpoint.
            // Since the user is specifying margins, then we are biased
            // towards keeping the margins as close to what is specified as
            // possible, shrinking or growing the printable area.
            // But the API uses printable area, so you need to know the
            // media size in which the margins were previously interpreted,
            // or at least have a record of the margins.
            // In the case that this is the creation of this UI we do not
            // have this record, so we are somewhat reliant on the client
            // to supply a reasonable default
            wid = mediaSize.getX(units);
            hgt = mediaSize.getY(units);
            if (lmVal >= 0f) {
                invalid = true;

                if (lmVal + rmVal > wid) {
                    // margins impossible, but maintain P.A if can
                    if (paw > pawMax) {
                        paw = pawMax;
                    }
                    // try to centre the printable area.
                    pax = (wid - paw)/2f;
                } else {
                    pax = (lmVal >= paxMax) ? lmVal : paxMax;
                    paw = wid - pax - rmVal;
                }
                if (tmVal + bmVal > hgt) {
                    if (pah > pahMax) {
                        pah = pahMax;
                    }
                    pay = (hgt - pah)/2f;
                } else {
                    pay = (tmVal >= payMax) ? tmVal : payMax;
                    pah = hgt - pay - bmVal;
                }
            }
            if (pax < paxMax) {
                invalid = true;
                pax = paxMax;
            }
            if (pay < payMax) {
                invalid = true;
                pay = payMax;
            }
            if (paw > pawMax) {
                invalid = true;
                paw = pawMax;
            }
            if (pah > pahMax) {
                invalid = true;
                pah = pahMax;
            }

            if ((pax + paw > paxMax + pawMax) || (paw <= 0f)) {
                invalid = true;
                pax = paxMax;
                paw = pawMax;
            }
            if ((pay + pah > payMax + pahMax) || (pah <= 0f)) {
                invalid = true;
                pay = payMax;
                pah = pahMax;
            }

            if (invalid) {
                mpa = new MediaPrintableArea(pax, pay, paw, pah, units);
                asCurrent.add(mpa);
            }

            /* We now have a valid printable area.
             * Turn it into margins, using the mediaSize
             */
            lmVal = pax;
            tmVal = pay;
            rmVal = mediaSize.getX(units) - pax - paw;
            bmVal = mediaSize.getY(units) - pay - pah;

            lmObj = new Float(lmVal);
            rmObj = new Float(rmVal);
            tmObj = new Float(tmVal);
            bmObj = new Float(bmVal);

            /* Now we know the values to use, we need to assign them
             * to the fields appropriate for the orientation.
             * Note: if orientation changes this method must be called.
             */
            Class orCategory = OrientationRequested.class;
            OrientationRequested or =
                (OrientationRequested)asCurrent.get(orCategory);

            if (or == null) {
                or = (OrientationRequested)
                     psCurrent.getDefaultAttributeValue(orCategory);
            }

            Float tmp;

            if (or == OrientationRequested.REVERSE_PORTRAIT) {
                tmp = lmObj; lmObj = rmObj; rmObj = tmp;
                tmp = tmObj; tmObj = bmObj; bmObj = tmp;
            }  else if (or == OrientationRequested.LANDSCAPE) {
                tmp = lmObj;
                lmObj = bmObj;
                bmObj = rmObj;
                rmObj = tmObj;
                tmObj = tmp;
            }  else if (or == OrientationRequested.REVERSE_LANDSCAPE) {
                tmp = lmObj;
                lmObj = tmObj;
                tmObj = rmObj;
                rmObj = bmObj;
                bmObj = tmp;
            }

            leftMargin.setValue(lmObj);
            rightMargin.setValue(rmObj);
            topMargin.setValue(tmObj);
            bottomMargin.setValue(bmObj);
        }
    }

    private class MediaPanel extends JPanel implements ItemListener {

        private final String strTitle = getMsg("border.media");
        private JLabel lblSize, lblSource;
        private JComboBox cbSize, cbSource;
        private Vector sizes = new Vector();
        private Vector sources = new Vector();
        private MarginsPanel pnlMargins = null;

        public MediaPanel() {
            super();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            setLayout(gridbag);
            setBorder(BorderFactory.createTitledBorder(strTitle));

            cbSize = new JComboBox();
            cbSource = new JComboBox();

            c.fill = GridBagConstraints.BOTH;
            c.insets = compInsets;
            c.weighty = 1.0;

            c.weightx = 0.0;
            lblSize = new JLabel(getMsg("label.size"), JLabel.TRAILING);
            lblSize.setDisplayedMnemonic(getMnemonic("label.size"));
            lblSize.setLabelFor(cbSize);
            addToGB(lblSize, this, gridbag, c);
            c.weightx = 1.0;
            c.gridwidth = GridBagConstraints.REMAINDER;
            addToGB(cbSize, this, gridbag, c);

            c.weightx = 0.0;
            c.gridwidth = 1;
            lblSource = new JLabel(getMsg("label.source"), JLabel.TRAILING);
            lblSource.setDisplayedMnemonic(getMnemonic("label.source"));
            lblSource.setLabelFor(cbSource);
            addToGB(lblSource, this, gridbag, c);
            c.gridwidth = GridBagConstraints.REMAINDER;
            addToGB(cbSource, this, gridbag, c);
        }

        private String getMediaName(String key) {
            try {
                // replace characters that would be invalid in
                // a resource key with valid characters
                String newkey = key.replace(' ', '-');
                newkey = newkey.replace('#', 'n');

                return messageRB.getString(newkey);
            } catch (java.util.MissingResourceException e) {
                return key;
            }
        }

        public void itemStateChanged(ItemEvent e) {
            Object source = e.getSource();

            if (e.getStateChange() == ItemEvent.SELECTED) {
                if (source == cbSize) {
                    int index = cbSize.getSelectedIndex();

                    if ((index >= 0) && (index < sizes.size())) {
                        if ((cbSource.getItemCount() > 1) &&
                            (cbSource.getSelectedIndex() >= 1))
                        {
                            int src = cbSource.getSelectedIndex() - 1;
                            MediaTray mt = (MediaTray)sources.get(src);
                            asCurrent.add(new SunAlternateMedia(mt));
                        }
                        asCurrent.add((MediaSizeName)sizes.get(index));
                    }
                } else if (source == cbSource) {
                    int index = cbSource.getSelectedIndex();

                    if ((index >= 1) && (index < (sources.size() + 1))) {
                       asCurrent.remove(SunAlternateMedia.class);
                       MediaTray newTray = (MediaTray)sources.get(index - 1);
                       Media m = (Media)asCurrent.get(Media.class);
                       if (m == null || m instanceof MediaTray) {
                           asCurrent.add(newTray);
                       } else if (m instanceof MediaSizeName) {
                           MediaSizeName msn = (MediaSizeName)m;
                           Media def = (Media)psCurrent.getDefaultAttributeValue(Media.class);
                           if (def instanceof MediaSizeName && def.equals(msn)) {
                               asCurrent.add(newTray);
                           } else {
                               /* Non-default paper size, so need to store tray
                                * as SunAlternateMedia
                                */
                               asCurrent.add(new SunAlternateMedia(newTray));
                           }
                       }
                    } else if (index == 0) {
                        asCurrent.remove(SunAlternateMedia.class);
                        if (cbSize.getItemCount() > 0) {
                            int size = cbSize.getSelectedIndex();
                            asCurrent.add((MediaSizeName)sizes.get(size));
                        }
                    }
                }
            // orientation affects display of margins.
                if (pnlMargins != null) {
                    pnlMargins.updateInfo();
                }
            }
        }


        /* this is ad hoc to keep things simple */
        public void addMediaListener(MarginsPanel pnl) {
            pnlMargins = pnl;
        }
        public void updateInfo() {
            Class mdCategory = Media.class;
            Class amCategory = SunAlternateMedia.class;
            boolean mediaSupported = false;

            cbSize.removeItemListener(this);
            cbSize.removeAllItems();
            cbSource.removeItemListener(this);
            cbSource.removeAllItems();
            cbSource.addItem(getMediaName("auto-select"));

            sizes.clear();
            sources.clear();

            if (psCurrent.isAttributeCategorySupported(mdCategory)) {
                mediaSupported = true;

                Object values =
                    psCurrent.getSupportedAttributeValues(mdCategory,
                                                          docFlavor,
                                                          asCurrent);

                if (values instanceof Media[]) {
                    Media[] media = (Media[])values;

                    for (int i = 0; i < media.length; i++) {
                        Media medium = media[i];

                        if (medium instanceof MediaSizeName) {
                            sizes.add(medium);
                            cbSize.addItem(getMediaName(medium.toString()));
                        } else if (medium instanceof MediaTray) {
                            sources.add(medium);
                            cbSource.addItem(getMediaName(medium.toString()));
                        }
                    }
                }
            }

            boolean msSupported = (mediaSupported && (sizes.size() > 0));
            lblSize.setEnabled(msSupported);
            cbSize.setEnabled(msSupported);

            if (isAWT) {
                cbSource.setEnabled(false);
                lblSource.setEnabled(false);
            } else {
                cbSource.setEnabled(mediaSupported);
            }

            if (mediaSupported) {

                Media medium = (Media)asCurrent.get(mdCategory);

               // initialize size selection to default
                Media defMedia = (Media)psCurrent.getDefaultAttributeValue(mdCategory);
                if (defMedia instanceof MediaSizeName) {
                    cbSize.setSelectedIndex(sizes.size() > 0 ? sizes.indexOf(defMedia) : -1);
                }

                if (medium == null ||
                    !psCurrent.isAttributeValueSupported(medium,
                                                         docFlavor, asCurrent)) {

                    medium = defMedia;

                    if (medium == null) {
                        if (sizes.size() > 0) {
                            medium = (Media)sizes.get(0);
                        }
                    }
                    if (medium != null) {
                        asCurrent.add(medium);
                    }
                }
                if (medium != null) {
                    if (medium instanceof MediaSizeName) {
                        MediaSizeName ms = (MediaSizeName)medium;
                        cbSize.setSelectedIndex(sizes.indexOf(ms));
                    } else if (medium instanceof MediaTray) {
                        MediaTray mt = (MediaTray)medium;
                        cbSource.setSelectedIndex(sources.indexOf(mt) + 1);
                    }
                } else {
                    cbSize.setSelectedIndex(sizes.size() > 0 ? 0 : -1);
                    cbSource.setSelectedIndex(0);
                }

                SunAlternateMedia alt = (SunAlternateMedia)asCurrent.get(amCategory);
                if (alt != null) {
                    Media md = alt.getMedia();
                    if (md instanceof MediaTray) {
                        MediaTray mt = (MediaTray)md;
                        cbSource.setSelectedIndex(sources.indexOf(mt) + 1);
                    }
                }

                int selIndex = cbSize.getSelectedIndex();
                if ((selIndex >= 0) && (selIndex < sizes.size())) {
                  asCurrent.add((MediaSizeName)sizes.get(selIndex));
                }

                selIndex = cbSource.getSelectedIndex();
                if ((selIndex >= 1) && (selIndex < (sources.size()+1))) {
                    MediaTray mt = (MediaTray)sources.get(selIndex-1);
                    if (medium instanceof MediaTray) {
                        asCurrent.add(mt);
                    } else {
                        asCurrent.add(new SunAlternateMedia(mt));
                    }
                }


            }
            cbSize.addItemListener(this);
            cbSource.addItemListener(this);
        }
    }

    private class OrientationPanel extends JPanel
        implements ActionListener
    {
        private final String strTitle = getMsg("border.orientation");
        private IconRadioButton rbPortrait, rbLandscape,
                                rbRevPortrait, rbRevLandscape;
        private MarginsPanel pnlMargins = null;

        public OrientationPanel() {
            super();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            setLayout(gridbag);
            setBorder(BorderFactory.createTitledBorder(strTitle));

            c.fill = GridBagConstraints.BOTH;
            c.insets = compInsets;
            c.weighty = 1.0;
            c.gridwidth = GridBagConstraints.REMAINDER;

            ButtonGroup bg = new ButtonGroup();
            rbPortrait = new IconRadioButton("radiobutton.portrait",
                                             "orientPortrait.png", true,
                                             bg, this);
            rbPortrait.addActionListener(this);
            addToGB(rbPortrait, this, gridbag, c);
            rbLandscape = new IconRadioButton("radiobutton.landscape",
                                              "orientLandscape.png", false,
                                              bg, this);
            rbLandscape.addActionListener(this);
            addToGB(rbLandscape, this, gridbag, c);
            rbRevPortrait = new IconRadioButton("radiobutton.revportrait",
                                                "orientRevPortrait.png", false,
                                                bg, this);
            rbRevPortrait.addActionListener(this);
            addToGB(rbRevPortrait, this, gridbag, c);
            rbRevLandscape = new IconRadioButton("radiobutton.revlandscape",
                                                 "orientRevLandscape.png", false,
                                                 bg, this);
            rbRevLandscape.addActionListener(this);
            addToGB(rbRevLandscape, this, gridbag, c);
        }

        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();

            if (rbPortrait.isSameAs(source)) {
                asCurrent.add(OrientationRequested.PORTRAIT);
            } else if (rbLandscape.isSameAs(source)) {
                asCurrent.add(OrientationRequested.LANDSCAPE);
            } else if (rbRevPortrait.isSameAs(source)) {
                asCurrent.add(OrientationRequested.REVERSE_PORTRAIT);
            } else if (rbRevLandscape.isSameAs(source)) {
                asCurrent.add(OrientationRequested.REVERSE_LANDSCAPE);
            }
            // orientation affects display of margins.
            if (pnlMargins != null) {
                pnlMargins.updateInfo();
            }
        }

        /* This is ad hoc to keep things simple */
        void addOrientationListener(MarginsPanel pnl) {
            pnlMargins = pnl;
        }

        public void updateInfo() {
            Class orCategory = OrientationRequested.class;
            boolean pSupported = false;
            boolean lSupported = false;
            boolean rpSupported = false;
            boolean rlSupported = false;

            if (isAWT) {
                pSupported = true;
                lSupported = true;
            } else
            if (psCurrent.isAttributeCategorySupported(orCategory)) {
                Object values =
                    psCurrent.getSupportedAttributeValues(orCategory,
                                                          docFlavor,
                                                          asCurrent);

                if (values instanceof OrientationRequested[]) {
                    OrientationRequested[] ovalues =
                        (OrientationRequested[])values;

                    for (int i = 0; i < ovalues.length; i++) {
                        OrientationRequested value = ovalues[i];

                        if (value == OrientationRequested.PORTRAIT) {
                            pSupported = true;
                        } else if (value == OrientationRequested.LANDSCAPE) {
                            lSupported = true;
                        } else if (value == OrientationRequested.REVERSE_PORTRAIT) {
                            rpSupported = true;
                        } else if (value == OrientationRequested.REVERSE_LANDSCAPE) {
                            rlSupported = true;
                        }
                    }
                }
            }


            rbPortrait.setEnabled(pSupported);
            rbLandscape.setEnabled(lSupported);
            rbRevPortrait.setEnabled(rpSupported);
            rbRevLandscape.setEnabled(rlSupported);

            OrientationRequested or = (OrientationRequested)asCurrent.get(orCategory);
            if (or == null ||
                !psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {

                or = (OrientationRequested)psCurrent.getDefaultAttributeValue(orCategory);
                // need to validate if default is not supported
                if ((or != null) &&
                   !psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
                    or = null;
                    Object values =
                        psCurrent.getSupportedAttributeValues(orCategory,
                                                              docFlavor,
                                                              asCurrent);
                    if (values instanceof OrientationRequested[]) {
                        OrientationRequested[] orValues =
                                            (OrientationRequested[])values;
                        if (orValues.length > 1) {
                            // get the first in the list
                            or = orValues[0];
                        }
                    }
                }

                if (or == null) {
                    or = OrientationRequested.PORTRAIT;
                }
                asCurrent.add(or);
            }

            if (or == OrientationRequested.PORTRAIT) {
                rbPortrait.setSelected(true);
            } else if (or == OrientationRequested.LANDSCAPE) {
                rbLandscape.setSelected(true);
            } else if (or == OrientationRequested.REVERSE_PORTRAIT) {
                rbRevPortrait.setSelected(true);
            } else { // if (or == OrientationRequested.REVERSE_LANDSCAPE)
                rbRevLandscape.setSelected(true);
            }
        }
    }



    /**
     * The "Appearance" tab.  Includes the controls for Chromaticity,
     * PrintQuality, JobPriority, JobName, and other related job attributes.
     */
    private class AppearancePanel extends JPanel {

        private ChromaticityPanel pnlChromaticity;
        private QualityPanel pnlQuality;
        private JobAttributesPanel pnlJobAttributes;
        private SidesPanel pnlSides;

        public AppearancePanel() {
            super();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            setLayout(gridbag);

            c.fill = GridBagConstraints.BOTH;
            c.insets = panelInsets;
            c.weightx = 1.0;
            c.weighty = 1.0;

            c.gridwidth = GridBagConstraints.RELATIVE;
            pnlChromaticity = new ChromaticityPanel();
            addToGB(pnlChromaticity, this, gridbag, c);

            c.gridwidth = GridBagConstraints.REMAINDER;
            pnlQuality = new QualityPanel();
            addToGB(pnlQuality, this, gridbag, c);

            c.gridwidth = 1;
            pnlSides = new SidesPanel();
            addToGB(pnlSides, this, gridbag, c);

            c.gridwidth = GridBagConstraints.REMAINDER;
            pnlJobAttributes = new JobAttributesPanel();
            addToGB(pnlJobAttributes, this, gridbag, c);

        }

        public void updateInfo() {
            pnlChromaticity.updateInfo();
            pnlQuality.updateInfo();
            pnlSides.updateInfo();
            pnlJobAttributes.updateInfo();
        }
    }

    private class ChromaticityPanel extends JPanel
        implements ActionListener
    {
        private final String strTitle = getMsg("border.chromaticity");
        private JRadioButton rbMonochrome, rbColor;

        public ChromaticityPanel() {
            super();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            setLayout(gridbag);
            setBorder(BorderFactory.createTitledBorder(strTitle));

            c.fill = GridBagConstraints.BOTH;
            c.gridwidth = GridBagConstraints.REMAINDER;
            c.weighty = 1.0;

            ButtonGroup bg = new ButtonGroup();
            rbMonochrome = createRadioButton("radiobutton.monochrome", this);
            rbMonochrome.setSelected(true);
            bg.add(rbMonochrome);
            addToGB(rbMonochrome, this, gridbag, c);
            rbColor = createRadioButton("radiobutton.color", this);
            bg.add(rbColor);
            addToGB(rbColor, this, gridbag, c);
        }

        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();

            // REMIND: use isSameAs if we move to a IconRB in the future
            if (source == rbMonochrome) {
                asCurrent.add(Chromaticity.MONOCHROME);
            } else if (source == rbColor) {
                asCurrent.add(Chromaticity.COLOR);
            }
        }

        public void updateInfo() {
            Class chCategory = Chromaticity.class;
            boolean monoSupported = false;
            boolean colorSupported = false;

            if (isAWT) {
                monoSupported = true;
                colorSupported = true;
            } else
            if (psCurrent.isAttributeCategorySupported(chCategory)) {
                Object values =
                    psCurrent.getSupportedAttributeValues(chCategory,
                                                          docFlavor,
                                                          asCurrent);

                if (values instanceof Chromaticity[]) {
                    Chromaticity[] cvalues = (Chromaticity[])values;

                    for (int i = 0; i < cvalues.length; i++) {
                        Chromaticity value = cvalues[i];

                        if (value == Chromaticity.MONOCHROME) {
                            monoSupported = true;
                        } else if (value == Chromaticity.COLOR) {
                            colorSupported = true;
                        }
                    }
                }
            }


            rbMonochrome.setEnabled(monoSupported);
            rbColor.setEnabled(colorSupported);

            Chromaticity ch = (Chromaticity)asCurrent.get(chCategory);
            if (ch == null) {
                ch = (Chromaticity)psCurrent.getDefaultAttributeValue(chCategory);
                if (ch == null) {
                    ch = Chromaticity.MONOCHROME;
                }
            }

            if (ch == Chromaticity.MONOCHROME) {
                rbMonochrome.setSelected(true);
            } else { // if (ch == Chromaticity.COLOR)
                rbColor.setSelected(true);
            }
        }
    }

    private class QualityPanel extends JPanel
        implements ActionListener
    {
        private final String strTitle = getMsg("border.quality");
        private JRadioButton rbDraft, rbNormal, rbHigh;

        public QualityPanel() {
            super();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            setLayout(gridbag);
            setBorder(BorderFactory.createTitledBorder(strTitle));

            c.fill = GridBagConstraints.BOTH;
            c.gridwidth = GridBagConstraints.REMAINDER;
            c.weighty = 1.0;

            ButtonGroup bg = new ButtonGroup();
            rbDraft = createRadioButton("radiobutton.draftq", this);
            bg.add(rbDraft);
            addToGB(rbDraft, this, gridbag, c);
            rbNormal = createRadioButton("radiobutton.normalq", this);
            rbNormal.setSelected(true);
            bg.add(rbNormal);
            addToGB(rbNormal, this, gridbag, c);
            rbHigh = createRadioButton("radiobutton.highq", this);
            bg.add(rbHigh);
            addToGB(rbHigh, this, gridbag, c);
        }

        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();

            if (source == rbDraft) {
                asCurrent.add(PrintQuality.DRAFT);
            } else if (source == rbNormal) {
                asCurrent.add(PrintQuality.NORMAL);
            } else if (source == rbHigh) {
                asCurrent.add(PrintQuality.HIGH);
            }
        }

        public void updateInfo() {
            Class pqCategory = PrintQuality.class;
            boolean draftSupported = false;
            boolean normalSupported = false;
            boolean highSupported = false;

            if (isAWT) {
                draftSupported = true;
                normalSupported = true;
                highSupported = true;
            } else
            if (psCurrent.isAttributeCategorySupported(pqCategory)) {
                Object values =
                    psCurrent.getSupportedAttributeValues(pqCategory,
                                                          docFlavor,
                                                          asCurrent);

                if (values instanceof PrintQuality[]) {
                    PrintQuality[] qvalues = (PrintQuality[])values;

                    for (int i = 0; i < qvalues.length; i++) {
                        PrintQuality value = qvalues[i];

                        if (value == PrintQuality.DRAFT) {
                            draftSupported = true;
                        } else if (value == PrintQuality.NORMAL) {
                            normalSupported = true;
                        } else if (value == PrintQuality.HIGH) {
                            highSupported = true;
                        }
                    }
                }
            }

            rbDraft.setEnabled(draftSupported);
            rbNormal.setEnabled(normalSupported);
            rbHigh.setEnabled(highSupported);

            PrintQuality pq = (PrintQuality)asCurrent.get(pqCategory);
            if (pq == null) {
                pq = (PrintQuality)psCurrent.getDefaultAttributeValue(pqCategory);
                if (pq == null) {
                    pq = PrintQuality.NORMAL;
                }
            }

            if (pq == PrintQuality.DRAFT) {
                rbDraft.setSelected(true);
            } else if (pq == PrintQuality.NORMAL) {
                rbNormal.setSelected(true);
            } else { // if (pq == PrintQuality.HIGH)
                rbHigh.setSelected(true);
            }
        }


    }
    private class SidesPanel extends JPanel
        implements ActionListener
    {
        private final String strTitle = getMsg("border.sides");
        private IconRadioButton rbOneSide, rbTumble, rbDuplex;

        public SidesPanel() {
            super();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            setLayout(gridbag);
            setBorder(BorderFactory.createTitledBorder(strTitle));

            c.fill = GridBagConstraints.BOTH;
            c.insets = compInsets;
            c.weighty = 1.0;
            c.gridwidth = GridBagConstraints.REMAINDER;

            ButtonGroup bg = new ButtonGroup();
            rbOneSide = new IconRadioButton("radiobutton.oneside",
                                            "oneside.png", true,
                                            bg, this);
            rbOneSide.addActionListener(this);
            addToGB(rbOneSide, this, gridbag, c);
            rbTumble = new IconRadioButton("radiobutton.tumble",
                                           "tumble.png", false,
                                           bg, this);
            rbTumble.addActionListener(this);
            addToGB(rbTumble, this, gridbag, c);
            rbDuplex = new IconRadioButton("radiobutton.duplex",
                                           "duplex.png", false,
                                           bg, this);
            rbDuplex.addActionListener(this);
            c.gridwidth = GridBagConstraints.REMAINDER;
            addToGB(rbDuplex, this, gridbag, c);
        }

        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();

            if (rbOneSide.isSameAs(source)) {
                asCurrent.add(Sides.ONE_SIDED);
            } else if (rbTumble.isSameAs(source)) {
                asCurrent.add(Sides.TUMBLE);
            } else if (rbDuplex.isSameAs(source)) {
                asCurrent.add(Sides.DUPLEX);
            }
        }

        public void updateInfo() {
            Class sdCategory = Sides.class;
            boolean osSupported = false;
            boolean tSupported = false;
            boolean dSupported = false;

            if (psCurrent.isAttributeCategorySupported(sdCategory)) {
                Object values =
                    psCurrent.getSupportedAttributeValues(sdCategory,
                                                          docFlavor,
                                                          asCurrent);

                if (values instanceof Sides[]) {
                    Sides[] svalues = (Sides[])values;

                    for (int i = 0; i < svalues.length; i++) {
                        Sides value = svalues[i];

                        if (value == Sides.ONE_SIDED) {
                            osSupported = true;
                        } else if (value == Sides.TUMBLE) {
                            tSupported = true;
                        } else if (value == Sides.DUPLEX) {
                            dSupported = true;
                        }
                    }
                }
            }
            rbOneSide.setEnabled(osSupported);
            rbTumble.setEnabled(tSupported);
            rbDuplex.setEnabled(dSupported);

            Sides sd = (Sides)asCurrent.get(sdCategory);
            if (sd == null) {
                sd = (Sides)psCurrent.getDefaultAttributeValue(sdCategory);
                if (sd == null) {
                    sd = Sides.ONE_SIDED;
                }
            }

            if (sd == Sides.ONE_SIDED) {
                rbOneSide.setSelected(true);
            } else if (sd == Sides.TUMBLE) {
                rbTumble.setSelected(true);
            } else { // if (sd == Sides.DUPLEX)
                rbDuplex.setSelected(true);
            }
        }
    }



    private class JobAttributesPanel extends JPanel
        implements ActionListener, ChangeListener, FocusListener
    {
        private final String strTitle = getMsg("border.jobattributes");
        private JLabel lblPriority, lblJobName, lblUserName;
        private JSpinner spinPriority;
        private SpinnerNumberModel snModel;
        private JCheckBox cbJobSheets;
        private JTextField tfJobName, tfUserName;

        public JobAttributesPanel() {
            super();

            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            setLayout(gridbag);
            setBorder(BorderFactory.createTitledBorder(strTitle));

            c.fill = GridBagConstraints.NONE;
            c.insets = compInsets;
            c.weighty = 1.0;

            cbJobSheets = createCheckBox("checkbox.jobsheets", this);
            c.anchor = GridBagConstraints.LINE_START;
            addToGB(cbJobSheets, this, gridbag, c);

            JPanel pnlTop = new JPanel();
            lblPriority = new JLabel(getMsg("label.priority"), JLabel.TRAILING);
            lblPriority.setDisplayedMnemonic(getMnemonic("label.priority"));

            pnlTop.add(lblPriority);
            snModel = new SpinnerNumberModel(1, 1, 100, 1);
            spinPriority = new JSpinner(snModel);
            lblPriority.setLabelFor(spinPriority);
            // REMIND
            ((JSpinner.NumberEditor)spinPriority.getEditor()).getTextField().setColumns(3);
            spinPriority.addChangeListener(this);
            pnlTop.add(spinPriority);
            c.anchor = GridBagConstraints.LINE_END;
            c.gridwidth = GridBagConstraints.REMAINDER;
            pnlTop.getAccessibleContext().setAccessibleName(
                                       getMsg("label.priority"));
            addToGB(pnlTop, this, gridbag, c);

            c.fill = GridBagConstraints.HORIZONTAL;
            c.anchor = GridBagConstraints.CENTER;
            c.weightx = 0.0;
            c.gridwidth = 1;
            char jmnemonic = getMnemonic("label.jobname");
            lblJobName = new JLabel(getMsg("label.jobname"), JLabel.TRAILING);
            lblJobName.setDisplayedMnemonic(jmnemonic);
            addToGB(lblJobName, this, gridbag, c);
            c.weightx = 1.0;
            c.gridwidth = GridBagConstraints.REMAINDER;
            tfJobName = new JTextField();
            lblJobName.setLabelFor(tfJobName);
            tfJobName.addFocusListener(this);
            tfJobName.setFocusAccelerator(jmnemonic);
            tfJobName.getAccessibleContext().setAccessibleName(
                                             getMsg("label.jobname"));
            addToGB(tfJobName, this, gridbag, c);

            c.weightx = 0.0;
            c.gridwidth = 1;
            char umnemonic = getMnemonic("label.username");
            lblUserName = new JLabel(getMsg("label.username"), JLabel.TRAILING);
            lblUserName.setDisplayedMnemonic(umnemonic);
            addToGB(lblUserName, this, gridbag, c);
            c.gridwidth = GridBagConstraints.REMAINDER;
            tfUserName = new JTextField();
            lblUserName.setLabelFor(tfUserName);
            tfUserName.addFocusListener(this);
            tfUserName.setFocusAccelerator(umnemonic);
            tfUserName.getAccessibleContext().setAccessibleName(
                                             getMsg("label.username"));
            addToGB(tfUserName, this, gridbag, c);
        }

        public void actionPerformed(ActionEvent e) {
            if (cbJobSheets.isSelected()) {
                asCurrent.add(JobSheets.STANDARD);
            } else {
                asCurrent.add(JobSheets.NONE);
            }
        }

        public void stateChanged(ChangeEvent e) {
            asCurrent.add(new JobPriority(snModel.getNumber().intValue()));
        }

        public void focusLost(FocusEvent e) {
            Object source = e.getSource();

            if (source == tfJobName) {
                asCurrent.add(new JobName(tfJobName.getText(),
                                          Locale.getDefault()));
            } else if (source == tfUserName) {
                asCurrent.add(new RequestingUserName(tfUserName.getText(),
                                                     Locale.getDefault()));
            }
        }

        public void focusGained(FocusEvent e) {}

        public void updateInfo() {
            Class jsCategory = JobSheets.class;
            Class jpCategory = JobPriority.class;
            Class jnCategory = JobName.class;
            Class unCategory = RequestingUserName.class;
            boolean jsSupported = false;
            boolean jpSupported = false;
            boolean jnSupported = false;
            boolean unSupported = false;

            // setup JobSheets checkbox
            if (psCurrent.isAttributeCategorySupported(jsCategory)) {
                jsSupported = true;
            }
            JobSheets js = (JobSheets)asCurrent.get(jsCategory);
            if (js == null) {
                js = (JobSheets)psCurrent.getDefaultAttributeValue(jsCategory);
                if (js == null) {
                    js = JobSheets.NONE;
                }
            }
            cbJobSheets.setSelected(js != JobSheets.NONE);
            cbJobSheets.setEnabled(jsSupported);

            // setup JobPriority spinner
            if (!isAWT && psCurrent.isAttributeCategorySupported(jpCategory)) {
                jpSupported = true;
            }
            JobPriority jp = (JobPriority)asCurrent.get(jpCategory);
            if (jp == null) {
                jp = (JobPriority)psCurrent.getDefaultAttributeValue(jpCategory);
                if (jp == null) {
                    jp = new JobPriority(1);
                }
            }
            int value = jp.getValue();
            if ((value < 1) || (value > 100)) {
                value = 1;
            }
            snModel.setValue(new Integer(value));
            lblPriority.setEnabled(jpSupported);
            spinPriority.setEnabled(jpSupported);

            // setup JobName text field
            if (psCurrent.isAttributeCategorySupported(jnCategory)) {
                jnSupported = true;
            }
            JobName jn = (JobName)asCurrent.get(jnCategory);
            if (jn == null) {
                jn = (JobName)psCurrent.getDefaultAttributeValue(jnCategory);
                if (jn == null) {
                    jn = new JobName("", Locale.getDefault());
                }
            }
            tfJobName.setText(jn.getValue());
            tfJobName.setEnabled(jnSupported);
            lblJobName.setEnabled(jnSupported);

            // setup RequestingUserName text field
            if (!isAWT && psCurrent.isAttributeCategorySupported(unCategory)) {
                unSupported = true;
            }
            RequestingUserName un = (RequestingUserName)asCurrent.get(unCategory);
            if (un == null) {
                un = (RequestingUserName)psCurrent.getDefaultAttributeValue(unCategory);
                if (un == null) {
                    un = new RequestingUserName("", Locale.getDefault());
                }
            }
            tfUserName.setText(un.getValue());
            tfUserName.setEnabled(unSupported);
            lblUserName.setEnabled(unSupported);
        }
    }




    /**
     * A special widget that groups a JRadioButton with an associated icon,
     * placed to the left of the radio button.
     */
    private class IconRadioButton extends JPanel {

        private JRadioButton rb;
        private JLabel lbl;

        public IconRadioButton(String key, String img, boolean selected,
                               ButtonGroup bg, ActionListener al)
        {
            super(new FlowLayout(FlowLayout.LEADING));
            final URL imgURL = getImageResource(img);
            Icon icon = (Icon)java.security.AccessController.doPrivileged(
                                 new java.security.PrivilegedAction() {
                public Object run() {
                    Icon icon = new ImageIcon(imgURL);
                    return icon;
                }
            });
            lbl = new JLabel(icon);
            add(lbl);

            rb = createRadioButton(key, al);
            rb.setSelected(selected);
            addToBG(rb, this, bg);
        }

        public void addActionListener(ActionListener al) {
            rb.addActionListener(al);
        }

        public boolean isSameAs(Object source) {
            return (rb == source);
        }

        public void setEnabled(boolean enabled) {
            rb.setEnabled(enabled);
            lbl.setEnabled(enabled);
        }

        public boolean isSelected() {
            return rb.isSelected();
        }

        public void setSelected(boolean selected) {
            rb.setSelected(selected);
        }
    }

    /**
     * Similar in functionality to the default JFileChooser, except this
     * chooser will pop up a "Do you want to overwrite..." dialog if the
     * user selects a file that already exists.
     */
    private class ValidatingFileChooser extends JFileChooser {
        public void approveSelection() {
            File selected = getSelectedFile();
            boolean exists;

            try {
                exists = selected.exists();
            } catch (SecurityException e) {
                exists = false;
            }

            if (exists) {
                int val;
                val = JOptionPane.showConfirmDialog(this,
                                                    getMsg("dialog.overwrite"),
                                                    getMsg("dialog.owtitle"),
                                                    JOptionPane.YES_NO_OPTION);
                if (val != JOptionPane.YES_OPTION) {
                    return;
                }
            }

            try {
                if (selected.createNewFile()) {
                    selected.delete();
                }
            }  catch (IOException ioe) {
                JOptionPane.showMessageDialog(this,
                                   getMsg("dialog.writeerror")+" "+selected,
                                   getMsg("dialog.owtitle"),
                                   JOptionPane.WARNING_MESSAGE);
                return;
            } catch (SecurityException se) {
                //There is already file read/write access so at this point
                // only delete access is denied.  Just ignore it because in
                // most cases the file created in createNewFile gets
                // overwritten anyway.
            }
            File pFile = selected.getParentFile();
            if ((selected.exists() &&
                      (!selected.isFile() || !selected.canWrite())) ||
                     ((pFile != null) &&
                      (!pFile.exists() || (pFile.exists() && !pFile.canWrite())))) {
                JOptionPane.showMessageDialog(this,
                                   getMsg("dialog.writeerror")+" "+selected,
                                   getMsg("dialog.owtitle"),
                                   JOptionPane.WARNING_MESSAGE);
                return;
            }

            super.approveSelection();
        }
    }
}
