/* PrinterDialog.java --
   Copyright (C) 2006, 2010  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.javax.print;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.ArrayList;
import java.util.ResourceBundle;

import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.JobPriority;
import javax.print.attribute.standard.JobSheets;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.PrintQuality;
import javax.print.attribute.standard.PrinterInfo;
import javax.print.attribute.standard.PrinterIsAcceptingJobs;
import javax.print.attribute.standard.PrinterMakeAndModel;
import javax.print.attribute.standard.PrinterState;
import javax.print.attribute.standard.RequestingUserName;
import javax.print.attribute.standard.SheetCollate;
import javax.print.attribute.standard.Sides;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * Implementation of the PrinterDialog used by
 * {@link javax.print.ServiceUI} for visual selection
 * of print services and its attributes.
 *
 * @author Wolfgang Baer (WBaer@gmx.de)
 */
public final class PrinterDialog extends JDialog implements ActionListener
{

  /**
   * The General Panel used in the printing dialog.
   * @author Wolfgang Baer (WBaer@gmx.de)
   */
  final class GeneralPanel extends JPanel
  {
    /**
     * Handles the copies attribute.
     * @author Wolfgang Baer (WBaer@gmx.de)
     */
    final class CopiesAndSorted extends JPanel
      implements ChangeListener, ActionListener
    {
      private JCheckBox sort;
      private JSpinner copies;
      private JLabel copies_lb;
      private SpinnerNumberModel copiesModel;

      CopiesAndSorted()
      {
        copies_lb = new JLabel(getLocalizedString("lb.copies"));
        sort = new JCheckBox(getLocalizedString("cb.sort"));
        sort.addActionListener(this);

        copiesModel = new SpinnerNumberModel(1, 1, 9999, 1);
        copies = new JSpinner(copiesModel);
        copies.addChangeListener(this);

        GridBagLayout layout = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;
        c.insets = new Insets(5, 5, 5, 5);

        setLayout(layout);
        setBorder(new TitledBorder(getLocalizedString("title.copies")));

        c.anchor = GridBagConstraints.WEST;

        c.gridx = 0;
        c.gridy = 0;
        add(copies_lb, c);

        c.gridx = 1;
        c.gridy = 0;
        add(copies, c);

        c.gridx = 0;
        c.gridy = 1;
        add(sort, c);
      }

      // copies jspinner state
      public void stateChanged(ChangeEvent event)
      {
        int value = ((Integer) copies.getValue()).intValue();
        atts.add(new Copies(value));

        if (value > 1 && categorySupported(SheetCollate.class))
          sort.setEnabled(true);
        else
          sort.setEnabled(false);
      }

      // sorted checkbox state
      public void actionPerformed(ActionEvent event)
      {
        if (sort.isSelected())
          atts.add(SheetCollate.COLLATED);
      }

      /**
       * Called to update for new selected
       * print service. Tests if currently
       * selected attributes are supported.
       */
      void updateForSelectedService()
      {
        if (categorySupported(Copies.class))
          {
            copies.setEnabled(true);
            copies_lb.setEnabled(true);

            Copies copies = (Copies) attribute(Copies.class);
            if (copies != null)
              copiesModel.setValue(new Integer(copies.getValue()));

            if (((Integer)copiesModel.getValue()).intValue() > 1
                && categorySupported(SheetCollate.class))
              {
                sort.setEnabled(true);
                Attribute collate = attribute(SheetCollate.class);
                if (collate != null && collate.equals(SheetCollate.COLLATED))
                  sort.setSelected(true);
              }
            else
              sort.setEnabled(false);
          }
        else
          {
            copies.setEnabled(false);
            copies_lb.setEnabled(false);
          }
      }
    }

    /**
     * Handles the print ranges attribute.
     * @author Wolfgang Baer (WBaer@gmx.de)
     */
    final class PrintRange extends JPanel
      implements ActionListener, FocusListener
    {
      private JLabel to;
      private JRadioButton all_rb, pages_rb;
      private JTextField from_tf, to_tf;

      PrintRange()
      {
        to = new JLabel(getLocalizedString("lb.to"));
        to.setEnabled(false);

        all_rb = new JRadioButton(getLocalizedString("rbt.all"));
        all_rb.setSelected(true);
        all_rb.setActionCommand("ALL");
        all_rb.addActionListener(this);
        pages_rb = new JRadioButton(getLocalizedString("rbt.pages"));
        pages_rb.setActionCommand("PAGES");
        pages_rb.setEnabled(false);
        pages_rb.addActionListener(this);

        ButtonGroup group = new ButtonGroup();
        group.add(all_rb);
        group.add(pages_rb);

        from_tf = new JTextField("1", 4);
        from_tf.setEnabled(false);
        from_tf.addFocusListener(this);
        to_tf = new JTextField("1", 4);
        to_tf.setEnabled(false);
        to_tf.addFocusListener(this);

        GridBagLayout layout = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;

        setLayout(layout);
        setBorder(new TitledBorder(getLocalizedString("title.printrange")));

        c.insets = new Insets(15, 5, 5, 5);
        c.gridx = 0;
        c.gridy = 0;
        add(all_rb, c);

        c.insets = new Insets(5, 5, 15, 5);
        c.gridx = 0;
        c.gridy = 1;
        add(pages_rb, c);

        c.gridx = 1;
        c.gridy = 1;
        add(from_tf, c);

        c.gridx = 2;
        c.gridy = 1;
        add(to, c);

        c.insets = new Insets(5, 5, 15, 15);
        c.gridx = 3;
        c.gridy = 1;
        add(to_tf, c);
      }

      // focus pagerange
      public void focusGained(FocusEvent event)
      {
        updatePageRanges();
      }

      public void focusLost(FocusEvent event)
      {
        updatePageRanges();
      }

      // updates the range after user changed it
      private void updatePageRanges()
      {
        int lower = Integer.parseInt(from_tf.getText());
        int upper = Integer.parseInt(to_tf.getText());

        if (lower > upper)
          {
            upper = lower;
            to_tf.setText("" + lower);
          }

        PageRanges range = new PageRanges(lower, upper);
        atts.add(range);
      }

      // page range change
      public void actionPerformed(ActionEvent e)
      {
        // if ALL is selected we must use a full-range object
        if (e.getActionCommand().equals("ALL"))
          {
            from_tf.setEnabled(false);
            to.setEnabled(false);
            to_tf.setEnabled(false);

            atts.add(new PageRanges(1, Integer.MAX_VALUE));
          }
        else
          {
            from_tf.setEnabled(true);
            to.setEnabled(true);
            to_tf.setEnabled(true);
            all_rb.setSelected(false);
          }
      }

      /**
       * Called to update for new selected
       * print service. Tests if currently
       * selected attributes are supported.
       */
      void updateForSelectedService()
      {
        if (categorySupported(PageRanges.class))
          {
            pages_rb.setEnabled(true);
            PageRanges range = (PageRanges) attribute(PageRanges.class);
            if (range != null)
              {
                from_tf.setEnabled(true);
                to.setEnabled(true);
                to_tf.setEnabled(true);
                all_rb.setSelected(false);
                pages_rb.setSelected(true);

                int[][] members = range.getMembers();
                // Although passed in attributes may contain more than one
                // range we only take the first one
                from_tf.setText("" + members[0][0]);
                to_tf.setText("" + members[0][1]);
              }
          }
        else
          {
            from_tf.setEnabled(false);
            to.setEnabled(false);
            to_tf.setEnabled(false);
            all_rb.setSelected(true);
          }
       }
    }

    /**
     * Handles the selection of the print services
     * and its location and description attributes.
     * @author Wolfgang Baer (WBaer@gmx.de)
     */
    final class PrintServices extends JPanel
      implements ActionListener
    {
      private JLabel name, status, typ, info;
      private JLabel statusValue, typValue, infoValue;
      private JButton attributes;
      private JComboBox services_cob;
      private JCheckBox fileRedirection_cb;

      PrintServices()
      {
        name = new JLabel(getLocalizedString("lb.name"));
        status = new JLabel(getLocalizedString("lb.status"));
        typ = new JLabel(getLocalizedString("lb.typ"));
        info = new JLabel(getLocalizedString("lb.info"));
        typValue = new JLabel();
        infoValue = new JLabel();
        statusValue = new JLabel();

        attributes = new JButton(getLocalizedString("bt.attributes"));
        attributes.setEnabled(false);
        attributes.setActionCommand("ATTRIBUTES");
        attributes.addActionListener(this);

        services_cob = new JComboBox(getPrintServices());
        services_cob.setActionCommand("SERVICE");
        services_cob.addActionListener(this);

        fileRedirection_cb = new JCheckBox(getLocalizedString("cb.output"));
        fileRedirection_cb.setEnabled(false);

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

        setLayout(layout);
        setBorder(new TitledBorder(getLocalizedString("title.printservice")));

        c.insets = new Insets(5, 5, 5, 5);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 0;
        c.gridy = 0;
        add(name, c);

        c.gridx = 0;
        c.gridy = 1;
        add(status, c);

        c.gridx = 0;
        c.gridy = 2;
        add(typ, c);

        c.gridx = 0;
        c.gridy = 3;
        add(info, c);

        c.gridx = 2;
        c.gridy = 3;
        c.weightx = 1;
        add(fileRedirection_cb, c);

        c.anchor = GridBagConstraints.LINE_START;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 0;
        c.weightx = 1.5;
        add(services_cob, c);

        c.gridx = 1;
        c.gridy = 1;
        c.gridwidth = 2;
        c.weightx = 1;
        add(statusValue, c);

        c.gridx = 1;
        c.gridy = 2;
        c.gridwidth = 2;
        c.weightx = 1;
        add(typValue, c);

        c.gridx = 1;
        c.gridy = 3;
        c.gridwidth = 2;
        c.weightx = 1;
        add(infoValue, c);

        c.gridx = 2;
        c.gridy = 0;
        c.weightx = 1.5;
        add(attributes, c);
      }

      public void actionPerformed(ActionEvent e)
      {
        if (e.getActionCommand().equals("SERVICE"))
          {
            setSelectedPrintService((PrintService) services_cob.getSelectedItem());
            updateAll();
          }
        else if (e.getActionCommand().equals("ATTRIBUTES"))
          {
            // TODO LowPriority-Enhancement: As tests have shown this button
            // is even gray and not enabled under Windows - Its a good place
            // to provide a classpath specific browsing dialog for all
            // attributes not in the default printing dialog.
          }
      }

      /**
       * Called to update for new selected
       * print service. Tests if currently
       * selected attributes are supported.
       */
      void updateForSelectedService()
      {
        PrinterMakeAndModel att1 =
          getSelectedPrintService().getAttribute(PrinterMakeAndModel.class);
        typValue.setText(att1 == null ? "" : att1.getValue());

        PrinterInfo att2 =
          getSelectedPrintService().getAttribute(PrinterInfo.class);
        infoValue.setText(att2 == null ? "" : att2.getValue());

        PrinterIsAcceptingJobs att3 =
          getSelectedPrintService().getAttribute(PrinterIsAcceptingJobs.class);
        PrinterState att4 =
          getSelectedPrintService().getAttribute(PrinterState.class);

        String status = att4.toString();
        if (att3 == PrinterIsAcceptingJobs.ACCEPTING_JOBS)
          status += " - " + getLocalizedString("lb.acceptingjobs");
        else if (att3 == PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS)
          status += " - " + getLocalizedString("lb.notacceptingjobs");

        statusValue.setText(status);

        if (categorySupported(Destination.class))
          {
            fileRedirection_cb.setEnabled(false);
          }
      }

    }

    private PrintServices printserv_panel;
    private PrintRange printrange_panel;
    private CopiesAndSorted copies;

    /**
     * Constructs the General Panel.
     */
    public GeneralPanel()
    {
      setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

      printserv_panel = new PrintServices();
      printrange_panel = new PrintRange();
      copies = new CopiesAndSorted();

      JPanel layout_panel = new JPanel();
      layout_panel.setLayout(new BoxLayout(layout_panel, BoxLayout.LINE_AXIS));
      layout_panel.add(printrange_panel);
      layout_panel.add(Box.createRigidArea(new Dimension(10, 0)));
      layout_panel.add(copies);

      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      add(printserv_panel);
      add(Box.createRigidArea(new Dimension(0, 12)));
      add(layout_panel);
    }

    /**
     * Calls update on all internal panels to adjust
     * for a new selected print service.
     */
    void update()
    {
      printserv_panel.updateForSelectedService();
      printrange_panel.updateForSelectedService();
      copies.updateForSelectedService();
    }
  }

  /**
   * The Page setup Panel.
   * @author Wolfgang Baer (WBaer@gmx.de)
   */
  final class PageSetupPanel extends JPanel
  {
    /**
     * Handles the orientation attribute.
     * @author Wolfgang Baer (WBaer@gmx.de)
     */
    final class Orientation extends JPanel implements ActionListener
    {
      private JRadioButton portrait, landscape, rev_portrait, rev_landscape;

      Orientation()
      {
        portrait = new JRadioButton(getLocalizedString("rbt.portrait"));
        portrait.addActionListener(this);
        landscape = new JRadioButton(getLocalizedString("rbt.landscape"));
        landscape.addActionListener(this);
        rev_portrait = new JRadioButton(getLocalizedString("rbt.revportrait"));
        rev_portrait.addActionListener(this);
        rev_landscape = new JRadioButton(getLocalizedString("rbt.revlandscape"));
        rev_landscape.addActionListener(this);

        ButtonGroup group = new ButtonGroup();
        group.add(portrait);
        group.add(landscape);
        group.add(rev_portrait);
        group.add(rev_landscape);

        GridBagLayout layout = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;

        setLayout(layout);
        setBorder(new TitledBorder(getLocalizedString("title.orientation")));

        c.insets = new Insets(5, 5, 5, 5);
        c.gridx = 0;
        c.gridy = 0;
        add(portrait, c);

        c.gridx = 0;
        c.gridy = 1;
        add(landscape, c);

        c.gridx = 0;
        c.gridy = 2;
        add(rev_portrait, c);

        c.gridx = 0;
        c.gridy = 3;
        add(rev_landscape, c);
      }

      // event handling orientation
      public void actionPerformed(ActionEvent e)
      {
        if (e.getSource() == portrait)
          atts.add(OrientationRequested.PORTRAIT);
        else if (e.getSource() == landscape)
          atts.add(OrientationRequested.LANDSCAPE);
        else if (e.getSource() == rev_portrait)
          atts.add(OrientationRequested.REVERSE_PORTRAIT);
        else
          atts.add(OrientationRequested.REVERSE_LANDSCAPE);
      }

      /**
       * Called to update for new selected
       * print service. Tests if currently
       * selected attributes are supported.
       */
      void updateForSelectedService()
      {
        if (categorySupported(OrientationRequested.class))
          {
            portrait.setEnabled(true);
            landscape.setEnabled(true);
            rev_landscape.setEnabled(true);
            rev_portrait.setEnabled(true);

            Attribute orientation = attribute(OrientationRequested.class);
            if (orientation != null)
              {
                if (orientation.equals(OrientationRequested.LANDSCAPE))
                  landscape.setSelected(true);
                else if (orientation.equals(OrientationRequested.PORTRAIT))
                  portrait.setSelected(true);
                else if (orientation.equals(OrientationRequested.REVERSE_PORTRAIT))
                  rev_portrait.setSelected(true);
                else
                  rev_landscape.setSelected(true);
              }
            else
              {
                Object defaultValue = defaultValue(OrientationRequested.class);
                if (defaultValue.equals(OrientationRequested.LANDSCAPE))
                  landscape.setSelected(true);
                else if (defaultValue.equals(OrientationRequested.PORTRAIT))
                  portrait.setSelected(true);
                else if (defaultValue.equals(OrientationRequested.REVERSE_PORTRAIT))
                  rev_portrait.setSelected(true);
                else
                  rev_landscape.setSelected(true);
              }
          }
        else
          {
            portrait.setEnabled(false);
            landscape.setEnabled(false);
            rev_landscape.setEnabled(false);
            rev_portrait.setEnabled(false);
          }
      }
    }

    /**
     * Handles the media attribute.
     * @author Wolfgang Baer (WBaer@gmx.de)
     */
    final class MediaTypes extends JPanel implements ActionListener
    {
      private JLabel size_lb, source_lb;
      private JComboBox size, source;

      MediaTypes()
      {
        size_lb = new JLabel(getLocalizedString("lb.size"));
        source_lb = new JLabel(getLocalizedString("lb.source"));

        size = new JComboBox();
        size.setEditable(false);
        size.addActionListener(this);
        source = new JComboBox();
        source.setEditable(false);
        size.addActionListener(this);

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

        setLayout(layout);
        setBorder(new TitledBorder(getLocalizedString("title.medias")));

        c.insets = new Insets(5, 5, 5, 5);
        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 0;
        c.gridy = 0;
        add(size_lb, c);

        c.gridx = 0;
        c.gridy = 1;
        add(source_lb, c);

        c.anchor = GridBagConstraints.LINE_START;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 0;
        c.weightx = 1.5;
        add(size, c);

        c.gridx = 1;
        c.gridy = 1;
        c.weightx = 1.5;
        add(source, c);
      }

      public void actionPerformed(ActionEvent event)
      {
        if (event.getSource() == size)
          {
            Object obj = size.getSelectedItem();
            if (obj instanceof Media)
              atts.add((Media) obj);
          }

        // we ignore source events currently
        // as only the automatic selection is used.
      }

      /**
       * Called to update for new selected
       * print service. Tests if currently
       * selected attributes are supported.
       */
      void updateForSelectedService()
      {
        if (categorySupported(Media.class))
          {
            Media[] medias = (Media[]) getSelectedPrintService()
              .getSupportedAttributeValues(Media.class, flavor, null);

            size.removeAllItems();
            if (medias.length == 0)
              size.addItem(getLocalizedString("lb.automatically"));
            else
              for (int i=0; i < medias.length; i++)
                size.addItem(medias[i]);

            Media media = (Media) attribute(Media.class);
            if (media != null)
              size.setSelectedItem(media);

            // this is currently ignored
            source.removeAllItems();
            source.addItem(getLocalizedString("lb.automatically"));
          }
        else
          {
            size.removeAllItems();
            source.removeAllItems();

            size.addItem(getLocalizedString("lb.automatically"));
            source.addItem(getLocalizedString("lb.automatically"));
          }
       }
    }

    /**
     * Handles the media printable area attribute.
     * @author Wolfgang Baer (WBaer@gmx.de)
     */
    final class Margins extends JPanel implements FocusListener
    {
      private JLabel left, right, top, bottom;
      private JTextField left_tf, right_tf, top_tf, bottom_tf;

      Margins()
      {
        left = new JLabel(getLocalizedString("lb.left"));
        right = new JLabel(getLocalizedString("lb.right"));
        top = new JLabel(getLocalizedString("lb.top"));
        bottom = new JLabel(getLocalizedString("lb.bottom"));

        left_tf = new JTextField(7);
        left_tf.addFocusListener(this);
        right_tf = new JTextField(7);
        right_tf.addFocusListener(this);
        top_tf = new JTextField(7);
        top_tf.addFocusListener(this);
        bottom_tf = new JTextField(7);
        bottom_tf.addFocusListener(this);

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

        setLayout(layout);
        setBorder(new TitledBorder(getLocalizedString("title.margins")));

        c.insets = new Insets(5, 5, 5, 5);
        c.gridx = 0;
        c.gridy = 0;
        add(left, c);

        c.gridx = 1;
        c.gridy = 0;
        add(right, c);

        c.insets = new Insets(5, 5, 5, 5);
        c.gridx = 0;
        c.gridy = 1;
        add(left_tf, c);

        c.gridx = 1;
        c.gridy = 1;
        add(right_tf, c);

        c.insets = new Insets(10, 5, 5, 5);
        c.gridx = 0;
        c.gridy = 2;
        add(top, c);

        c.gridx = 1;
        c.gridy = 2;
        add(bottom, c);

        c.insets = new Insets(0, 5, 5, 5);
        c.gridx = 0;
        c.gridy = 3;
        add(top_tf, c);

        c.gridx = 1;
        c.gridy = 3;
        add(bottom_tf, c);
      }

      public void focusGained(FocusEvent event)
      {
        updateMargins();
      }

      public void focusLost(FocusEvent event)
      {
        updateMargins();
      }

      // updates the margins after user changed it
      private void updateMargins()
      {
        // We currently do not support this attribute
        // as it is not in the IPP spec and therefore not in CUPS
      }

      /**
       * Called to update for new selected
       * print service. Tests if currently
       * selected attributes are supported.
       */
      void updateForSelectedService()
      {
        if (categorySupported(MediaPrintableArea.class))
          {
            left.setEnabled(true);
            right.setEnabled(true);
            top.setEnabled(true);
            bottom.setEnabled(true);
            left_tf.setEnabled(true);
            right_tf.setEnabled(true);
            top_tf.setEnabled(true);
            bottom_tf.setEnabled(true);
          }
        else
          {
            left.setEnabled(false);
            right.setEnabled(false);
            top.setEnabled(false);
            bottom.setEnabled(false);
            left_tf.setEnabled(false);
            right_tf.setEnabled(false);
            top_tf.setEnabled(false);
            bottom_tf.setEnabled(false);
          }
       }
    }

    private MediaTypes media_panel;
    private Orientation orientation_panel;
    private Margins margins_panel;

    /**
     * Constructs the page setup user interface.
     */
    public PageSetupPanel()
    {
      setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

      media_panel = new MediaTypes();
      orientation_panel = new Orientation();
      margins_panel = new Margins();

      JPanel layout_panel = new JPanel();
      layout_panel.setLayout(new BoxLayout(layout_panel, BoxLayout.LINE_AXIS));
      layout_panel.add(orientation_panel);
      layout_panel.add(Box.createRigidArea(new Dimension(10, 0)));
      layout_panel.add(margins_panel);

      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      add(media_panel);
      add(Box.createRigidArea(new Dimension(0, 12)));
      add(layout_panel);
    }

    /**
     * Calls update on all internal panels to adjust
     * for a new selected print service.
     */
    void update()
    {
      media_panel.updateForSelectedService();
      orientation_panel.updateForSelectedService();
      margins_panel.updateForSelectedService();
    }
  }

  /**
   * The Appearance panel for quality, color etc.
   * @author Wolfgang Baer (WBaer@gmx.de)
   */
  final class AppearancePanel extends JPanel
  {
    /**
     * Handles the print quality attribute.
     * @author Wolfgang Baer (WBaer@gmx.de)
     */
    final class Quality extends JPanel implements ActionListener
    {
      private JRadioButton low, normal, high;
      private ButtonGroup group;

      Quality()
      {
        low = new JRadioButton(getLocalizedString("rbt.low"));
        low.addActionListener(this);
        normal = new JRadioButton(getLocalizedString("rbt.normal"));
        normal.addActionListener(this);
        high = new JRadioButton(getLocalizedString("rbt.high"));
        high.addActionListener(this);

        group = new ButtonGroup();
        group.add(low);
        group.add(normal);
        group.add(high);

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

        setLayout(layout);
        setBorder(new TitledBorder(getLocalizedString("title.quality")));

        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(5, 5, 5, 5);
        c.gridx = 0;
        c.gridy = 0;
        add(low, c);

        c.gridx = 0;
        c.gridy = 1;
        add(normal, c);

        c.gridx = 0;
        c.gridy = 2;
        add(high, c);
      }

      public void actionPerformed(ActionEvent e)
      {
        if (e.getSource() == low)
          atts.add(PrintQuality.DRAFT);
        else if (e.getSource() == normal)
          atts.add(PrintQuality.NORMAL);
        else
          atts.add(PrintQuality.HIGH);
      }

      /**
       * Called to update for new selected
       * print service. Tests if currently
       * selected attributes are supported.
       */
      void updateForSelectedService()
      {
        if (categorySupported(PrintQuality.class))
          {
            low.setEnabled(true);
            normal.setEnabled(true);
            high.setEnabled(true);

            Object defaultValue = defaultValue(PrintQuality.class);
            Attribute quality = attribute(PrintQuality.class);

            if (quality != null)
              {
                if (quality.equals(PrintQuality.DRAFT))
                  low.setSelected(true);
                else if (quality.equals(PrintQuality.NORMAL))
                  normal.setSelected(true);
                else
                  high.setSelected(true);
              }
            else
              {
                if (defaultValue.equals(PrintQuality.DRAFT))
                  low.setSelected(true);
                else if (defaultValue.equals(PrintQuality.NORMAL))
                  normal.setSelected(true);
                else
                  high.setSelected(true);
              }
          }
        else
          {
            low.setEnabled(false);
            normal.setEnabled(false);
            high.setEnabled(false);
          }
      }
    }

    /**
     * Handles the job attributes as requesting username, jobname etc.
     * @author Wolfgang Baer (WBaer@gmx.de)
     */
    final class JobAttributes extends JPanel
      implements ActionListener, ChangeListener, FocusListener
    {
      private JLabel jobname, username, priority_lb;
      private JTextField jobname_tf, username_tf;
      private JCheckBox cover;
      private JSpinner priority;
      private SpinnerNumberModel model;

      JobAttributes()
      {
        jobname = new JLabel(getLocalizedString("lb.jobname"));
        username = new JLabel(getLocalizedString("lb.username"));
        priority_lb = new JLabel(getLocalizedString("lb.priority"));

        cover = new JCheckBox(getLocalizedString("cb.cover"));
        cover.addActionListener(this);

        model = new SpinnerNumberModel(1, 1, 100, 1);
        priority = new JSpinner(model);
        priority.addChangeListener(this);

        jobname_tf = new JTextField();
        jobname_tf.addFocusListener(this);
        username_tf = new JTextField();
        username_tf.addFocusListener(this);

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

        setLayout(layout);
        setBorder(new TitledBorder(getLocalizedString("title.jobattributes")));

        c.insets = new Insets(10, 5, 10, 5);
        c.gridx = 0;
        c.gridy = 0;
        add(cover, c);

        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 1;
        c.gridy = 0;
        c.weightx = 2;
        add(priority_lb, c);

        c.gridx = 2;
        c.gridy = 0;
        c.weightx = 0.5;
        add(priority, c);

        c.anchor = GridBagConstraints.LINE_END;
        c.gridx = 0;
        c.gridy = 1;
        add(jobname, c);

        c.gridx = 0;
        c.gridy = 2;
        add(username, c);

        c.anchor = GridBagConstraints.CENTER;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 1;
        c.gridwidth = 2;
        c.weightx = 1.5;
        add(jobname_tf, c);

        c.insets = new Insets(10, 5, 15, 5);
        c.gridx = 1;
        c.gridy = 2;
        add(username_tf, c);
      }

      public void actionPerformed(ActionEvent event)
      {
        if (cover.isSelected())
          atts.add(JobSheets.STANDARD);
        else
          atts.add(JobSheets.NONE);
      }

      public void stateChanged(ChangeEvent event)
      {
        int value = ((Integer) priority.getValue()).intValue();
        atts.add(new JobPriority(value));
      }

      public void focusGained(FocusEvent event)
      {
        updateTextfields(event);
      }

      public void focusLost(FocusEvent event)
      {
        updateTextfields(event);
      }

      private void updateTextfields(FocusEvent event)
      {
        if (event.getSource() == jobname_tf)
            atts.add(new JobName(jobname_tf.getText(), null));
        else
            atts.add(new RequestingUserName(username_tf.getText(), null));
      }

      /**
       * Called to update for new selected
       * print service. Tests if currently
       * selected attributes are supported.
       */
      void updateForSelectedService()
      {
        // JobPriority
        if (categorySupported(JobPriority.class))
          {
            JobPriority prio = (JobPriority) attribute(JobPriority.class);
            JobPriority value = (JobPriority) defaultValue(JobPriority.class);
            priority.setEnabled(true);
            if (prio != null)
              model.setValue(new Integer(prio.getValue()));
            else
              model.setValue(new Integer(value.getValue()));
          }
        else
          priority.setEnabled(false);

        // Requesting username
        if (categorySupported(RequestingUserName.class))
          {
            Attribute user = attribute(RequestingUserName.class);
            Object value = defaultValue(RequestingUserName.class);
            username.setEnabled(true);
            if (user != null)
              username_tf.setText(user.toString());
            else
              username_tf.setText(value.toString());
          }
        else
          username.setEnabled(false);

        // Job Name
        if (categorySupported(JobName.class))
          {
            Attribute job = attribute(JobName.class);
            Object value = defaultValue(JobName.class);
            jobname.setEnabled(true);
            if (job != null)
              jobname_tf.setText(job.toString());
            else
              jobname_tf.setText(value.toString());
          }
        else
          jobname.setEnabled(false);

        // Job sheets
        if (categorySupported(JobSheets.class))
          {
            Attribute sheet = attribute(JobSheets.class);
            Object value = defaultValue(JobSheets.class);
            cover.setEnabled(true);
            if (sheet != null)
              {
                if (sheet.equals(JobSheets.NONE))
                  cover.setSelected(false);
                else
                  cover.setSelected(true);
              }
            else
              {
                if (value.equals(JobSheets.NONE))
                  cover.setSelected(false);
                else
                  cover.setSelected(true);
              }
          }
        else
          cover.setEnabled(false);
      }
    }

    /**
     * Handles the sides attributes.
     * @author Wolfgang Baer (WBaer@gmx.de)
     */
    final class SidesPanel extends JPanel implements ActionListener
    {
      private JRadioButton oneside, calendar, duplex;

      SidesPanel()
      {
        oneside = new JRadioButton(getLocalizedString("rbt.onesided"));
        oneside.addActionListener(this);
        calendar = new JRadioButton(getLocalizedString("rbt.calendar"));
        calendar.addActionListener(this);
        duplex = new JRadioButton(getLocalizedString("rbt.duplex"));
        duplex.addActionListener(this);

        ButtonGroup group = new ButtonGroup();
        group.add(oneside);
        group.add(calendar);
        group.add(duplex);

        GridBagLayout layout = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;

        setLayout(layout);
        setBorder(new TitledBorder(getLocalizedString("title.sides")));

        c.insets = new Insets(5, 5, 5, 5);
        c.gridx = 0;
        c.gridy = 0;
        add(oneside, c);

        c.gridx = 0;
        c.gridy = 1;
        add(calendar, c);

        c.gridx = 0;
        c.gridy = 2;
        add(duplex, c);
      }

      public void actionPerformed(ActionEvent e)
      {
        if (e.getSource() == calendar)
          atts.add(Sides.TWO_SIDED_SHORT_EDGE);
        else if (e.getSource() == oneside)
          atts.add(Sides.ONE_SIDED);
        else
          atts.add(Sides.TWO_SIDED_LONG_EDGE);
      }

      /**
       * Called to update for new selected
       * print service. Tests if currently
       * selected attributes are supported.
       */
      void updateForSelectedService()
      {
        if (categorySupported(Sides.class))
          {
            oneside.setEnabled(true);
            calendar.setEnabled(true);
            duplex.setEnabled(true);

            Object defaultValue = defaultValue(Sides.class);
            Attribute sides = attribute(Sides.class);
            if (sides != null)
              {
                if (sides.equals(Sides.TWO_SIDED_SHORT_EDGE))
                  calendar.setSelected(true);
                else if (sides.equals(Sides.ONE_SIDED))
                  oneside.setSelected(true);
                else
                  duplex.setSelected(true);
              }
            else
              {
                if (defaultValue.equals(Sides.TWO_SIDED_SHORT_EDGE))
                  calendar.setSelected(true);
                else if (defaultValue.equals(Sides.ONE_SIDED))
                  oneside.setSelected(true);
                else
                  duplex.setSelected(true);
              }
          }
        else
          {
            oneside.setEnabled(false);
            calendar.setEnabled(false);
            duplex.setEnabled(false);
          }
      }
    }

    /**
     * Handles the chromaticity attributes.
     * @author Wolfgang Baer (WBaer@gmx.de)
     */
    final class Color extends JPanel implements ActionListener
    {
      private JRadioButton bw, color;

      Color()
      {
        bw = new JRadioButton(getLocalizedString("rbt.blackwhite"));
        bw.addActionListener(this);
        color = new JRadioButton(getLocalizedString("rbt.color"));
        color.addActionListener(this);

        ButtonGroup group = new ButtonGroup();
        group.add(bw);
        group.add(color);

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

        setLayout(layout);
        setBorder(new TitledBorder(getLocalizedString("title.color")));

        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(5, 5, 5, 5);
        c.gridx = 0;
        c.gridy = 0;
        add(bw, c);

        c.gridx = 0;
        c.gridy = 1;
        add(color, c);
      }

      public void actionPerformed(ActionEvent e)
      {
        if (e.getSource() == bw)
          atts.add(Chromaticity.MONOCHROME);
        else
          atts.add(Chromaticity.COLOR);
      }

      /**
       * Called to update for new selected
       * print service. Tests if currently
       * selected attributes are supported.
       */
      void updateForSelectedService()
      {
        if (categorySupported(Chromaticity.class))
          {
            bw.setEnabled(true);
            color.setEnabled(true);

            Object defaultValue = defaultValue(Chromaticity.class);
            Attribute chromaticity = attribute(Chromaticity.class);
            if (chromaticity != null)
              {
                if (chromaticity.equals(Chromaticity.MONOCHROME))
                  bw.setSelected(true);
                else
                  color.setSelected(true);
              }
            else
              {
                if (defaultValue.equals(Chromaticity.MONOCHROME))
                  bw.setSelected(true);
                else
                  color.setSelected(true);
              }
          }
        else
          {
            bw.setEnabled(false);
            color.setEnabled(false);
          }
      }
    }

    private Quality quality_panel;
    private JobAttributes jobAttr_panel;
    private SidesPanel sides_panel;
    private Color chromaticy_panel;

    /**
     * Creates the panel for appearance attributes.
     */
    public AppearancePanel()
    {
      setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

      quality_panel = new Quality();
      jobAttr_panel = new JobAttributes();
      sides_panel = new SidesPanel();
      chromaticy_panel = new Color();

      JPanel layout_panel = new JPanel();
      layout_panel.setLayout(new BoxLayout(layout_panel, BoxLayout.LINE_AXIS));
      layout_panel.add(chromaticy_panel);
      layout_panel.add(Box.createRigidArea(new Dimension(10, 0)));
      layout_panel.add(quality_panel);

      JPanel layout2_panel = new JPanel();
      layout2_panel.setLayout(new BoxLayout(layout2_panel, BoxLayout.LINE_AXIS));
      layout2_panel.add(sides_panel);
      layout2_panel.add(Box.createRigidArea(new Dimension(10, 0)));
      layout2_panel.add(jobAttr_panel);

      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      add(layout_panel);
      add(Box.createRigidArea(new Dimension(0, 12)));
      add(layout2_panel);
    }

    /**
     * Calls update on all internal panels to adjust
     * for a new selected print service.
     */
    void update()
    {
      quality_panel.updateForSelectedService();
      jobAttr_panel.updateForSelectedService();
      sides_panel.updateForSelectedService();
      chromaticy_panel.updateForSelectedService();
    }
  }

  // on main contentpane
  private JButton ok_bt;
  private JButton cancel_bt;

  // the tabs
  private GeneralPanel general_panel;
  private PageSetupPanel pagesetup_panel;
  private AppearancePanel appearance_panel;

  private PrintService[] services;
  private PrintService defaultService;
  private PrintService selectedService;
  private DocFlavor flavor;
  private PrintRequestAttributeSet attributes;

  private boolean onlyPageDialog;
  private PrintRequestAttributeSet atts;

  private final static ResourceBundle messages
    = ResourceBundle.getBundle("gnu.javax.print.MessagesBundle");

  // TODO LowPriority: Include checks so that if a specific value formerly
  // selected is no more supported by the new service changes to the default.

  /**
   * Class private constructs a printer dialog.
   *
   * @param gc the screen to use. <code>null</code> is default screen.
   * @param services the print services to browse (not null).
   * @param defaultService the default service. If <code>null</code>
   * the first of the print services in the services array will be used.
   * @param flavor the flavours to be printed.
   * @param attributes the attributes requested. Will be updated
   * by selections done by the user in the dialog.
   * @param onlyPageDialog if true a page settings only dialog is constructed.
   *
   * @throws HeadlessException if GraphicsEnvironment is headless
   */
  private PrinterDialog(GraphicsConfiguration gc, PrintService[] services,
    PrintService defaultService, DocFlavor flavor,
    PrintRequestAttributeSet attributes, boolean onlyPageDialog, String title)
    throws HeadlessException
  {
    super((Frame)null, title, true, gc);

    setResizable(false);
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);

    // check and remove service not supporting the flavor
    if (flavor != null)
      {
        ArrayList list = new ArrayList(services.length);
        for(int i=0; i < services.length; i++)
          if (services[i].isDocFlavorSupported(flavor))
            list.add(services[i]);

        if (defaultService != null
            && (! list.contains(defaultService)))
          defaultService = (PrintService) list.get(0);

        PrintService[] newServices = new PrintService[list.size()];
        this.services = (PrintService[]) list.toArray(newServices);
      }
    else
      this.services = services;

    if (defaultService == null)
      this.defaultService = services[0];
    else
      this.defaultService = defaultService;

    this.selectedService = this.defaultService;
    this.flavor = flavor;

    // the attributes given by the user
    this.attributes = attributes;
    // the one to work with during browsing
    this.atts = new HashPrintRequestAttributeSet(attributes);

    this.onlyPageDialog = onlyPageDialog;

    initUI(onlyPageDialog);
    pack();
    updateAll();
  }

  /**
   * Constructs a page settings only dialog.
   *
   * @param gc the screen to use. <code>null</code> is default screen.
   * @param service the print service for the page dialog.
   * the first of the print services in the services array will be used.
   * @param flavor the flavours to be printed.
   * @param attributes the attributes requested. Will be updated
   * by selections done by the user in the dialog.
   *
   * @throws HeadlessException if GraphicsEnvironment is headless
   */
  public PrinterDialog(GraphicsConfiguration gc, PrintService service,
    DocFlavor flavor, PrintRequestAttributeSet attributes)
    throws HeadlessException
  {
    this(gc, new PrintService[] {service}, service, flavor, attributes,
         true, getLocalizedString("title.pagedialog"));
  }

  /**
   * Constructs a printer dialog.
   *
   * @param gc the screen to use. <code>null</code> is default screen.
   * @param services the print services to browse (not null).
   * @param defaultService the default service. If <code>null</code>
   * the first of the print services in the services array will be used.
   * @param flavor the flavours to be printed.
   * @param attributes the attributes requested. Will be updated
   * by selections done by the user in the dialog.
   *
   * @throws HeadlessException if GraphicsEnvironment is headless
   */
  public PrinterDialog(GraphicsConfiguration gc, PrintService[] services,
    PrintService defaultService, DocFlavor flavor,
    PrintRequestAttributeSet attributes)
    throws HeadlessException
  {
    this(gc, services, defaultService, flavor, attributes,
         false, getLocalizedString("title.printdialog"));
  }

  // initializes the gui parts
  private void initUI(boolean onlyPageDialog)
  {
    JPanel buttonPane = new JPanel();

    if (onlyPageDialog)
      {
        JPanel pane = new JPanel();
        pane.setLayout(new BorderLayout());
        pagesetup_panel = new PageSetupPanel();
        pane.add(pagesetup_panel, BorderLayout.CENTER);

        ok_bt = new JButton(getLocalizedString("bt.OK"));
        ok_bt.addActionListener(this);
        cancel_bt = new JButton(getLocalizedString("bt.cancel"));
        cancel_bt.addActionListener(this);

        getContentPane().add(pane, BorderLayout.CENTER);
      }
    else
      {
        general_panel = new GeneralPanel();
        pagesetup_panel = new PageSetupPanel();
        appearance_panel = new AppearancePanel();

        JTabbedPane pane = new JTabbedPane();
        pane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        ok_bt = new JButton(getLocalizedString("bt.print"));
        ok_bt.addActionListener(this);
        cancel_bt = new JButton(getLocalizedString("bt.cancel"));
        cancel_bt.addActionListener(this);

        // populate jtabbedpane
        pane.addTab(getLocalizedString("tab.general"), general_panel);
        pane.addTab(getLocalizedString("tab.pagesetup"), pagesetup_panel);
        pane.addTab(getLocalizedString("tab.appearance"), appearance_panel);

        // Put everything together
        getContentPane().add(pane, BorderLayout.CENTER);
      }

    buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
    buttonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    buttonPane.add(Box.createHorizontalGlue());
    buttonPane.add(ok_bt);
    buttonPane.add(Box.createRigidArea(new Dimension(5, 0)));
    buttonPane.add(cancel_bt);

    getContentPane().add(buttonPane, BorderLayout.PAGE_END);
  }

  /**
   * Returns the modified attributes set.
   * @return The attributes.
   */
  public PrintRequestAttributeSet getAttributes()
  {
    return attributes;
  }

  /**
   * Returns the print service selected by the user.
   * @return The selected print service.
   */
  public PrintService getSelectedPrintService()
  {
    return selectedService;
  }

  /**
   * Sets the currently selected print service.
   *
   * @param service the service selected.
   */
  protected void setSelectedPrintService(PrintService service)
  {
    selectedService = service;
  }

  /**
   * Returns the print service array.
   * @return The print services.
   */
  protected PrintService[] getPrintServices()
  {
    return services;
  }

  /**
   * Calls update on all panels to adjust
   * for a new selected print service.
   */
  void updateAll()
  {
    pagesetup_panel.update();

    if (! onlyPageDialog)
      {
        general_panel.update();
        appearance_panel.update();
      }
  }

  boolean categorySupported(Class category)
  {
    return getSelectedPrintService().
      isAttributeCategorySupported(category);
  }

  Object defaultValue(Class category)
  {
    return getSelectedPrintService().
      getDefaultAttributeValue(category);
  }

  Attribute attribute(Class category)
  {
    return atts.get(category);
  }

  /**
   *  Action handler for Print/Cancel buttons.
   *  If cancel is pressed we reset the attributes
   *  and the selected service.
   *
   *  @param e the ActionEvent
   */
  public void actionPerformed(ActionEvent e)
  {
    if (e.getSource() == ok_bt)
      {
        setVisible(false);
        attributes.addAll(atts);
        dispose();
      }
    else
      {
        setVisible(false);
        selectedService = null;
        dispose();
      }
  }

  /**
   * Retrieves localized messages from the resource bundle.
   *
   * @param key the key
   * @return The localized value for the key.
   */
  static final String getLocalizedString(String key) {
    return messages.getString(key);
  }
}
