/*  SimplePrintDialog
    (C) Copyright 2009
    Wildcrest Associates
    http://www.wildcrest.com
This source code may be freely used, modified, incorporated, and
distributed without restriction as part of any software that uses
J2PrinterWorks by Wildcrest Associates.
*/

import com.wildcrest.j2printerworks.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.swing.border.TitledBorder;
import javax.print.attribute.standard.*;
import javax.print.PrintService;
import javax.swing.event.*;
import javax.print.attribute.HashPrintRequestAttributeSet;

public class SimplePrintDialog extends JDialog {
   public static final int CANCEL = 0;
   public static final int PRINT = 1;

   private J2Printer14 printer;
   private PrintRequestAttributeSet attributeSet;
   private String printerName;
   private JComboBox printerChoices;
   private String currentPrinter;
   private int retVal;
   private JTextField pageRangesField;
   private JRadioButton allButton, rangeButton;
   private SpinnerNumberModel copiesSpinnerModel;
   private String fullPageRange;
   private Integer int1 = new Integer(1);
   private Integer int999 = new Integer(999);
   private JCheckBox collateCheckBox;
   private ImagePanel collatedImagePanel;
   private Image isCollatedImage, notCollatedImage;

   SimplePrintDialog(Frame frame, J2Printer14 printer) {
      super(frame, "Print", true); // true = modal
      this.printer = printer;
      this.setResizable(false);

      PrintRequestAttributeSet aset = printer.getPrintRequestAttributeSet(); // pointer to printer's aset
   //tests:
      //aset.add(new Copies(2));
      //aset.add(SheetCollate.COLLATED);
      //aset.add(new PageRanges(2, printer.getPageable().getNumberOfPages()));

      this.attributeSet = new HashPrintRequestAttributeSet(aset);
      this.attributeSet = new HashPrintRequestAttributeSet(printer.getPrintRequestAttributeSet());
      this.printerName = printer.getPrinter();
      this.setLayout(new BorderLayout());

   // printer choices
      JPanel selectPrinterLine = new JPanel();
      TitledBorder selectPrinterBorder = new TitledBorder("Select Printer");
      selectPrinterLine.setBorder(new TitledBorder("Select Printer"));
      selectPrinterLine.setLayout(new FlowLayout(FlowLayout.LEFT));
      printerChoices = new JComboBox(printer.getAllPrinterNames());
      printerChoices.setEditable(false);
      currentPrinter = printer.getPrinter(); // returns default printer if none specified
      printerChoices.setSelectedItem(currentPrinter);
      JPanel printerField = new JPanel();
      printerField.add(new JLabel("Name: "));
      printerField.add(printerChoices);
      selectPrinterLine.add(printerField);
      this.add(selectPrinterLine, "North");

      printerChoices.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) { printerChanged(); }});

   // page range
      JPanel pageRangePanel = new JPanel();
      pageRangePanel.setBorder(new TitledBorder("Page Range"));
      pageRangePanel.setLayout(new BorderLayout());

      allButton = new JRadioButton("All");
      rangeButton = new JRadioButton("Pages: ");
      ButtonGroup pagesGroup = new ButtonGroup();
      pagesGroup.add(allButton);
      pagesGroup.add(rangeButton);

      JPanel allLine = new JPanel();
      allLine.setLayout(new FlowLayout(FlowLayout.LEFT));
      allLine.add(allButton);

      JPanel pageNumbersLine = new JPanel();
      pageNumbersLine.setLayout(new FlowLayout(FlowLayout.LEFT));
      pageNumbersLine.add(rangeButton);
      pageRangesField = new JTextField(6);
      pageNumbersLine.add(pageRangesField);
      JLabel pageNumbersLabel = new JLabel("e.g. 1-3,6,9-12");
      pageNumbersLabel.setBackground(this.getContentPane().getBackground());
      pageNumbersLabel.setFont(new Font("SanSerif",Font.PLAIN,11));
      pageNumbersLine.add(pageNumbersLabel);

      fullPageRange = "1-" + printer.getPageable().getNumberOfPages();
      String pageRanges = printer.getPageRanges();
      if (pageRanges.length() == 0) pageRangesField.setText(fullPageRange);
      else pageRangesField.setText(pageRanges);


      pageRangePanel.add(allLine, "North");
      pageRangePanel.add(pageNumbersLine, "South");

      allButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) { pageRangesChanged(); }});
      rangeButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) { pageRangesChanged(); }});
      pageRangesField.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) { pageRangesChanged(); } });
      pageRangesField.addFocusListener(new FocusListener() {
         public void focusLost(FocusEvent fe) { pageRangesChanged(); }
         public void focusGained(FocusEvent fe) {  }
      });

   // copies
      JPanel copiesPanel = new JPanel();
      copiesPanel.setBorder(new TitledBorder("Copies"));
      copiesPanel.setLayout(new BorderLayout());
      JPanel numberOfCopiesLine = new JPanel();
      numberOfCopiesLine.add(new JLabel("Number of copies: "));
      copiesSpinnerModel = new SpinnerNumberModel(printer.getCopies(), 1, 999, 1);
      numberOfCopiesLine.add(new JSpinner(copiesSpinnerModel));
      copiesPanel.add(numberOfCopiesLine, "North");

      copiesSpinnerModel.addChangeListener(new ChangeListener() {
         public void stateChanged(ChangeEvent e) { copiesChanged(); }});

   // collate
      collateCheckBox = new JCheckBox("Collate ");
      JPanel collatePanel = new JPanel();
      collatePanel.add(collateCheckBox);

      isCollatedImage = new ImageIcon("isCollated.png").getImage();
      notCollatedImage = new ImageIcon("notCollated.png").getImage();

      collatedImagePanel = new ImagePanel();
      collatedImagePanel.setBackground(this.getContentPane().getBackground());
      collatePanel.add(collatedImagePanel);

      copiesPanel.add(collatePanel, "South");

      collateCheckBox.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) { collateChanged(); }});
      collateCheckBox.setSelected(printer.getCollate());
      collateChanged();

   // page range + copies panel
      JPanel printerOptions = new JPanel();
      printerOptions.setLayout(new GridLayout());
      printerOptions.add(pageRangePanel);
      printerOptions.add(copiesPanel);
      this.add(printerOptions, "Center");

   // print + cancel buttons
      JPanel printCancel = new JPanel();
      JButton printButton = new JButton("Print");
      JButton cancelButton = new JButton("Cancel");
      printCancel.setLayout(new FlowLayout(FlowLayout.RIGHT));
      printCancel.add(printButton);
      printCancel.add(cancelButton);
      this.add(printCancel, "South");

      printButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) { print(); }});
      cancelButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) { cancel(); }});

      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) { cancel(); }});

      validateUI();

      pack();
      Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
      Rectangle frameDim = getBounds();
      setLocation( (screenDim.width - frameDim.width) / 2, (screenDim.height - frameDim.height) / 2);
   }

   void validateUI() {
      // update copies UI given printer selection
      PrintService ps = printer.getPrinterJob().getPrintService();
      Object copies = ps.getSupportedAttributeValues(Copies.class, null, null);
      if (copies!=null && copies.toString().equals("1")) {
         copiesSpinnerModel.setValue(int1);
         copiesSpinnerModel.setMaximum(int1);
         printer.setCopies(1);
         collateCheckBox.setSelected(false);
      }
      else {
         copiesSpinnerModel.setMaximum(int999);
      }

      // update collate UI
      int nCopies = printer.getCopies();
      collateCheckBox.setEnabled(nCopies > 1);
      if (nCopies == 1) collateCheckBox.setSelected(false);
      if (collateCheckBox.isSelected()) collatedImagePanel.setImage(isCollatedImage);
      else collatedImagePanel.setImage(notCollatedImage);

      // update page ranges UI
      try { PageRanges pr = new PageRanges(pageRangesField.getText()); }
      catch (Exception e) { pageRangesField.setText(fullPageRange); }
      boolean isAll = printer.getPageRanges().length()==0;
      pageRangesField.setEnabled(!isAll);
      rangeButton.setSelected(!isAll);
      allButton.setSelected(isAll);

      repaint();
   }

   void printerChanged() {
      printer.setPrinter( (String) printerChoices.getSelectedItem());
      validateUI();
   }

   void copiesChanged() {
      printer.setCopies(copiesSpinnerModel.getNumber().intValue());
      validateUI();
   }

   void collateChanged() {
      printer.setCollate(collateCheckBox.isSelected());
      validateUI();
   }

   void pageRangesChanged() {
      boolean isAll = allButton.isSelected();
      if (isAll) printer.setPageRanges(null);
      else try { printer.setPageRanges(pageRangesField.getText()); } catch (Exception e) { }
      validateUI();
   }

   public int showDialog() {
      setVisible(true);
      return retVal;
   }

   public void print() {
      retVal = SimplePrintDialog.PRINT;
      setVisible(false);
   }

   public void cancel() {
      printer.setPrintRequestAttributeSet(attributeSet);
      printer.setPrinter(printerName);
      retVal = SimplePrintDialog.CANCEL;
      setVisible(false);
   }

}

