/* PrinterDialog.java --
   Copyright (C)  2006  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;

  static
  {    
    messages = ResourceBundle.getBundle("gnu/javax/print/PrinterDialog");
  }
  
  // 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);
  }
}
