/*
 * Copyright (c) 2000, 2013, 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.awt.print.PrinterJob;
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;
import java.lang.reflect.Field;


/**
 * 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.setDialogType(JFileChooser.SAVE_DIALOG);
        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 removeMnemonics(messageRB.getString(key));
        } catch (java.util.MissingResourceException e) {
            throw new Error("Fatal: Resource for ServiceUI is broken; " +
                            "there is no " + key + " key in resource");
        }
    }

    private static String removeMnemonics(String s) {
        int i = s.indexOf('&');
        int len = s.length();
        if (i < 0 || i == (len - 1)) {
            return s;
        }
        int j = s.indexOf('&', i+1);
        if (j == i+1) {
            if (j+1 == len) {
                return s.substring(0, i+1);  // string ends with &&
            } else {
                return s.substring(0, i+1) + removeMnemonics(s.substring(j+1));
            }
        }
        // ok first & not double &&
        if (i == 0) {
            return removeMnemonics(s.substring(1));
        } else {
            return (s.substring(0, i) + removeMnemonics(s.substring(i+1)));
        }
    }


    /**
     * Returns mnemonic character from resource
     */
    private static char getMnemonic(String key) {
        String str = messageRB.getString(key).replace("&&", "");
        int index = str.indexOf('&');
        if (0 <= index && index < str.length() - 1) {
            char c = str.charAt(index + 1);
            return Character.toUpperCase(c);
        } else {
            return (char)0;
        }
    }

    /**
     * Returns the mnemonic as a KeyEvent.VK constant from the resource.
     */
    static Class _keyEventClazz = null;
    private static int getVKMnemonic(String key) {
        String s = String.valueOf(getMnemonic(key));
        if ( s == null || s.length() != 1) {
            return 0;
        }
        String vkString = "VK_" + s.toUpperCase();

        try {
            if (_keyEventClazz == null) {
                _keyEventClazz= Class.forName("java.awt.event.KeyEvent",
                                 true, (ServiceDialog.class).getClassLoader());
            }
            Field field = _keyEventClazz.getDeclaredField(vkString);
            int value = field.getInt(null);
            return value;
        } catch (Exception e) {
        }
        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 {
                        DocumentPropertiesUI docPropertiesUI = null;
                        try {
                            docPropertiesUI =
                                (DocumentPropertiesUI)uiFactory.getUI
                                (DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE,
                                 DocumentPropertiesUI.DOCPROPERTIESCLASSNAME);
                        } catch (Exception ex) {
                        }
                        if (docPropertiesUI != null) {
                            PrinterJobWrapper wrapper = (PrinterJobWrapper)
                                asCurrent.get(PrinterJobWrapper.class);
                            if (wrapper == null) {
                                return; // should not happen, defensive only.
                            }
                            PrinterJob job = wrapper.getPrinterJob();
                            if (job == null) {
                                return;  // should not happen, defensive only.
                            }
                            PrintRequestAttributeSet newAttrs =
                               docPropertiesUI.showDocumentProperties
                               (job, ServiceDialog.this, psCurrent, asCurrent);
                            if (newAttrs != null) {
                                asCurrent.addAll(newAttrs);
                                updatePanels();
                            }
                        }
                    }
                }
            }
        }

        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();
        }
    }
}
