/*
 * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package java.awt;

/**
 * A set of attributes which control a print job.
 * <p>
 * Instances of this class control the number of copies, default selection,
 * destination, print dialog, file and printer names, page ranges, multiple
 * document handling (including collation), and multi-page imposition (such
 * as duplex) of every print job which uses the instance. Attribute names are
 * compliant with the Internet Printing Protocol (IPP) 1.1 where possible.
 * Attribute values are partially compliant where possible.
 * <p>
 * To use a method which takes an inner class type, pass a reference to
 * one of the constant fields of the inner class. Client code cannot create
 * new instances of the inner class types because none of those classes
 * has a public constructor. For example, to set the print dialog type to
 * the cross-platform, pure Java print dialog, use the following code:
 * <pre>
 * import java.awt.JobAttributes;
 *
 * public class PureJavaPrintDialogExample {
 *     public void setPureJavaPrintDialog(JobAttributes jobAttributes) {
 *         jobAttributes.setDialog(JobAttributes.DialogType.COMMON);
 *     }
 * }
 * </pre>
 * <p>
 * Every IPP attribute which supports an <i>attributeName</i>-default value
 * has a corresponding <code>set<i>attributeName</i>ToDefault</code> method.
 * Default value fields are not provided.
 *
 * @author      David Mendenhall
 * @since 1.3
 */
public final class JobAttributes implements Cloneable {
    /**
     * A type-safe enumeration of possible default selection states.
     * @since 1.3
     */
    public static final class DefaultSelectionType extends AttributeValue {
        private static final int I_ALL = 0;
        private static final int I_RANGE = 1;
        private static final int I_SELECTION = 2;

        private static final String NAMES[] = {
            "all", "range", "selection"
        };

        /**
         * The <code>DefaultSelectionType</code> instance to use for
         * specifying that all pages of the job should be printed.
         */
        public static final DefaultSelectionType ALL =
           new DefaultSelectionType(I_ALL);
        /**
         * The <code>DefaultSelectionType</code> instance to use for
         * specifying that a range of pages of the job should be printed.
         */
        public static final DefaultSelectionType RANGE =
           new DefaultSelectionType(I_RANGE);
        /**
         * The <code>DefaultSelectionType</code> instance to use for
         * specifying that the current selection should be printed.
         */
        public static final DefaultSelectionType SELECTION =
           new DefaultSelectionType(I_SELECTION);

        private DefaultSelectionType(int type) {
            super(type, NAMES);
        }
    }

    /**
     * A type-safe enumeration of possible job destinations.
     * @since 1.3
     */
    public static final class DestinationType extends AttributeValue {
        private static final int I_FILE = 0;
        private static final int I_PRINTER = 1;

        private static final String NAMES[] = {
            "file", "printer"
        };

        /**
         * The <code>DestinationType</code> instance to use for
         * specifying print to file.
         */
        public static final DestinationType FILE =
            new DestinationType(I_FILE);
        /**
         * The <code>DestinationType</code> instance to use for
         * specifying print to printer.
         */
        public static final DestinationType PRINTER =
            new DestinationType(I_PRINTER);

        private DestinationType(int type) {
            super(type, NAMES);
        }
    }

    /**
     * A type-safe enumeration of possible dialogs to display to the user.
     * @since 1.3
     */
    public static final class DialogType extends AttributeValue {
        private static final int I_COMMON = 0;
        private static final int I_NATIVE = 1;
        private static final int I_NONE = 2;

        private static final String NAMES[] = {
            "common", "native", "none"
        };

        /**
         * The <code>DialogType</code> instance to use for
         * specifying the cross-platform, pure Java print dialog.
         */
        public static final DialogType COMMON = new DialogType(I_COMMON);
        /**
         * The <code>DialogType</code> instance to use for
         * specifying the platform's native print dialog.
         */
        public static final DialogType NATIVE = new DialogType(I_NATIVE);
        /**
         * The <code>DialogType</code> instance to use for
         * specifying no print dialog.
         */
        public static final DialogType NONE = new DialogType(I_NONE);

        private DialogType(int type) {
            super(type, NAMES);
        }
    }

    /**
     * A type-safe enumeration of possible multiple copy handling states.
     * It is used to control how the sheets of multiple copies of a single
     * document are collated.
     * @since 1.3
     */
    public static final class MultipleDocumentHandlingType extends
                                                               AttributeValue {
        private static final int I_SEPARATE_DOCUMENTS_COLLATED_COPIES = 0;
        private static final int I_SEPARATE_DOCUMENTS_UNCOLLATED_COPIES = 1;

        private static final String NAMES[] = {
            "separate-documents-collated-copies",
            "separate-documents-uncollated-copies"
        };

        /**
         * The <code>MultipleDocumentHandlingType</code> instance to use for specifying
         * that the job should be divided into separate, collated copies.
         */
        public static final MultipleDocumentHandlingType
            SEPARATE_DOCUMENTS_COLLATED_COPIES =
                new MultipleDocumentHandlingType(
                    I_SEPARATE_DOCUMENTS_COLLATED_COPIES);
        /**
         * The <code>MultipleDocumentHandlingType</code> instance to use for specifying
         * that the job should be divided into separate, uncollated copies.
         */
        public static final MultipleDocumentHandlingType
            SEPARATE_DOCUMENTS_UNCOLLATED_COPIES =
                new MultipleDocumentHandlingType(
                    I_SEPARATE_DOCUMENTS_UNCOLLATED_COPIES);

        private MultipleDocumentHandlingType(int type) {
            super(type, NAMES);
        }
    }

    /**
     * A type-safe enumeration of possible multi-page impositions. These
     * impositions are in compliance with IPP 1.1.
     * @since 1.3
     */
    public static final class SidesType extends AttributeValue {
        private static final int I_ONE_SIDED = 0;
        private static final int I_TWO_SIDED_LONG_EDGE = 1;
        private static final int I_TWO_SIDED_SHORT_EDGE = 2;

        private static final String NAMES[] = {
            "one-sided", "two-sided-long-edge", "two-sided-short-edge"
        };

        /**
         * The <code>SidesType</code> instance to use for specifying that
         * consecutive job pages should be printed upon the same side of
         * consecutive media sheets.
         */
        public static final SidesType ONE_SIDED = new SidesType(I_ONE_SIDED);
        /**
         * The <code>SidesType</code> instance to use for specifying that
         * consecutive job pages should be printed upon front and back sides
         * of consecutive media sheets, such that the orientation of each pair
         * of pages on the medium would be correct for the reader as if for
         * binding on the long edge.
         */
        public static final SidesType TWO_SIDED_LONG_EDGE =
            new SidesType(I_TWO_SIDED_LONG_EDGE);
        /**
         * The <code>SidesType</code> instance to use for specifying that
         * consecutive job pages should be printed upon front and back sides
         * of consecutive media sheets, such that the orientation of each pair
         * of pages on the medium would be correct for the reader as if for
         * binding on the short edge.
         */
        public static final SidesType TWO_SIDED_SHORT_EDGE =
            new SidesType(I_TWO_SIDED_SHORT_EDGE);

        private SidesType(int type) {
            super(type, NAMES);
        }
    }

    private int copies;
    private DefaultSelectionType defaultSelection;
    private DestinationType destination;
    private DialogType dialog;
    private String fileName;
    private int fromPage;
    private int maxPage;
    private int minPage;
    private MultipleDocumentHandlingType multipleDocumentHandling;
    private int[][] pageRanges;
    private int prFirst;
    private int prLast;
    private String printer;
    private SidesType sides;
    private int toPage;

    /**
     * Constructs a <code>JobAttributes</code> instance with default
     * values for every attribute.  The dialog defaults to
     * <code>DialogType.NATIVE</code>.  Min page defaults to
     * <code>1</code>.  Max page defaults to <code>Integer.MAX_VALUE</code>.
     * Destination defaults to <code>DestinationType.PRINTER</code>.
     * Selection defaults to <code>DefaultSelectionType.ALL</code>.
     * Number of copies defaults to <code>1</code>. Multiple document handling defaults
     * to <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES</code>.
     * Sides defaults to <code>SidesType.ONE_SIDED</code>. File name defaults
     * to <code>null</code>.
     */
    public JobAttributes() {
        setCopiesToDefault();
        setDefaultSelection(DefaultSelectionType.ALL);
        setDestination(DestinationType.PRINTER);
        setDialog(DialogType.NATIVE);
        setMaxPage(Integer.MAX_VALUE);
        setMinPage(1);
        setMultipleDocumentHandlingToDefault();
        setSidesToDefault();
    }

    /**
     * Constructs a <code>JobAttributes</code> instance which is a copy
     * of the supplied <code>JobAttributes</code>.
     *
     * @param   obj the <code>JobAttributes</code> to copy
     */
    public JobAttributes(JobAttributes obj) {
        set(obj);
    }

    /**
     * Constructs a <code>JobAttributes</code> instance with the
     * specified values for every attribute.
     *
     * @param   copies an integer greater than 0
     * @param   defaultSelection <code>DefaultSelectionType.ALL</code>,
     *          <code>DefaultSelectionType.RANGE</code>, or
     *          <code>DefaultSelectionType.SELECTION</code>
     * @param   destination <code>DesintationType.FILE</code> or
     *          <code>DesintationType.PRINTER</code>
     * @param   dialog <code>DialogType.COMMON</code>,
     *          <code>DialogType.NATIVE</code>, or
     *          <code>DialogType.NONE</code>
     * @param   fileName the possibly <code>null</code> file name
     * @param   maxPage an integer greater than zero and greater than or equal
     *          to <i>minPage</i>
     * @param   minPage an integer greater than zero and less than or equal
     *          to <i>maxPage</i>
     * @param   multipleDocumentHandling
     *     <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES</code> or
     *     <code>MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES</code>
     * @param   pageRanges an array of integer arrays of two elements; an array
     *          is interpreted as a range spanning all pages including and
     *          between the specified pages; ranges must be in ascending
     *          order and must not overlap; specified page numbers cannot be
     *          less than <i>minPage</i> nor greater than <i>maxPage</i>;
     *          for example:
     *          <pre>
     *          (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 },
     *                         new int[] { 15, 19 } }),
     *          </pre>
     *          specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19. Note that
     *          (<code>new int[][] { new int[] { 1, 1 }, new int[] { 1, 2 } }</code>),
     *          is an invalid set of page ranges because the two ranges
     *          overlap
     * @param   printer the possibly <code>null</code> printer name
     * @param   sides <code>SidesType.ONE_SIDED</code>,
     *          <code>SidesType.TWO_SIDED_LONG_EDGE</code>, or
     *          <code>SidesType.TWO_SIDED_SHORT_EDGE</code>
     * @throws  IllegalArgumentException if one or more of the above
     *          conditions is violated
     */
    public JobAttributes(int copies, DefaultSelectionType defaultSelection,
                         DestinationType destination, DialogType dialog,
                         String fileName, int maxPage, int minPage,
                         MultipleDocumentHandlingType multipleDocumentHandling,
                         int[][] pageRanges, String printer, SidesType sides) {
        setCopies(copies);
        setDefaultSelection(defaultSelection);
        setDestination(destination);
        setDialog(dialog);
        setFileName(fileName);
        setMaxPage(maxPage);
        setMinPage(minPage);
        setMultipleDocumentHandling(multipleDocumentHandling);
        setPageRanges(pageRanges);
        setPrinter(printer);
        setSides(sides);
    }

    /**
     * Creates and returns a copy of this <code>JobAttributes</code>.
     *
     * @return  the newly created copy; it is safe to cast this Object into
     *          a <code>JobAttributes</code>
     */
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            // Since we implement Cloneable, this should never happen
            throw new InternalError();
        }
    }

    /**
     * Sets all of the attributes of this <code>JobAttributes</code> to
     * the same values as the attributes of obj.
     *
     * @param   obj the <code>JobAttributes</code> to copy
     */
    public void set(JobAttributes obj) {
        copies = obj.copies;
        defaultSelection = obj.defaultSelection;
        destination = obj.destination;
        dialog = obj.dialog;
        fileName = obj.fileName;
        fromPage = obj.fromPage;
        maxPage = obj.maxPage;
        minPage = obj.minPage;
        multipleDocumentHandling = obj.multipleDocumentHandling;
        // okay because we never modify the contents of pageRanges
        pageRanges = obj.pageRanges;
        prFirst = obj.prFirst;
        prLast = obj.prLast;
        printer = obj.printer;
        sides = obj.sides;
        toPage = obj.toPage;
    }

    /**
     * Returns the number of copies the application should render for jobs
     * using these attributes. This attribute is updated to the value chosen
     * by the user.
     *
     * @return  an integer greater than 0.
     */
    public int getCopies() {
        return copies;
    }

    /**
     * Specifies the number of copies the application should render for jobs
     * using these attributes. Not specifying this attribute is equivalent to
     * specifying <code>1</code>.
     *
     * @param   copies an integer greater than 0
     * @throws  IllegalArgumentException if <code>copies</code> is less than
     *      or equal to 0
     */
    public void setCopies(int copies) {
        if (copies <= 0) {
            throw new IllegalArgumentException("Invalid value for attribute "+
                                               "copies");
        }
        this.copies = copies;
    }

    /**
     * Sets the number of copies the application should render for jobs using
     * these attributes to the default. The default number of copies is 1.
     */
    public void setCopiesToDefault() {
        setCopies(1);
    }

    /**
     * Specifies whether, for jobs using these attributes, the application
     * should print all pages, the range specified by the return value of
     * <code>getPageRanges</code>, or the current selection. This attribute
     * is updated to the value chosen by the user.
     *
     * @return  DefaultSelectionType.ALL, DefaultSelectionType.RANGE, or
     *          DefaultSelectionType.SELECTION
     */
    public DefaultSelectionType getDefaultSelection() {
        return defaultSelection;
    }

    /**
     * Specifies whether, for jobs using these attributes, the application
     * should print all pages, the range specified by the return value of
     * <code>getPageRanges</code>, or the current selection. Not specifying
     * this attribute is equivalent to specifying DefaultSelectionType.ALL.
     *
     * @param   defaultSelection DefaultSelectionType.ALL,
     *          DefaultSelectionType.RANGE, or DefaultSelectionType.SELECTION.
     * @throws  IllegalArgumentException if defaultSelection is <code>null</code>
     */
    public void setDefaultSelection(DefaultSelectionType defaultSelection) {
        if (defaultSelection == null) {
            throw new IllegalArgumentException("Invalid value for attribute "+
                                               "defaultSelection");
        }
        this.defaultSelection = defaultSelection;
    }

    /**
     * Specifies whether output will be to a printer or a file for jobs using
     * these attributes. This attribute is updated to the value chosen by the
     * user.
     *
     * @return  DesintationType.FILE or DesintationType.PRINTER
     */
    public DestinationType getDestination() {
        return destination;
    }

    /**
     * Specifies whether output will be to a printer or a file for jobs using
     * these attributes. Not specifying this attribute is equivalent to
     * specifying DesintationType.PRINTER.
     *
     * @param   destination DesintationType.FILE or DesintationType.PRINTER.
     * @throws  IllegalArgumentException if destination is null.
     */
    public void setDestination(DestinationType destination) {
        if (destination == null) {
            throw new IllegalArgumentException("Invalid value for attribute "+
                                               "destination");
        }
        this.destination = destination;
    }

    /**
     * Returns whether, for jobs using these attributes, the user should see
     * a print dialog in which to modify the print settings, and which type of
     * print dialog should be displayed. DialogType.COMMON denotes a cross-
     * platform, pure Java print dialog. DialogType.NATIVE denotes the
     * platform's native print dialog. If a platform does not support a native
     * print dialog, the pure Java print dialog is displayed instead.
     * DialogType.NONE specifies no print dialog (i.e., background printing).
     * This attribute cannot be modified by, and is not subject to any
     * limitations of, the implementation or the target printer.
     *
     * @return  <code>DialogType.COMMON</code>, <code>DialogType.NATIVE</code>, or
     *          <code>DialogType.NONE</code>
     */
    public DialogType getDialog() {
        return dialog;
    }

    /**
     * Specifies whether, for jobs using these attributes, the user should see
     * a print dialog in which to modify the print settings, and which type of
     * print dialog should be displayed. DialogType.COMMON denotes a cross-
     * platform, pure Java print dialog. DialogType.NATIVE denotes the
     * platform's native print dialog. If a platform does not support a native
     * print dialog, the pure Java print dialog is displayed instead.
     * DialogType.NONE specifies no print dialog (i.e., background printing).
     * Not specifying this attribute is equivalent to specifying
     * DialogType.NATIVE.
     *
     * @param   dialog DialogType.COMMON, DialogType.NATIVE, or
     *          DialogType.NONE.
     * @throws  IllegalArgumentException if dialog is null.
     */
    public void setDialog(DialogType dialog) {
        if (dialog == null) {
            throw new IllegalArgumentException("Invalid value for attribute "+
                                               "dialog");
        }
        this.dialog = dialog;
    }

    /**
     * Specifies the file name for the output file for jobs using these
     * attributes. This attribute is updated to the value chosen by the user.
     *
     * @return  the possibly <code>null</code> file name
     */
    public String getFileName() {
        return fileName;
    }

    /**
     * Specifies the file name for the output file for jobs using these
     * attributes. Default is platform-dependent and implementation-defined.
     *
     * @param   fileName the possibly null file name.
     */
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    /**
     * Returns, for jobs using these attributes, the first page to be
     * printed, if a range of pages is to be printed. This attribute is
     * updated to the value chosen by the user. An application should ignore
     * this attribute on output, unless the return value of the <code>
     * getDefaultSelection</code> method is DefaultSelectionType.RANGE. An
     * application should honor the return value of <code>getPageRanges</code>
     * over the return value of this method, if possible.
     *
     * @return  an integer greater than zero and less than or equal to
     *          <i>toPage</i> and greater than or equal to <i>minPage</i> and
     *          less than or equal to <i>maxPage</i>.
     */
    public int getFromPage() {
        if (fromPage != 0) {
            return fromPage;
        } else if (toPage != 0) {
            return getMinPage();
        } else if (pageRanges != null) {
            return prFirst;
        } else {
            return getMinPage();
        }
    }

    /**
     * Specifies, for jobs using these attributes, the first page to be
     * printed, if a range of pages is to be printed. If this attribute is not
     * specified, then the values from the pageRanges attribute are used. If
     * pageRanges and either or both of fromPage and toPage are specified,
     * pageRanges takes precedence. Specifying none of pageRanges, fromPage,
     * or toPage is equivalent to calling
     * setPageRanges(new int[][] { new int[] { <i>minPage</i> } });
     *
     * @param   fromPage an integer greater than zero and less than or equal to
     *          <i>toPage</i> and greater than or equal to <i>minPage</i> and
     *          less than or equal to <i>maxPage</i>.
     * @throws  IllegalArgumentException if one or more of the above
     *          conditions is violated.
     */
    public void setFromPage(int fromPage) {
        if (fromPage <= 0 ||
            (toPage != 0 && fromPage > toPage) ||
            fromPage < minPage ||
            fromPage > maxPage) {
            throw new IllegalArgumentException("Invalid value for attribute "+
                                               "fromPage");
        }
        this.fromPage = fromPage;
    }

    /**
     * Specifies the maximum value the user can specify as the last page to
     * be printed for jobs using these attributes. This attribute cannot be
     * modified by, and is not subject to any limitations of, the
     * implementation or the target printer.
     *
     * @return  an integer greater than zero and greater than or equal
     *          to <i>minPage</i>.
     */
    public int getMaxPage() {
        return maxPage;
    }

    /**
     * Specifies the maximum value the user can specify as the last page to
     * be printed for jobs using these attributes. Not specifying this
     * attribute is equivalent to specifying <code>Integer.MAX_VALUE</code>.
     *
     * @param   maxPage an integer greater than zero and greater than or equal
     *          to <i>minPage</i>
     * @throws  IllegalArgumentException if one or more of the above
     *          conditions is violated
     */
    public void setMaxPage(int maxPage) {
        if (maxPage <= 0 || maxPage < minPage) {
            throw new IllegalArgumentException("Invalid value for attribute "+
                                               "maxPage");
        }
        this.maxPage = maxPage;
    }

    /**
     * Specifies the minimum value the user can specify as the first page to
     * be printed for jobs using these attributes. This attribute cannot be
     * modified by, and is not subject to any limitations of, the
     * implementation or the target printer.
     *
     * @return  an integer greater than zero and less than or equal
     *          to <i>maxPage</i>.
     */
    public int getMinPage() {
        return minPage;
    }

    /**
     * Specifies the minimum value the user can specify as the first page to
     * be printed for jobs using these attributes. Not specifying this
     * attribute is equivalent to specifying <code>1</code>.
     *
     * @param   minPage an integer greater than zero and less than or equal
     *          to <i>maxPage</i>.
     * @throws  IllegalArgumentException if one or more of the above
     *          conditions is violated.
     */
    public void setMinPage(int minPage) {
        if (minPage <= 0 || minPage > maxPage) {
            throw new IllegalArgumentException("Invalid value for attribute "+
                                               "minPage");
        }
        this.minPage = minPage;
    }

    /**
     * Specifies the handling of multiple copies, including collation, for
     * jobs using these attributes. This attribute is updated to the value
     * chosen by the user.
     *
     * @return
     *     MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES or
     *     MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
     */
    public MultipleDocumentHandlingType getMultipleDocumentHandling() {
        return multipleDocumentHandling;
    }

    /**
     * Specifies the handling of multiple copies, including collation, for
     * jobs using these attributes. Not specifying this attribute is equivalent
     * to specifying
     * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
     *
     * @param   multipleDocumentHandling
     *     MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_COLLATED_COPIES or
     *     MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
     * @throws  IllegalArgumentException if multipleDocumentHandling is null.
     */
    public void setMultipleDocumentHandling(MultipleDocumentHandlingType
                                            multipleDocumentHandling) {
        if (multipleDocumentHandling == null) {
            throw new IllegalArgumentException("Invalid value for attribute "+
                                               "multipleDocumentHandling");
        }
        this.multipleDocumentHandling = multipleDocumentHandling;
    }

    /**
     * Sets the handling of multiple copies, including collation, for jobs
     * using these attributes to the default. The default handling is
     * MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES.
     */
    public void setMultipleDocumentHandlingToDefault() {
        setMultipleDocumentHandling(
            MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES);
    }

    /**
     * Specifies, for jobs using these attributes, the ranges of pages to be
     * printed, if a range of pages is to be printed. All range numbers are
     * inclusive. This attribute is updated to the value chosen by the user.
     * An application should ignore this attribute on output, unless the
     * return value of the <code>getDefaultSelection</code> method is
     * DefaultSelectionType.RANGE.
     *
     * @return  an array of integer arrays of 2 elements. An array
     *          is interpreted as a range spanning all pages including and
     *          between the specified pages. Ranges must be in ascending
     *          order and must not overlap. Specified page numbers cannot be
     *          less than <i>minPage</i> nor greater than <i>maxPage</i>.
     *          For example:
     *          (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 },
     *                         new int[] { 15, 19 } }),
     *          specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19.
     */
    public int[][] getPageRanges() {
        if (pageRanges != null) {
            // Return a copy because otherwise client code could circumvent the
            // the checks made in setPageRanges by modifying the returned
            // array.
            int[][] copy = new int[pageRanges.length][2];
            for (int i = 0; i < pageRanges.length; i++) {
                copy[i][0] = pageRanges[i][0];
                copy[i][1] = pageRanges[i][1];
            }
            return copy;
        } else if (fromPage != 0 || toPage != 0) {
            int fromPage = getFromPage();
            int toPage = getToPage();
            return new int[][] { new int[] { fromPage, toPage } };
        } else {
            int minPage = getMinPage();
            return new int[][] { new int[] { minPage, minPage } };
        }
    }

    /**
     * Specifies, for jobs using these attributes, the ranges of pages to be
     * printed, if a range of pages is to be printed. All range numbers are
     * inclusive. If this attribute is not specified, then the values from the
     * fromPage and toPages attributes are used. If pageRanges and either or
     * both of fromPage and toPage are specified, pageRanges takes precedence.
     * Specifying none of pageRanges, fromPage, or toPage is equivalent to
     * calling setPageRanges(new int[][] { new int[] { <i>minPage</i>,
     *                                                 <i>minPage</i> } });
     *
     * @param   pageRanges an array of integer arrays of 2 elements. An array
     *          is interpreted as a range spanning all pages including and
     *          between the specified pages. Ranges must be in ascending
     *          order and must not overlap. Specified page numbers cannot be
     *          less than <i>minPage</i> nor greater than <i>maxPage</i>.
     *          For example:
     *          (new int[][] { new int[] { 1, 3 }, new int[] { 5, 5 },
     *                         new int[] { 15, 19 } }),
     *          specifies pages 1, 2, 3, 5, 15, 16, 17, 18, and 19. Note that
     *          (new int[][] { new int[] { 1, 1 }, new int[] { 1, 2 } }),
     *          is an invalid set of page ranges because the two ranges
     *          overlap.
     * @throws  IllegalArgumentException if one or more of the above
     *          conditions is violated.
     */
    public void setPageRanges(int[][] pageRanges) {
        String xcp = "Invalid value for attribute pageRanges";
        int first = 0;
        int last = 0;

        if (pageRanges == null) {
            throw new IllegalArgumentException(xcp);
        }

        for (int i = 0; i < pageRanges.length; i++) {
            if (pageRanges[i] == null ||
                pageRanges[i].length != 2 ||
                pageRanges[i][0] <= last ||
                pageRanges[i][1] < pageRanges[i][0]) {
                    throw new IllegalArgumentException(xcp);
            }
            last = pageRanges[i][1];
            if (first == 0) {
                first = pageRanges[i][0];
            }
        }

        if (first < minPage || last > maxPage) {
            throw new IllegalArgumentException(xcp);
        }

        // Store a copy because otherwise client code could circumvent the
        // the checks made above by holding a reference to the array and
        // modifying it after calling setPageRanges.
        int[][] copy = new int[pageRanges.length][2];
        for (int i = 0; i < pageRanges.length; i++) {
            copy[i][0] = pageRanges[i][0];
            copy[i][1] = pageRanges[i][1];
        }
        this.pageRanges = copy;
        this.prFirst = first;
        this.prLast = last;
    }

    /**
     * Returns the destination printer for jobs using these attributes. This
     * attribute is updated to the value chosen by the user.
     *
     * @return  the possibly null printer name.
     */
    public String getPrinter() {
        return printer;
    }

    /**
     * Specifies the destination printer for jobs using these attributes.
     * Default is platform-dependent and implementation-defined.
     *
     * @param   printer the possibly null printer name.
     */
    public void setPrinter(String printer) {
        this.printer = printer;
    }

    /**
     * Returns how consecutive pages should be imposed upon the sides of the
     * print medium for jobs using these attributes. SidesType.ONE_SIDED
     * imposes each consecutive page upon the same side of consecutive media
     * sheets. This imposition is sometimes called <i>simplex</i>.
     * SidesType.TWO_SIDED_LONG_EDGE imposes each consecutive pair of pages
     * upon front and back sides of consecutive media sheets, such that the
     * orientation of each pair of pages on the medium would be correct for
     * the reader as if for binding on the long edge. This imposition is
     * sometimes called <i>duplex</i>. SidesType.TWO_SIDED_SHORT_EDGE imposes
     * each consecutive pair of pages upon front and back sides of consecutive
     * media sheets, such that the orientation of each pair of pages on the
     * medium would be correct for the reader as if for binding on the short
     * edge. This imposition is sometimes called <i>tumble</i>. This attribute
     * is updated to the value chosen by the user.
     *
     * @return  SidesType.ONE_SIDED, SidesType.TWO_SIDED_LONG_EDGE, or
     *          SidesType.TWO_SIDED_SHORT_EDGE.
     */
    public SidesType getSides() {
        return sides;
    }

    /**
     * Specifies how consecutive pages should be imposed upon the sides of the
     * print medium for jobs using these attributes. SidesType.ONE_SIDED
     * imposes each consecutive page upon the same side of consecutive media
     * sheets. This imposition is sometimes called <i>simplex</i>.
     * SidesType.TWO_SIDED_LONG_EDGE imposes each consecutive pair of pages
     * upon front and back sides of consecutive media sheets, such that the
     * orientation of each pair of pages on the medium would be correct for
     * the reader as if for binding on the long edge. This imposition is
     * sometimes called <i>duplex</i>. SidesType.TWO_SIDED_SHORT_EDGE imposes
     * each consecutive pair of pages upon front and back sides of consecutive
     * media sheets, such that the orientation of each pair of pages on the
     * medium would be correct for the reader as if for binding on the short
     * edge. This imposition is sometimes called <i>tumble</i>. Not specifying
     * this attribute is equivalent to specifying SidesType.ONE_SIDED.
     *
     * @param   sides SidesType.ONE_SIDED, SidesType.TWO_SIDED_LONG_EDGE, or
     *          SidesType.TWO_SIDED_SHORT_EDGE.
     * @throws  IllegalArgumentException if sides is null.
     */
    public void setSides(SidesType sides) {
        if (sides == null) {
            throw new IllegalArgumentException("Invalid value for attribute "+
                                               "sides");
        }
        this.sides = sides;
    }

    /**
     * Sets how consecutive pages should be imposed upon the sides of the
     * print medium for jobs using these attributes to the default. The
     * default imposition is SidesType.ONE_SIDED.
     */
    public void setSidesToDefault() {
        setSides(SidesType.ONE_SIDED);
    }

    /**
     * Returns, for jobs using these attributes, the last page (inclusive)
     * to be printed, if a range of pages is to be printed. This attribute is
     * updated to the value chosen by the user. An application should ignore
     * this attribute on output, unless the return value of the <code>
     * getDefaultSelection</code> method is DefaultSelectionType.RANGE. An
     * application should honor the return value of <code>getPageRanges</code>
     * over the return value of this method, if possible.
     *
     * @return  an integer greater than zero and greater than or equal
     *          to <i>toPage</i> and greater than or equal to <i>minPage</i>
     *          and less than or equal to <i>maxPage</i>.
     */
    public int getToPage() {
        if (toPage != 0) {
            return toPage;
        } else if (fromPage != 0) {
            return fromPage;
        } else if (pageRanges != null) {
            return prLast;
        } else {
            return getMinPage();
        }
    }

    /**
     * Specifies, for jobs using these attributes, the last page (inclusive)
     * to be printed, if a range of pages is to be printed.
     * If this attribute is not specified, then the values from the pageRanges
     * attribute are used. If pageRanges and either or both of fromPage and
     * toPage are specified, pageRanges takes precedence. Specifying none of
     * pageRanges, fromPage, or toPage is equivalent to calling
     * setPageRanges(new int[][] { new int[] { <i>minPage</i> } });
     *
     * @param   toPage an integer greater than zero and greater than or equal
     *          to <i>fromPage</i> and greater than or equal to <i>minPage</i>
     *          and less than or equal to <i>maxPage</i>.
     * @throws  IllegalArgumentException if one or more of the above
     *          conditions is violated.
     */
    public void setToPage(int toPage) {
        if (toPage <= 0 ||
            (fromPage != 0 && toPage < fromPage) ||
            toPage < minPage ||
            toPage > maxPage) {
            throw new IllegalArgumentException("Invalid value for attribute "+
                                               "toPage");
        }
        this.toPage = toPage;
    }

    /**
     * Determines whether two JobAttributes are equal to each other.
     * <p>
     * Two JobAttributes are equal if and only if each of their attributes are
     * equal. Attributes of enumeration type are equal if and only if the
     * fields refer to the same unique enumeration object. A set of page
     * ranges is equal if and only if the sets are of equal length, each range
     * enumerates the same pages, and the ranges are in the same order.
     *
     * @param   obj the object whose equality will be checked.
     * @return  whether obj is equal to this JobAttribute according to the
     *          above criteria.
     */
    public boolean equals(Object obj) {
        if (!(obj instanceof JobAttributes)) {
            return false;
        }
        JobAttributes rhs = (JobAttributes)obj;

        if (fileName == null) {
            if (rhs.fileName != null) {
                return false;
            }
        } else {
            if (!fileName.equals(rhs.fileName)) {
                return false;
            }
        }

        if (pageRanges == null) {
            if (rhs.pageRanges != null) {
                return false;
            }
        } else {
            if (rhs.pageRanges == null ||
                    pageRanges.length != rhs.pageRanges.length) {
                return false;
            }
            for (int i = 0; i < pageRanges.length; i++) {
                if (pageRanges[i][0] != rhs.pageRanges[i][0] ||
                    pageRanges[i][1] != rhs.pageRanges[i][1]) {
                    return false;
                }
            }
        }

        if (printer == null) {
            if (rhs.printer != null) {
                return false;
            }
        } else {
            if (!printer.equals(rhs.printer)) {
                return false;
            }
        }

        return (copies == rhs.copies &&
                defaultSelection == rhs.defaultSelection &&
                destination == rhs.destination &&
                dialog == rhs.dialog &&
                fromPage == rhs.fromPage &&
                maxPage == rhs.maxPage &&
                minPage == rhs.minPage &&
                multipleDocumentHandling == rhs.multipleDocumentHandling &&
                prFirst == rhs.prFirst &&
                prLast == rhs.prLast &&
                sides == rhs.sides &&
                toPage == rhs.toPage);
    }

    /**
     * Returns a hash code value for this JobAttributes.
     *
     * @return  the hash code.
     */
    public int hashCode() {
        int rest = ((copies + fromPage + maxPage + minPage + prFirst + prLast +
                     toPage) * 31) << 21;
        if (pageRanges != null) {
            int sum = 0;
            for (int i = 0; i < pageRanges.length; i++) {
                sum += pageRanges[i][0] + pageRanges[i][1];
            }
            rest ^= (sum * 31) << 11;
        }
        if (fileName != null) {
            rest ^= fileName.hashCode();
        }
        if (printer != null) {
            rest ^= printer.hashCode();
        }
        return (defaultSelection.hashCode() << 6 ^
                destination.hashCode() << 5 ^
                dialog.hashCode() << 3 ^
                multipleDocumentHandling.hashCode() << 2 ^
                sides.hashCode() ^
                rest);
    }

    /**
     * Returns a string representation of this JobAttributes.
     *
     * @return  the string representation.
     */
    public String toString() {
        int[][] pageRanges = getPageRanges();
        String prStr = "[";
        boolean first = true;
        for (int i = 0; i < pageRanges.length; i++) {
            if (first) {
                first = false;
            } else {
                prStr += ",";
            }
            prStr += pageRanges[i][0] + ":" + pageRanges[i][1];
        }
        prStr += "]";

        return "copies=" + getCopies() + ",defaultSelection=" +
            getDefaultSelection() + ",destination=" + getDestination() +
            ",dialog=" + getDialog() + ",fileName=" + getFileName() +
            ",fromPage=" + getFromPage() + ",maxPage=" + getMaxPage() +
            ",minPage=" + getMinPage() + ",multiple-document-handling=" +
            getMultipleDocumentHandling() + ",page-ranges=" + prStr +
            ",printer=" + getPrinter() + ",sides=" + getSides() + ",toPage=" +
            getToPage();
    }
}
