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

package sun.print;

import java.io.FilePermission;

import java.awt.Color;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.KeyboardFocusManager;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.print.Book;
import java.awt.print.Pageable;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterAbortException;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.awt.Window;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Locale;
import sun.awt.image.ByteInterleavedRaster;

import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.ServiceUI;
import javax.print.StreamPrintService;
import javax.print.StreamPrintServiceFactory;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.Size2DSyntax;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.DialogTypeSelection;
import javax.print.attribute.standard.Fidelity;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.JobSheets;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.PrinterState;
import javax.print.attribute.standard.PrinterStateReason;
import javax.print.attribute.standard.PrinterStateReasons;
import javax.print.attribute.standard.PrinterIsAcceptingJobs;
import javax.print.attribute.standard.RequestingUserName;
import javax.print.attribute.standard.SheetCollate;
import javax.print.attribute.standard.Sides;

import sun.print.PageableDoc;
import sun.print.ServiceDialog;
import sun.print.SunPrinterJobService;
import sun.print.SunPageSelection;

/**
 * A class which rasterizes a printer job.
 *
 * @author Richard Blanchard
 */
public abstract class RasterPrinterJob extends PrinterJob {

 /* Class Constants */

     /* Printer destination type. */
    protected static final int PRINTER = 0;

     /* File destination type.  */
    protected static final int FILE = 1;

    /* Stream destination type.  */
    protected static final int STREAM = 2;

    /**
     * Maximum amount of memory in bytes to use for the
     * buffered image "band". 4Mb is a compromise between
     * limiting the number of bands on hi-res printers and
     * not using too much of the Java heap or causing paging
     * on systems with little RAM.
     */
    private static final int MAX_BAND_SIZE = (1024 * 1024 * 4);

    /* Dots Per Inch */
    private static final float DPI = 72.0f;

    /**
     * Useful mainly for debugging, this system property
     * can be used to force the printing code to print
     * using a particular pipeline. The two currently
     * supported values are FORCE_RASTER and FORCE_PDL.
     */
    private static final String FORCE_PIPE_PROP = "sun.java2d.print.pipeline";

    /**
     * When the system property FORCE_PIPE_PROP has this value
     * then each page of a print job will be rendered through
     * the raster pipeline.
     */
    private static final String FORCE_RASTER = "raster";

    /**
     * When the system property FORCE_PIPE_PROP has this value
     * then each page of a print job will be rendered through
     * the PDL pipeline.
     */
    private static final String FORCE_PDL = "pdl";

    /**
     * When the system property SHAPE_TEXT_PROP has this value
     * then text is always rendered as a shape, and no attempt is made
     * to match the font through GDI
     */
    private static final String SHAPE_TEXT_PROP = "sun.java2d.print.shapetext";

    /**
     * values obtained from System properties in static initialiser block
     */
    public static boolean forcePDL = false;
    public static boolean forceRaster = false;
    public static boolean shapeTextProp = false;

    static {
        /* The system property FORCE_PIPE_PROP
         * can be used to force the printing code to
         * use a particular pipeline. Either the raster
         * pipeline or the pdl pipeline can be forced.
         */
        String forceStr =
           (String)java.security.AccessController.doPrivileged(
                   new sun.security.action.GetPropertyAction(FORCE_PIPE_PROP));

        if (forceStr != null) {
            if (forceStr.equalsIgnoreCase(FORCE_PDL)) {
                forcePDL = true;
            } else if (forceStr.equalsIgnoreCase(FORCE_RASTER)) {
                forceRaster = true;
            }
        }

        String shapeTextStr =
           (String)java.security.AccessController.doPrivileged(
                   new sun.security.action.GetPropertyAction(SHAPE_TEXT_PROP));

        if (shapeTextStr != null) {
            shapeTextProp = true;
        }
    }

    /* Instance Variables */

    /**
     * Used to minimise GC & reallocation of band when printing
     */
    private int cachedBandWidth = 0;
    private int cachedBandHeight = 0;
    private BufferedImage cachedBand = null;

    /**
     * The number of book copies to be printed.
     */
    private int mNumCopies = 1;

    /**
     * Collation effects the order of the pages printed
     * when multiple copies are requested. For two copies
     * of a three page document the page order is:
     *  mCollate true: 1, 2, 3, 1, 2, 3
     *  mCollate false: 1, 1, 2, 2, 3, 3
     */
    private boolean mCollate = false;

    /**
     * The zero based indices of the first and last
     * pages to be printed. If 'mFirstPage' is
     * UNDEFINED_PAGE_NUM then the first page to
     * be printed is page 0. If 'mLastPage' is
     * UNDEFINED_PAGE_NUM then the last page to
     * be printed is the last one in the book.
     */
    private int mFirstPage = Pageable.UNKNOWN_NUMBER_OF_PAGES;
    private int mLastPage = Pageable.UNKNOWN_NUMBER_OF_PAGES;

    /**
     * The previous print stream Paper
     * Used to check if the paper size has changed such that the
     * implementation needs to emit the new paper size information
     * into the print stream.
     * Since we do our own rotation, and the margins aren't relevant,
     * Its strictly the dimensions of the paper that we will check.
     */
    private Paper previousPaper;

    /**
     * The document to be printed. It is initialized to an
     * empty (zero pages) book.
     */
    private Pageable mDocument = new Book();

    /**
     * The name of the job being printed.
     */
    private String mDocName = "Java Printing";


    /**
     * Printing cancellation flags
     */
    private boolean performingPrinting = false;
    private boolean userCancelled = false;

   /**
    * Print to file permission variables.
    */
    private FilePermission printToFilePermission;

    /**
     * List of areas & the graphics state for redrawing
     */
    private ArrayList redrawList = new ArrayList();


    /* variables representing values extracted from an attribute set.
     * These take precedence over values set on a printer job
     */
    private int copiesAttr;
    private String jobNameAttr;
    private String userNameAttr;
    private PageRanges pageRangesAttr;
    protected Sides sidesAttr;
    protected String destinationAttr;
    protected boolean noJobSheet = false;
    protected int mDestType = RasterPrinterJob.FILE;
    protected String mDestination = "";
    protected boolean collateAttReq = false;

    /**
     * Device rotation flag, if it support 270, this is set to true;
     */
    protected boolean landscapeRotates270 = false;

   /**
     * attributes used by no-args page and print dialog and print method to
     * communicate state
     */
    protected PrintRequestAttributeSet attributes = null;

    /**
     * Class to keep state information for redrawing areas
     * "region" is an area at as a high a resolution as possible.
     * The redrawing code needs to look at sx, sy to calculate the scale
     * to device resolution.
     */
    private class GraphicsState {
        Rectangle2D region;  // Area of page to repaint
        Shape theClip;       // image drawing clip.
        AffineTransform theTransform; // to transform clip to dev coords.
        double sx;           // X scale from region to device resolution
        double sy;           // Y scale from region to device resolution
    }

    /**
     * Service for this job
     */
    protected PrintService myService;

 /* Constructors */

    public RasterPrinterJob()
    {
    }

/* Abstract Methods */

    /**
     * Returns the resolution in dots per inch across the width
     * of the page.
     */
    abstract protected double getXRes();

    /**
     * Returns the resolution in dots per inch down the height
     * of the page.
     */
    abstract protected double getYRes();

    /**
     * Must be obtained from the current printer.
     * Value is in device pixels.
     * Not adjusted for orientation of the paper.
     */
    abstract protected double getPhysicalPrintableX(Paper p);

    /**
     * Must be obtained from the current printer.
     * Value is in device pixels.
     * Not adjusted for orientation of the paper.
     */
    abstract protected double getPhysicalPrintableY(Paper p);

    /**
     * Must be obtained from the current printer.
     * Value is in device pixels.
     * Not adjusted for orientation of the paper.
     */
    abstract protected double getPhysicalPrintableWidth(Paper p);

    /**
     * Must be obtained from the current printer.
     * Value is in device pixels.
     * Not adjusted for orientation of the paper.
     */
    abstract protected double getPhysicalPrintableHeight(Paper p);

    /**
     * Must be obtained from the current printer.
     * Value is in device pixels.
     * Not adjusted for orientation of the paper.
     */
    abstract protected double getPhysicalPageWidth(Paper p);

    /**
     * Must be obtained from the current printer.
     * Value is in device pixels.
     * Not adjusted for orientation of the paper.
     */
    abstract protected double getPhysicalPageHeight(Paper p);

    /**
     * Begin a new page.
     */
    abstract protected void startPage(PageFormat format, Printable painter,
                                      int index, boolean paperChanged)
        throws PrinterException;

    /**
     * End a page.
     */
    abstract protected void endPage(PageFormat format, Printable painter,
                                    int index)
        throws PrinterException;

    /**
     * Prints the contents of the array of ints, 'data'
     * to the current page. The band is placed at the
     * location (x, y) in device coordinates on the
     * page. The width and height of the band is
     * specified by the caller.
     */
    abstract protected void printBand(byte[] data, int x, int y,
                                      int width, int height)
        throws PrinterException;

/* Instance Methods */

    /**
      * save graphics state of a PathGraphics for later redrawing
      * of part of page represented by the region in that state
      */

    public void saveState(AffineTransform at, Shape clip,
                          Rectangle2D region, double sx, double sy) {
        GraphicsState gstate = new GraphicsState();
        gstate.theTransform = at;
        gstate.theClip = clip;
        gstate.region = region;
        gstate.sx = sx;
        gstate.sy = sy;
        redrawList.add(gstate);
    }


    /*
     * A convenience method which returns the default service
     * for 2D <code>PrinterJob</code>s.
     * May return null if there is no suitable default (although there
     * may still be 2D services available).
     * @return default 2D print service, or null.
     * @since     1.4
     */
    protected static PrintService lookupDefaultPrintService() {
        PrintService service = PrintServiceLookup.lookupDefaultPrintService();

        /* Pageable implies Printable so checking both isn't strictly needed */
        if (service != null &&
            service.isDocFlavorSupported(
                                DocFlavor.SERVICE_FORMATTED.PAGEABLE) &&
            service.isDocFlavorSupported(
                                DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
            return service;
        } else {
           PrintService []services =
             PrintServiceLookup.lookupPrintServices(
                                DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);
           if (services.length > 0) {
               return services[0];
           }
        }
        return null;
    }

   /**
     * Returns the service (printer) for this printer job.
     * Implementations of this class which do not support print services
     * may return null;
     * @return the service for this printer job.
     *
     */
    public PrintService getPrintService() {
        if (myService == null) {
            PrintService svc = PrintServiceLookup.lookupDefaultPrintService();
            if (svc != null &&
                svc.isDocFlavorSupported(
                     DocFlavor.SERVICE_FORMATTED.PAGEABLE)) {
                try {
                    setPrintService(svc);
                    myService = svc;
                } catch (PrinterException e) {
                }
            }
            if (myService == null) {
                PrintService[] svcs = PrintServiceLookup.lookupPrintServices(
                    DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);
                if (svcs.length > 0) {
                    try {
                        setPrintService(svcs[0]);
                        myService = svcs[0];
                    } catch (PrinterException e) {
                    }
                }
            }
        }
        return myService;
    }

    /**
     * Associate this PrinterJob with a new PrintService.
     *
     * Throws <code>PrinterException</code> if the specified service
     * cannot support the <code>Pageable</code> and
     * <code>Printable</code> interfaces necessary to support 2D printing.
     * @param a print service which supports 2D printing.
     *
     * @throws PrinterException if the specified service does not support
     * 2D printing or no longer available.
     */
    public void setPrintService(PrintService service)
        throws PrinterException {
        if (service == null) {
            throw new PrinterException("Service cannot be null");
        } else if (!(service instanceof StreamPrintService) &&
                   service.getName() == null) {
            throw new PrinterException("Null PrintService name.");
        } else {
            // Check the list of services.  This service may have been
            // deleted already
            PrinterState prnState = (PrinterState)service.getAttribute(
                                                  PrinterState.class);
            if (prnState == PrinterState.STOPPED) {
                PrinterStateReasons prnStateReasons =
                    (PrinterStateReasons)service.getAttribute(
                                                 PrinterStateReasons.class);
                if ((prnStateReasons != null) &&
                    (prnStateReasons.containsKey(PrinterStateReason.SHUTDOWN)))
                {
                    throw new PrinterException("PrintService is no longer available.");
                }
            }


            if (service.isDocFlavorSupported(
                                             DocFlavor.SERVICE_FORMATTED.PAGEABLE) &&
                service.isDocFlavorSupported(
                                             DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
                myService = service;
            } else {
                throw new PrinterException("Not a 2D print service: " + service);
            }
        }
    }


    protected void updatePageAttributes(PrintService service,
                                        PageFormat page) {
        if (service == null || page == null) {
            return;
        }

        float x = (float)Math.rint(
                         (page.getPaper().getWidth()*Size2DSyntax.INCH)/
                         (72.0))/(float)Size2DSyntax.INCH;
        float y = (float)Math.rint(
                         (page.getPaper().getHeight()*Size2DSyntax.INCH)/
                         (72.0))/(float)Size2DSyntax.INCH;

        // We should limit the list where we search the matching
        // media, this will prevent mapping to wrong media ex. Ledger
        // can be mapped to B.  Especially useful when creating
        // custom MediaSize.
        Media[] mediaList = (Media[])service.getSupportedAttributeValues(
                                      Media.class, null, null);
        Media media = null;
        try {
            media = CustomMediaSizeName.findMedia(mediaList, x, y,
                                   Size2DSyntax.INCH);
        } catch (IllegalArgumentException iae) {
        }
        if ((media == null) ||
             !(service.isAttributeValueSupported(media, null, null))) {
            media = (Media)service.getDefaultAttributeValue(Media.class);
        }

        OrientationRequested orient;
        switch (page.getOrientation()) {
        case PageFormat.LANDSCAPE :
            orient = OrientationRequested.LANDSCAPE;
            break;
        case PageFormat.REVERSE_LANDSCAPE:
            orient = OrientationRequested.REVERSE_LANDSCAPE;
            break;
        default:
            orient = OrientationRequested.PORTRAIT;
        }

        if (attributes == null) {
            attributes = new HashPrintRequestAttributeSet();
        }
        if (media != null) {
            attributes.add(media);
        }
        attributes.add(orient);

        float ix = (float)(page.getPaper().getImageableX()/DPI);
        float iw = (float)(page.getPaper().getImageableWidth()/DPI);
        float iy = (float)(page.getPaper().getImageableY()/DPI);
        float ih = (float)(page.getPaper().getImageableHeight()/DPI);
        if (ix < 0) ix = 0f; if (iy < 0) iy = 0f;
        try {
            attributes.add(new MediaPrintableArea(ix, iy, iw, ih,
                                                  MediaPrintableArea.INCH));
        } catch (IllegalArgumentException iae) {
        }
    }

   /**
     * Display a dialog to the user allowing the modification of a
     * PageFormat instance.
     * The <code>page</code> argument is used to initialize controls
     * in the page setup dialog.
     * If the user cancels the dialog, then the method returns the
     * original <code>page</code> object unmodified.
     * If the user okays the dialog then the method returns a new
     * PageFormat object with the indicated changes.
     * In either case the original <code>page</code> object will
     * not be modified.
     * @param     page    the default PageFormat presented to the user
     *                    for modification
     * @return    the original <code>page</code> object if the dialog
     *            is cancelled, or a new PageFormat object containing
     *            the format indicated by the user if the dialog is
     *            acknowledged
     * @exception HeadlessException if GraphicsEnvironment.isHeadless()
     * returns true.
     * @see java.awt.GraphicsEnvironment#isHeadless
     * @since     1.2
     */
    public PageFormat pageDialog(PageFormat page)
        throws HeadlessException {
        if (GraphicsEnvironment.isHeadless()) {
            throw new HeadlessException();
        }

        final GraphicsConfiguration gc =
          GraphicsEnvironment.getLocalGraphicsEnvironment().
          getDefaultScreenDevice().getDefaultConfiguration();

        PrintService service =
            (PrintService)java.security.AccessController.doPrivileged(
                                        new java.security.PrivilegedAction() {
                public Object run() {
                    PrintService service = getPrintService();
                    if (service == null) {
                        ServiceDialog.showNoPrintService(gc);
                        return null;
                    }
                    return service;
                }
            });

        if (service == null) {
            return page;
        }
        updatePageAttributes(service, page);

        PageFormat newPage = pageDialog(attributes);

        if (newPage == null) {
            return page;
        } else {
            return newPage;
        }
    }

    /**
     * return a PageFormat corresponding to the updated attributes,
     * or null if the user cancelled the dialog.
     */
    public PageFormat pageDialog(final PrintRequestAttributeSet attributes)
        throws HeadlessException {
        if (GraphicsEnvironment.isHeadless()) {
            throw new HeadlessException();
        }

        final GraphicsConfiguration gc =
            GraphicsEnvironment.getLocalGraphicsEnvironment().
            getDefaultScreenDevice().getDefaultConfiguration();
        Rectangle bounds = gc.getBounds();
        int x = bounds.x+bounds.width/3;
        int y = bounds.y+bounds.height/3;

        PrintService service =
            (PrintService)java.security.AccessController.doPrivileged(
                                        new java.security.PrivilegedAction() {
                public Object run() {
                    PrintService service = getPrintService();
                    if (service == null) {
                        ServiceDialog.showNoPrintService(gc);
                        return null;
                    }
                    return service;
                }
            });

        if (service == null) {
            return null;
        }

        ServiceDialog pageDialog = new ServiceDialog(gc, x, y, service,
                                       DocFlavor.SERVICE_FORMATTED.PAGEABLE,
                                       attributes, (Frame)null);
        pageDialog.show();

        if (pageDialog.getStatus() == ServiceDialog.APPROVE) {
            PrintRequestAttributeSet newas =
                pageDialog.getAttributes();
            Class amCategory = SunAlternateMedia.class;

            if (attributes.containsKey(amCategory) &&
                !newas.containsKey(amCategory)) {
                attributes.remove(amCategory);
            }
            attributes.addAll(newas);

            PageFormat page = defaultPage();

            OrientationRequested orient =
                (OrientationRequested)
                attributes.get(OrientationRequested.class);
            int pfOrient =  PageFormat.PORTRAIT;
            if (orient != null) {
                if (orient == OrientationRequested.REVERSE_LANDSCAPE) {
                    pfOrient = PageFormat.REVERSE_LANDSCAPE;
                } else if (orient == OrientationRequested.LANDSCAPE) {
                    pfOrient = PageFormat.LANDSCAPE;
                }
            }
            page.setOrientation(pfOrient);

            Media media = (Media)attributes.get(Media.class);
            if (media == null) {
                media =
                    (Media)service.getDefaultAttributeValue(Media.class);
            }
            if (!(media instanceof MediaSizeName)) {
                media = MediaSizeName.NA_LETTER;
            }
            MediaSize size =
                MediaSize.getMediaSizeForName((MediaSizeName)media);
            if (size == null) {
                size = MediaSize.NA.LETTER;
            }
            Paper paper = new Paper();
            float dim[] = size.getSize(1); //units == 1 to avoid FP error
            double w = Math.rint((dim[0]*72.0)/Size2DSyntax.INCH);
            double h = Math.rint((dim[1]*72.0)/Size2DSyntax.INCH);
            paper.setSize(w, h);
            MediaPrintableArea area =
                (MediaPrintableArea)
                attributes.get(MediaPrintableArea.class);
            double ix, iw, iy, ih;

            if (area != null) {
                // Should pass in same unit as updatePageAttributes
                // to avoid rounding off errors.
                ix = Math.rint(
                               area.getX(MediaPrintableArea.INCH) * DPI);
                iy = Math.rint(
                               area.getY(MediaPrintableArea.INCH) * DPI);
                iw = Math.rint(
                               area.getWidth(MediaPrintableArea.INCH) * DPI);
                ih = Math.rint(
                               area.getHeight(MediaPrintableArea.INCH) * DPI);
            }
            else {
                if (w >= 72.0 * 6.0) {
                    ix = 72.0;
                    iw = w - 2 * 72.0;
                } else {
                    ix = w / 6.0;
                    iw = w * 0.75;
                }
                if (h >= 72.0 * 6.0) {
                    iy = 72.0;
                    ih = h - 2 * 72.0;
                } else {
                    iy = h / 6.0;
                    ih = h * 0.75;
                }
            }
            paper.setImageableArea(ix, iy, iw, ih);
            page.setPaper(paper);

            return page;
        } else {
            return null;
        }
   }

   /**
     * Presents the user a dialog for changing properties of the
     * print job interactively.
     * The services browsable here are determined by the type of
     * service currently installed.
     * If the application installed a StreamPrintService on this
     * PrinterJob, only the available StreamPrintService (factories) are
     * browsable.
     *
     * @param attributes to store changed properties.
     * @return false if the user cancels the dialog and true otherwise.
     * @exception HeadlessException if GraphicsEnvironment.isHeadless()
     * returns true.
     * @see java.awt.GraphicsEnvironment#isHeadless
     */
    public boolean printDialog(final PrintRequestAttributeSet attributes)
        throws HeadlessException {
        if (GraphicsEnvironment.isHeadless()) {
            throw new HeadlessException();
        }


        DialogTypeSelection dlg =
            (DialogTypeSelection)attributes.get(DialogTypeSelection.class);

        // Check for native, note that default dialog is COMMON.
        if (dlg == DialogTypeSelection.NATIVE) {
            this.attributes = attributes;
            try {
                debug_println("calling setAttributes in printDialog");
                setAttributes(attributes);

            } catch (PrinterException e) {

            }

            boolean ret = printDialog();
            this.attributes = attributes;
            return ret;

        }


        /* A security check has already been performed in the
         * java.awt.print.printerJob.getPrinterJob method.
         * So by the time we get here, it is OK for the current thread
         * to print either to a file (from a Dialog we control!) or
         * to a chosen printer.
         *
         * We raise privilege when we put up the dialog, to avoid
         * the "warning applet window" banner.
         */
        final GraphicsConfiguration gc =
            GraphicsEnvironment.getLocalGraphicsEnvironment().
            getDefaultScreenDevice().getDefaultConfiguration();

        PrintService service =
            (PrintService)java.security.AccessController.doPrivileged(
                       new java.security.PrivilegedAction() {
                public Object run() {
                    PrintService service = getPrintService();
                    if (service == null) {
                        ServiceDialog.showNoPrintService(gc);
                        return null;
                    }
                    return service;
                }
            });

        if (service == null) {
            return false;
        }

        PrintService[] services;
        StreamPrintServiceFactory[] spsFactories = null;
        if (service instanceof StreamPrintService) {
            spsFactories = lookupStreamPrintServices(null);
            services = new StreamPrintService[spsFactories.length];
            for (int i=0; i<spsFactories.length; i++) {
                services[i] = spsFactories[i].getPrintService(null);
            }
        } else {
            services =
            (PrintService[])java.security.AccessController.doPrivileged(
                       new java.security.PrivilegedAction() {
                public Object run() {
                    PrintService[] services = PrinterJob.lookupPrintServices();
                    return services;
                }
            });

            if ((services == null) || (services.length == 0)) {
                /*
                 * No services but default PrintService exists?
                 * Create services using defaultService.
                 */
                services = new PrintService[1];
                services[0] = service;
            }
        }

        Rectangle bounds = gc.getBounds();
        int x = bounds.x+bounds.width/3;
        int y = bounds.y+bounds.height/3;
        PrintService newService;
        try {
            newService =
            ServiceUI.printDialog(gc, x, y,
                                  services, service,
                                  DocFlavor.SERVICE_FORMATTED.PAGEABLE,
                                  attributes);
        } catch (IllegalArgumentException iae) {
            newService = ServiceUI.printDialog(gc, x, y,
                                  services, services[0],
                                  DocFlavor.SERVICE_FORMATTED.PAGEABLE,
                                  attributes);
        }

        if (newService == null) {
            return false;
        }

        if (!service.equals(newService)) {
            try {
                setPrintService(newService);
            } catch (PrinterException e) {
                /*
                 * The only time it would throw an exception is when
                 * newService is no longer available but we should still
                 * select this printer.
                 */
                myService = newService;
            }
        }
        return true;
    }

   /**
     * Presents the user a dialog for changing properties of the
     * print job interactively.
     * @returns false if the user cancels the dialog and
     *          true otherwise.
     * @exception HeadlessException if GraphicsEnvironment.isHeadless()
     * returns true.
     * @see java.awt.GraphicsEnvironment#isHeadless
     */
    public boolean printDialog() throws HeadlessException {

        if (GraphicsEnvironment.isHeadless()) {
            throw new HeadlessException();
        }

        PrintRequestAttributeSet attributes =
          new HashPrintRequestAttributeSet();
        attributes.add(new Copies(getCopies()));
        attributes.add(new JobName(getJobName(), null));
        boolean doPrint = printDialog(attributes);
        if (doPrint) {
            JobName jobName = (JobName)attributes.get(JobName.class);
            if (jobName != null) {
                setJobName(jobName.getValue());
            }
            Copies copies = (Copies)attributes.get(Copies.class);
            if (copies != null) {
                setCopies(copies.getValue());
            }

            Destination dest = (Destination)attributes.get(Destination.class);

            if (dest != null) {
                try {
                    mDestType = RasterPrinterJob.FILE;
                    mDestination = (new File(dest.getURI())).getPath();
                } catch (Exception e) {
                    mDestination = "out.prn";
                    PrintService ps = getPrintService();
                    if (ps != null) {
                        Destination defaultDest = (Destination)ps.
                            getDefaultAttributeValue(Destination.class);
                        if (defaultDest != null) {
                            mDestination = (new File(defaultDest.getURI())).getPath();
                        }
                    }
                }
            } else {
                mDestType = RasterPrinterJob.PRINTER;
                PrintService ps = getPrintService();
                if (ps != null) {
                    mDestination = ps.getName();
                }
            }
        }

        return doPrint;
    }

    /**
     * The pages in the document to be printed by this PrinterJob
     * are drawn by the Printable object 'painter'. The PageFormat
     * for each page is the default page format.
     * @param Printable Called to render each page of the document.
     */
    public void setPrintable(Printable painter) {
        setPageable(new OpenBook(defaultPage(new PageFormat()), painter));
    }

    /**
     * The pages in the document to be printed by this PrinterJob
     * are drawn by the Printable object 'painter'. The PageFormat
     * of each page is 'format'.
     * @param Printable Called to render each page of the document.
     * @param PageFormat The size and orientation of each page to
     *                   be printed.
     */
    public void setPrintable(Printable painter, PageFormat format) {
        setPageable(new OpenBook(format, painter));
        updatePageAttributes(getPrintService(), format);
    }

    /**
     * The pages in the document to be printed are held by the
     * Pageable instance 'document'. 'document' will be queried
     * for the number of pages as well as the PageFormat and
     * Printable for each page.
     * @param Pageable The document to be printed. It may not be null.
     * @exception NullPointerException the Pageable passed in was null.
     * @see PageFormat
     * @see Printable
     */
    public void setPageable(Pageable document) throws NullPointerException {
        if (document != null) {
            mDocument = document;

        } else {
            throw new NullPointerException();
        }
    }

    protected void initPrinter() {
        return;
    }

    protected boolean isSupportedValue(Attribute attrval,
                                     PrintRequestAttributeSet attrset) {
        PrintService ps = getPrintService();
        return
            (attrval != null && ps != null &&
             ps.isAttributeValueSupported(attrval,
                                          DocFlavor.SERVICE_FORMATTED.PAGEABLE,
                                          attrset));
    }

    /* subclasses may need to pull extra information out of the attribute set
     * They can override this method & call super.setAttributes()
     */
    protected  void setAttributes(PrintRequestAttributeSet attributes)
        throws PrinterException {
        /*  reset all values to defaults */
        setCollated(false);
        sidesAttr = null;
        pageRangesAttr = null;
        copiesAttr = 0;
        jobNameAttr = null;
        userNameAttr = null;
        destinationAttr = null;
        collateAttReq = false;

        PrintService service = getPrintService();
        if (attributes == null  || service == null) {
            return;
        }

        boolean fidelity = false;
        Fidelity attrFidelity = (Fidelity)attributes.get(Fidelity.class);
        if (attrFidelity != null && attrFidelity == Fidelity.FIDELITY_TRUE) {
            fidelity = true;
        }

        if (fidelity == true) {
           AttributeSet unsupported =
               service.getUnsupportedAttributes(
                                         DocFlavor.SERVICE_FORMATTED.PAGEABLE,
                                         attributes);
           if (unsupported != null) {
               throw new PrinterException("Fidelity cannot be satisfied");
           }
        }

        /*
         * Since we have verified supported values if fidelity is true,
         * we can either ignore unsupported values, or substitute a
         * reasonable alternative
         */

        SheetCollate collateAttr =
            (SheetCollate)attributes.get(SheetCollate.class);
        if (isSupportedValue(collateAttr,  attributes)) {
            setCollated(collateAttr == SheetCollate.COLLATED);
        }

        sidesAttr = (Sides)attributes.get(Sides.class);
        if (!isSupportedValue(sidesAttr,  attributes)) {
            sidesAttr = Sides.ONE_SIDED;
        }

        pageRangesAttr =  (PageRanges)attributes.get(PageRanges.class);
        if (!isSupportedValue(pageRangesAttr, attributes)) {
            pageRangesAttr = null;
        } else {
            if ((SunPageSelection)attributes.get(SunPageSelection.class)
                     == SunPageSelection.RANGE) {
                // get to, from, min, max page ranges
                int[][] range = pageRangesAttr.getMembers();
                // setPageRanges uses 0-based indexing so we subtract 1
                setPageRange(range[0][0] - 1, range[0][1] - 1);
            } else {
               setPageRange(-1, - 1);
            }
        }

        Copies copies = (Copies)attributes.get(Copies.class);
        if (isSupportedValue(copies,  attributes) ||
            (!fidelity && copies != null)) {
            copiesAttr = copies.getValue();
            setCopies(copiesAttr);
        } else {
            copiesAttr = getCopies();
        }

        Destination destination =
            (Destination)attributes.get(Destination.class);

        if (isSupportedValue(destination,  attributes)) {
            try {
                // Old code (new File(destination.getURI())).getPath()
                // would generate a "URI is not hierarchical" IAE
                // for "file:out.prn" so we use getSchemeSpecificPart instead
                destinationAttr = "" + new File(destination.getURI().
                                                getSchemeSpecificPart());
            } catch (Exception e) { // paranoid exception
                Destination defaultDest = (Destination)service.
                    getDefaultAttributeValue(Destination.class);
                if (defaultDest != null) {
                    destinationAttr = "" + new File(defaultDest.getURI().
                                                getSchemeSpecificPart());
                }
            }
        }

        JobSheets jobSheets = (JobSheets)attributes.get(JobSheets.class);
        if (jobSheets != null) {
            noJobSheet = jobSheets == JobSheets.NONE;
        }

        JobName jobName = (JobName)attributes.get(JobName.class);
        if (isSupportedValue(jobName,  attributes) ||
            (!fidelity && jobName != null)) {
            jobNameAttr = jobName.getValue();
            setJobName(jobNameAttr);
        } else {
            jobNameAttr = getJobName();
        }

        RequestingUserName userName =
            (RequestingUserName)attributes.get(RequestingUserName.class);
        if (isSupportedValue(userName,  attributes) ||
            (!fidelity && userName != null)) {
            userNameAttr = userName.getValue();
        } else {
            try {
                userNameAttr = getUserName();
            } catch (SecurityException e) {
                userNameAttr = "";
            }
        }

        /* OpenBook is used internally only when app uses Printable.
         * This is the case when we use the values from the attribute set.
         */
        Media media = (Media)attributes.get(Media.class);
        OrientationRequested orientReq =
           (OrientationRequested)attributes.get(OrientationRequested.class);
        MediaPrintableArea mpa =
            (MediaPrintableArea)attributes.get(MediaPrintableArea.class);

        if ((orientReq != null || media != null || mpa != null) &&
            getPageable() instanceof OpenBook) {

            /* We could almost(!) use PrinterJob.getPageFormat() except
             * here we need to start with the PageFormat from the OpenBook :
             */
            Pageable pageable = getPageable();
            Printable printable = pageable.getPrintable(0);
            PageFormat pf = (PageFormat)pageable.getPageFormat(0).clone();
            Paper paper = pf.getPaper();

            /* If there's a media but no media printable area, we can try
             * to retrieve the default value for mpa and use that.
             */
            if (mpa == null && media != null &&
                service.
                isAttributeCategorySupported(MediaPrintableArea.class)) {
                Object mpaVals = service.
                    getSupportedAttributeValues(MediaPrintableArea.class,
                                                null, attributes);
                if (mpaVals instanceof MediaPrintableArea[] &&
                    ((MediaPrintableArea[])mpaVals).length > 0) {
                    mpa = ((MediaPrintableArea[])mpaVals)[0];
                }
            }

            if (isSupportedValue(orientReq, attributes) ||
                (!fidelity && orientReq != null)) {
                int orient;
                if (orientReq.equals(OrientationRequested.REVERSE_LANDSCAPE)) {
                    orient = PageFormat.REVERSE_LANDSCAPE;
                } else if (orientReq.equals(OrientationRequested.LANDSCAPE)) {
                    orient = PageFormat.LANDSCAPE;
                } else {
                    orient = PageFormat.PORTRAIT;
                }
                pf.setOrientation(orient);
            }

            if (isSupportedValue(media, attributes) ||
                (!fidelity && media != null)) {
                if (media instanceof MediaSizeName) {
                    MediaSizeName msn = (MediaSizeName)media;
                    MediaSize msz = MediaSize.getMediaSizeForName(msn);
                    if (msz != null) {
                        float paperWid =  msz.getX(MediaSize.INCH) * 72.0f;
                        float paperHgt =  msz.getY(MediaSize.INCH) * 72.0f;
                        paper.setSize(paperWid, paperHgt);
                        if (mpa == null) {
                            paper.setImageableArea(72.0, 72.0,
                                                   paperWid-144.0,
                                                   paperHgt-144.0);
                        }
                    }
                }
            }

            if (isSupportedValue(mpa, attributes) ||
                (!fidelity && mpa != null)) {
                float [] printableArea =
                    mpa.getPrintableArea(MediaPrintableArea.INCH);
                for (int i=0; i < printableArea.length; i++) {
                    printableArea[i] = printableArea[i]*72.0f;
                }
                paper.setImageableArea(printableArea[0], printableArea[1],
                                       printableArea[2], printableArea[3]);
            }

            pf.setPaper(paper);
            pf = validatePage(pf);
            setPrintable(printable, pf);
        } else {
            // for AWT where pageable is not an instance of OpenBook,
            // we need to save paper info
            this.attributes = attributes;
        }

    }

    /*
     * Services we don't recognize as built-in services can't be
     * implemented as subclasses of PrinterJob, therefore we create
     * a DocPrintJob from their service and pass a Doc representing
     * the application's printjob
     */
    private void spoolToService(PrintService psvc,
                                PrintRequestAttributeSet attributes)
        throws PrinterException {

        if (psvc == null) {
            throw new PrinterException("No print service found.");
        }

        DocPrintJob job = psvc.createPrintJob();
        Doc doc = new PageableDoc(getPageable());
        if (attributes == null) {
            attributes = new HashPrintRequestAttributeSet();
        }
        try {
            job.print(doc, attributes);
        } catch (PrintException e) {
            throw new PrinterException(e.toString());
        }
    }

    /**
     * Prints a set of pages.
     * @exception java.awt.print.PrinterException an error in the print system
     *                                          caused the job to be aborted
     * @see java.awt.print.Book
     * @see java.awt.print.Pageable
     * @see java.awt.print.Printable
     */
    public void print() throws PrinterException {
        print(attributes);
    }

    public static boolean debugPrint = false;
    protected void debug_println(String str) {
        if (debugPrint) {
            System.out.println("RasterPrinterJob "+str+" "+this);
        }
    }

    public void print(PrintRequestAttributeSet attributes)
        throws PrinterException {

        /*
         * In the future PrinterJob will probably always dispatch
         * the print job to the PrintService.
         * This is how third party 2D Print Services will be invoked
         * when applications use the PrinterJob API.
         * However the JRE's concrete PrinterJob implementations have
         * not yet been re-worked to be implemented as standalone
         * services, and are implemented only as subclasses of PrinterJob.
         * So here we dispatch only those services we do not recognize
         * as implemented through platform subclasses of PrinterJob
         * (and this class).
         */
        PrintService psvc = getPrintService();
        debug_println("psvc = "+psvc);
        if (psvc == null) {
            throw new PrinterException("No print service found.");
        }

        // Check the list of services.  This service may have been
        // deleted already
        PrinterState prnState = (PrinterState)psvc.getAttribute(
                                                  PrinterState.class);
        if (prnState == PrinterState.STOPPED) {
            PrinterStateReasons prnStateReasons =
                    (PrinterStateReasons)psvc.getAttribute(
                                                 PrinterStateReasons.class);
                if ((prnStateReasons != null) &&
                    (prnStateReasons.containsKey(PrinterStateReason.SHUTDOWN)))
                {
                    throw new PrinterException("PrintService is no longer available.");
                }
        }

        if ((PrinterIsAcceptingJobs)(psvc.getAttribute(
                         PrinterIsAcceptingJobs.class)) ==
                         PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS) {
            throw new PrinterException("Printer is not accepting job.");
        }

        if ((psvc instanceof SunPrinterJobService) &&
            ((SunPrinterJobService)psvc).usesClass(getClass())) {
            setAttributes(attributes);
            // throw exception for invalid destination
            if (destinationAttr != null) {
                // destinationAttr is null for Destination(new URI(""))
                // because isAttributeValueSupported returns false in setAttributes

                // Destination(new URI(" ")) throws URISyntaxException
                File f = new File(destinationAttr);
                try {
                    // check if this is a new file and if filename chars are valid
                    if (f.createNewFile()) {
                        f.delete();
                    }
                } catch (IOException ioe) {
                    throw new PrinterException("Cannot write to file:"+
                                               destinationAttr);
                } catch (SecurityException se) {
                    //There is already file read/write access so at this point
                    // only delete access is denied.  Just ignore it because in
                    // most cases the file created in createNewFile gets overwritten
                    // anyway.
                }

                File pFile = f.getParentFile();
                if ((f.exists() &&
                     (!f.isFile() || !f.canWrite())) ||
                    ((pFile != null) &&
                     (!pFile.exists() || (pFile.exists() && !pFile.canWrite())))) {
                    throw new PrinterException("Cannot write to file:"+
                                               destinationAttr);
                }
            }
        } else {
            spoolToService(psvc, attributes);
            return;
        }
        /* We need to make sure that the collation and copies
         * settings are initialised */
        initPrinter();

        int numCollatedCopies = getCollatedCopies();
        int numNonCollatedCopies = getNoncollatedCopies();
        debug_println("getCollatedCopies()  "+numCollatedCopies
              + " getNoncollatedCopies() "+ numNonCollatedCopies);

        /* Get the range of pages we are to print. If the
         * last page to print is unknown, then we print to
         * the end of the document. Note that firstPage
         * and lastPage are 0 based page indices.
         */
        int numPages = mDocument.getNumberOfPages();
        if (numPages == 0) {
            return;
        }

        int firstPage = getFirstPage();
        int lastPage = getLastPage();
        if(lastPage == Pageable.UNKNOWN_NUMBER_OF_PAGES){
            int totalPages = mDocument.getNumberOfPages();
            if (totalPages != Pageable.UNKNOWN_NUMBER_OF_PAGES) {
                lastPage = mDocument.getNumberOfPages() - 1;
            }
        }

        try {
            synchronized (this) {
                performingPrinting = true;
                userCancelled = false;
            }

            startDoc();
            if (isCancelled()) {
                cancelDoc();
            }

            // PageRanges can be set even if RANGE is not selected
            // so we need to check if it is selected.
            boolean rangeIsSelected = true;
            if (attributes != null) {
                SunPageSelection pages =
                    (SunPageSelection)attributes.get(SunPageSelection.class);
                if ((pages != null) && (pages != SunPageSelection.RANGE)) {
                    rangeIsSelected = false;
                }
            }


            debug_println("after startDoc rangeSelected? "+rangeIsSelected
                      + " numNonCollatedCopies "+ numNonCollatedCopies);


            /* Three nested loops iterate over the document. The outer loop
             * counts the number of collated copies while the inner loop
             * counts the number of nonCollated copies. Normally, one of
             * these two loops will only execute once; that is we will
             * either print collated copies or noncollated copies. The
             * middle loop iterates over the pages.
             * If a PageRanges attribute is used, it constrains the pages
             * that are imaged. If a platform subclass (though a user dialog)
             * requests a page range via setPageRange(). it too can
             * constrain the page ranges that are imaged.
             * It is expected that only one of these will be used in a
             * job but both should be able to co-exist.
             */
            for(int collated = 0; collated < numCollatedCopies; collated++) {
                for(int i = firstPage, pageResult = Printable.PAGE_EXISTS;
                    (i <= lastPage ||
                     lastPage == Pageable.UNKNOWN_NUMBER_OF_PAGES)
                    && pageResult == Printable.PAGE_EXISTS;
                    i++)
                {

                    if ((pageRangesAttr != null) && rangeIsSelected ){
                        int nexti = pageRangesAttr.next(i);
                        if (nexti == -1) {
                            break;
                        } else if (nexti != i+1) {
                            continue;
                        }
                    }

                    for(int nonCollated = 0;
                        nonCollated < numNonCollatedCopies
                        && pageResult == Printable.PAGE_EXISTS;
                        nonCollated++)
                    {
                        if (isCancelled()) {
                            cancelDoc();
                        }
                        debug_println("printPage "+i);
                        pageResult = printPage(mDocument, i);

                    }
                }
            }

            if (isCancelled()) {
                cancelDoc();
            }

        } finally {
            // reset previousPaper in case this job is invoked again.
            previousPaper = null;
            synchronized (this) {
                if (performingPrinting) {
                    endDoc();
                }
                performingPrinting = false;
                notify();
            }
        }
    }

    /**
     * updates a Paper object to reflect the current printer's selected
     * paper size and imageable area for that paper size.
     * Default implementation copies settings from the original, applies
     * applies some validity checks, changes them only if they are
     * clearly unreasonable, then sets them into the new Paper.
     * Subclasses are expected to override this method to make more
     * informed decisons.
     */
    protected void validatePaper(Paper origPaper, Paper newPaper) {
        if (origPaper == null || newPaper == null) {
            return;
        } else {
            double wid = origPaper.getWidth();
            double hgt = origPaper.getHeight();
            double ix = origPaper.getImageableX();
            double iy = origPaper.getImageableY();
            double iw = origPaper.getImageableWidth();
            double ih = origPaper.getImageableHeight();

            /* Assume any +ve values are legal. Overall paper dimensions
             * take precedence. Make sure imageable area fits on the paper.
             */
            Paper defaultPaper = new Paper();
            wid = ((wid > 0.0) ? wid : defaultPaper.getWidth());
            hgt = ((hgt > 0.0) ? hgt : defaultPaper.getHeight());
            ix = ((ix > 0.0) ? ix : defaultPaper.getImageableX());
            iy = ((iy > 0.0) ? iy : defaultPaper.getImageableY());
            iw = ((iw > 0.0) ? iw : defaultPaper.getImageableWidth());
            ih = ((ih > 0.0) ? ih : defaultPaper.getImageableHeight());
            /* full width/height is not likely to be imageable, but since we
             * don't know the limits we have to allow it
             */
            if (iw > wid) {
                iw = wid;
            }
            if (ih > hgt) {
                ih = hgt;
            }
            if ((ix + iw) > wid) {
                ix = wid - iw;
            }
            if ((iy + ih) > hgt) {
                iy = hgt - ih;
            }
            newPaper.setSize(wid, hgt);
            newPaper.setImageableArea(ix, iy, iw, ih);
        }
    }

    /**
     * The passed in PageFormat will be copied and altered to describe
     * the default page size and orientation of the PrinterJob's
     * current printer.
     * Platform subclasses which can access the actual default paper size
     * for a printer may override this method.
     */
    public PageFormat defaultPage(PageFormat page) {
        PageFormat newPage = (PageFormat)page.clone();
        newPage.setOrientation(PageFormat.PORTRAIT);
        Paper newPaper = new Paper();
        double ptsPerInch = 72.0;
        double w, h;
        Media media = null;

        PrintService service = getPrintService();
        if (service != null) {
            MediaSize size;
            media =
                (Media)service.getDefaultAttributeValue(Media.class);

            if (media instanceof MediaSizeName &&
               ((size = MediaSize.getMediaSizeForName((MediaSizeName)media)) !=
                null)) {
                w =  size.getX(MediaSize.INCH) * ptsPerInch;
                h =  size.getY(MediaSize.INCH) * ptsPerInch;
                newPaper.setSize(w, h);
                newPaper.setImageableArea(ptsPerInch, ptsPerInch,
                                          w - 2.0*ptsPerInch,
                                          h - 2.0*ptsPerInch);
                newPage.setPaper(newPaper);
                return newPage;

            }
        }

        /* Default to A4 paper outside North America.
         */
        String defaultCountry = Locale.getDefault().getCountry();
        if (!Locale.getDefault().equals(Locale.ENGLISH) && // ie "C"
            defaultCountry != null &&
            !defaultCountry.equals(Locale.US.getCountry()) &&
            !defaultCountry.equals(Locale.CANADA.getCountry())) {

            double mmPerInch = 25.4;
            w = Math.rint((210.0*ptsPerInch)/mmPerInch);
            h = Math.rint((297.0*ptsPerInch)/mmPerInch);
            newPaper.setSize(w, h);
            newPaper.setImageableArea(ptsPerInch, ptsPerInch,
                                      w - 2.0*ptsPerInch,
                                      h - 2.0*ptsPerInch);
        }

        newPage.setPaper(newPaper);

        return newPage;
    }

    /**
     * The passed in PageFormat is cloned and altered to be usable on
     * the PrinterJob's current printer.
     */
    public PageFormat validatePage(PageFormat page) {
        PageFormat newPage = (PageFormat)page.clone();
        Paper newPaper = new Paper();
        validatePaper(newPage.getPaper(), newPaper);
        newPage.setPaper(newPaper);

        return newPage;
    }

    /**
     * Set the number of copies to be printed.
     */
    public void setCopies(int copies) {
        mNumCopies = copies;
    }

    /**
     * Get the number of copies to be printed.
     */
    public int getCopies() {
        return mNumCopies;
    }

   /* Used when executing a print job where an attribute set may
     * over ride API values.
     */
    protected int getCopiesInt() {
        return (copiesAttr > 0) ? copiesAttr : getCopies();
    }

    /**
     * Get the name of the printing user.
     * The caller must have security permission to read system properties.
     */
    public String getUserName() {
        return System.getProperty("user.name");
    }

   /* Used when executing a print job where an attribute set may
     * over ride API values.
     */
    protected String getUserNameInt() {
        if  (userNameAttr != null) {
            return userNameAttr;
        } else {
            try {
                return  getUserName();
            } catch (SecurityException e) {
                return "";
            }
        }
    }

    /**
     * Set the name of the document to be printed.
     * The document name can not be null.
     */
    public void setJobName(String jobName) {
        if (jobName != null) {
            mDocName = jobName;
        } else {
            throw new NullPointerException();
        }
    }

    /**
     * Get the name of the document to be printed.
     */
    public String getJobName() {
        return mDocName;
    }

    /* Used when executing a print job where an attribute set may
     * over ride API values.
     */
    protected String getJobNameInt() {
        return (jobNameAttr != null) ? jobNameAttr : getJobName();
    }

    /**
     * Set the range of pages from a Book to be printed.
     * Both 'firstPage' and 'lastPage' are zero based
     * page indices. If either parameter is less than
     * zero then the page range is set to be from the
     * first page to the last.
     */
    protected void setPageRange(int firstPage, int lastPage) {
        if(firstPage >= 0 && lastPage >= 0) {
            mFirstPage = firstPage;
            mLastPage = lastPage;
            if(mLastPage < mFirstPage) mLastPage = mFirstPage;
        } else {
            mFirstPage = Pageable.UNKNOWN_NUMBER_OF_PAGES;
            mLastPage = Pageable.UNKNOWN_NUMBER_OF_PAGES;
        }
    }

    /**
     * Return the zero based index of the first page to
     * be printed in this job.
     */
    protected int getFirstPage() {
        return mFirstPage == Book.UNKNOWN_NUMBER_OF_PAGES ? 0 : mFirstPage;
    }

    /**
     * Return the zero based index of the last page to
     * be printed in this job.
     */
    protected int getLastPage() {
        return mLastPage;
    }

    /**
     * Set whether copies should be collated or not.
     * Two collated copies of a three page document
     * print in this order: 1, 2, 3, 1, 2, 3 while
     * uncollated copies print in this order:
     * 1, 1, 2, 2, 3, 3.
     * This is set when request is using an attribute set.
     */
    protected void setCollated(boolean collate) {
        mCollate = collate;
        collateAttReq = true;
    }

    /**
     * Return true if collated copies will be printed as determined
     * in an attribute set.
     */
    protected boolean isCollated() {
            return mCollate;
    }

    /**
     * Called by the print() method at the start of
     * a print job.
     */
    protected abstract void startDoc() throws PrinterException;

    /**
     * Called by the print() method at the end of
     * a print job.
     */
    protected abstract void endDoc() throws PrinterException;

    /* Called by cancelDoc */
    protected abstract void abortDoc();

    private void cancelDoc() throws PrinterAbortException {
        abortDoc();
        synchronized (this) {
            userCancelled = false;
            performingPrinting = false;
            notify();
        }
        throw new PrinterAbortException();
    }

    /**
     * Returns how many times the entire book should
     * be printed by the PrintJob. If the printer
     * itself supports collation then this method
     * should return 1 indicating that the entire
     * book need only be printed once and the copies
     * will be collated and made in the printer.
     */
    protected int getCollatedCopies() {
        return isCollated() ? getCopiesInt() : 1;
    }

    /**
     * Returns how many times each page in the book
     * should be consecutively printed by PrintJob.
     * If the printer makes copies itself then this
     * method should return 1.
     */
    protected int getNoncollatedCopies() {
        return isCollated() ? 1 : getCopiesInt();
    }


    /* The printer graphics config is cached on the job, so that it can
     * be created once, and updated only as needed (for now only to change
     * the bounds if when using a Pageable the page sizes changes).
     */

    private int deviceWidth, deviceHeight;
    private AffineTransform defaultDeviceTransform;
    private PrinterGraphicsConfig pgConfig;

    synchronized void setGraphicsConfigInfo(AffineTransform at,
                                            double pw, double ph) {
        Point2D.Double pt = new Point2D.Double(pw, ph);
        at.transform(pt, pt);

        if (pgConfig == null ||
            defaultDeviceTransform == null ||
            !at.equals(defaultDeviceTransform) ||
            deviceWidth != (int)pt.getX() ||
            deviceHeight != (int)pt.getY()) {

                deviceWidth = (int)pt.getX();
                deviceHeight = (int)pt.getY();
                defaultDeviceTransform = at;
                pgConfig = null;
        }
    }

    synchronized PrinterGraphicsConfig getPrinterGraphicsConfig() {
        if (pgConfig != null) {
            return pgConfig;
        }
        String deviceID = "Printer Device";
        PrintService service = getPrintService();
        if (service != null) {
            deviceID = service.toString();
        }
        pgConfig = new PrinterGraphicsConfig(deviceID,
                                             defaultDeviceTransform,
                                             deviceWidth, deviceHeight);
        return pgConfig;
    }

    /**
     * Print a page from the provided document.
     * @return int Printable.PAGE_EXISTS if the page existed and was drawn and
     *             Printable.NO_SUCH_PAGE if the page did not exist.
     * @see java.awt.print.Printable
     */
    protected int printPage(Pageable document, int pageIndex)
        throws PrinterException
    {
        PageFormat page;
        PageFormat origPage;
        Printable painter;
        try {
            origPage = document.getPageFormat(pageIndex);
            page = (PageFormat)origPage.clone();
            painter = document.getPrintable(pageIndex);
        } catch (Exception e) {
            PrinterException pe =
                    new PrinterException("Error getting page or printable.[ " +
                                          e +" ]");
            pe.initCause(e);
            throw pe;
        }

        /* Get the imageable area from Paper instead of PageFormat
         * because we do not want it adjusted by the page orientation.
         */
        Paper paper = page.getPaper();
        // if non-portrait and 270 degree landscape rotation
        if (page.getOrientation() != PageFormat.PORTRAIT &&
            landscapeRotates270) {

            double left = paper.getImageableX();
            double top = paper.getImageableY();
            double width = paper.getImageableWidth();
            double height = paper.getImageableHeight();
            paper.setImageableArea(paper.getWidth()-left-width,
                                   paper.getHeight()-top-height,
                                   width, height);
            page.setPaper(paper);
            if (page.getOrientation() == PageFormat.LANDSCAPE) {
                page.setOrientation(PageFormat.REVERSE_LANDSCAPE);
            } else {
                page.setOrientation(PageFormat.LANDSCAPE);
            }
        }

        double xScale = getXRes() / 72.0;
        double yScale = getYRes() / 72.0;

        /* The deviceArea is the imageable area in the printer's
         * resolution.
         */
        Rectangle2D deviceArea =
            new Rectangle2D.Double(paper.getImageableX() * xScale,
                                   paper.getImageableY() * yScale,
                                   paper.getImageableWidth() * xScale,
                                   paper.getImageableHeight() * yScale);

        /* Build and hold on to a uniform transform so that
         * we can get back to device space at the beginning
         * of each band.
         */
        AffineTransform uniformTransform = new AffineTransform();

        /* The scale transform is used to switch from the
         * device space to the user's 72 dpi space.
         */
        AffineTransform scaleTransform = new AffineTransform();
        scaleTransform.scale(xScale, yScale);

        /* bandwidth is multiple of 4 as the data is used in a win32 DIB and
         * some drivers behave badly if scanlines aren't multiples of 4 bytes.
         */
        int bandWidth = (int) deviceArea.getWidth();
        if (bandWidth % 4 != 0) {
            bandWidth += (4 - (bandWidth % 4));
        }
        if (bandWidth <= 0) {
            throw new PrinterException("Paper's imageable width is too small.");
        }

        int deviceAreaHeight = (int)deviceArea.getHeight();
        if (deviceAreaHeight <= 0) {
            throw new PrinterException("Paper's imageable height is too small.");
        }

        /* Figure out the number of lines that will fit into
         * our maximum band size. The hard coded 3 reflects the
         * fact that we can only create 24 bit per pixel 3 byte BGR
         * BufferedImages. FIX.
         */
        int bandHeight = (int)(MAX_BAND_SIZE / bandWidth / 3);

        int deviceLeft = (int)Math.rint(paper.getImageableX() * xScale);
        int deviceTop  = (int)Math.rint(paper.getImageableY() * yScale);

        /* The device transform is used to move the band down
         * the page using translates. Normally this is all it
         * would do, but since, when printing, the Window's
         * DIB format wants the last line to be first (lowest) in
         * memory, the deviceTransform moves the origin to the
         * bottom of the band and flips the origin. This way the
         * app prints upside down into the band which is the DIB
         * format.
         */
        AffineTransform deviceTransform = new AffineTransform();
        deviceTransform.translate(-deviceLeft, deviceTop);
        deviceTransform.translate(0, bandHeight);
        deviceTransform.scale(1, -1);

        /* Create a BufferedImage to hold the band. We set the clip
         * of the band to be tight around the bits so that the
         * application can use it to figure what part of the
         * page needs to be drawn. The clip is never altered in
         * this method, but we do translate the band's coordinate
         * system so that the app will see the clip moving down the
         * page though it s always around the same set of pixels.
         */
        BufferedImage pBand = new BufferedImage(1, 1,
                                                BufferedImage.TYPE_3BYTE_BGR);

        /* Have the app draw into a PeekGraphics object so we can
         * learn something about the needs of the print job.
         */

        PeekGraphics peekGraphics = createPeekGraphics(pBand.createGraphics(),
                                                       this);

        Rectangle2D.Double pageFormatArea =
            new Rectangle2D.Double(page.getImageableX(),
                                   page.getImageableY(),
                                   page.getImageableWidth(),
                                   page.getImageableHeight());
        peekGraphics.transform(scaleTransform);
        peekGraphics.translate(-getPhysicalPrintableX(paper) / xScale,
                               -getPhysicalPrintableY(paper) / yScale);
        peekGraphics.transform(new AffineTransform(page.getMatrix()));
        initPrinterGraphics(peekGraphics, pageFormatArea);
        AffineTransform pgAt = peekGraphics.getTransform();

        /* Update the information used to return a GraphicsConfiguration
         * for this printer device. It needs to be updated per page as
         * not all pages in a job may be the same size (different bounds)
         * The transform is the scaling transform as this corresponds to
         * the default transform for the device. The width and height are
         * those of the paper, not the page format, as we want to describe
         * the bounds of the device in its natural coordinate system of
         * device coordinate whereas a page format may be in a rotated context.
         */
        setGraphicsConfigInfo(scaleTransform,
                              paper.getWidth(), paper.getHeight());
        int pageResult = painter.print(peekGraphics, origPage, pageIndex);
        debug_println("pageResult "+pageResult);
        if (pageResult == Printable.PAGE_EXISTS) {
            debug_println("startPage "+pageIndex);

            /* We need to check if the paper size is changed.
             * Note that it is not sufficient to ask for the pageformat
             * of "pageIndex-1", since PageRanges mean that pages can be
             * skipped. So we have to look at the actual last paper size used.
             */
            Paper thisPaper = page.getPaper();
            boolean paperChanged =
                previousPaper == null ||
                thisPaper.getWidth() != previousPaper.getWidth() ||
                thisPaper.getHeight() != previousPaper.getHeight();
            previousPaper = thisPaper;

            startPage(page, painter, pageIndex, paperChanged);
            Graphics2D pathGraphics = createPathGraphics(peekGraphics, this,
                                                         painter, page,
                                                         pageIndex);

            /* If we can convert the page directly to the
             * underlying graphics system then we do not
             * need to rasterize. We also may not need to
             * create the 'band' if all the pages can take
             * this path.
             */
            if (pathGraphics != null) {
                pathGraphics.transform(scaleTransform);
                // user (0,0) should be origin of page, not imageable area
                pathGraphics.translate(-getPhysicalPrintableX(paper) / xScale,
                                       -getPhysicalPrintableY(paper) / yScale);
                pathGraphics.transform(new AffineTransform(page.getMatrix()));
                initPrinterGraphics(pathGraphics, pageFormatArea);

                redrawList.clear();

                AffineTransform initialTx = pathGraphics.getTransform();

                painter.print(pathGraphics, origPage, pageIndex);

                for (int i=0;i<redrawList.size();i++) {
                   GraphicsState gstate = (GraphicsState)redrawList.get(i);
                   pathGraphics.setTransform(initialTx);
                   ((PathGraphics)pathGraphics).redrawRegion(
                                                         gstate.region,
                                                         gstate.sx,
                                                         gstate.sy,
                                                         gstate.theClip,
                                                         gstate.theTransform);
                }

            /* This is the banded-raster printing loop.
             * It should be moved into its own method.
             */
            } else {
                BufferedImage band = cachedBand;
                if (cachedBand == null ||
                    bandWidth != cachedBandWidth ||
                    bandHeight != cachedBandHeight) {
                    band = new BufferedImage(bandWidth, bandHeight,
                                             BufferedImage.TYPE_3BYTE_BGR);
                    cachedBand = band;
                    cachedBandWidth = bandWidth;
                    cachedBandHeight = bandHeight;
                }
                Graphics2D bandGraphics = band.createGraphics();

                Rectangle2D.Double clipArea =
                    new Rectangle2D.Double(0, 0, bandWidth, bandHeight);

                initPrinterGraphics(bandGraphics, clipArea);

                ProxyGraphics2D painterGraphics =
                    new ProxyGraphics2D(bandGraphics, this);

                Graphics2D clearGraphics = band.createGraphics();
                clearGraphics.setColor(Color.white);

                /* We need the actual bits of the BufferedImage to send to
                 * the native Window's code. 'data' points to the actual
                 * pixels. Right now these are in ARGB format with 8 bits
                 * per component. We need to use a monochrome BufferedImage
                 * for monochrome printers when this is supported by
                 * BufferedImage. FIX
                 */
                ByteInterleavedRaster tile = (ByteInterleavedRaster)band.getRaster();
                byte[] data = tile.getDataStorage();

                /* Loop over the page moving our band down the page,
                 * calling the app to render the band, and then send the band
                 * to the printer.
                 */
                int deviceBottom = deviceTop + deviceAreaHeight;

                /* device's printable x,y is really addressable origin
                 * we address relative to media origin so when we print a
                 * band we need to adjust for the different methods of
                 * addressing it.
                 */
                int deviceAddressableX = (int)getPhysicalPrintableX(paper);
                int deviceAddressableY = (int)getPhysicalPrintableY(paper);

                for (int bandTop = 0; bandTop <= deviceAreaHeight;
                     bandTop += bandHeight)
                {

                    /* Put the band back into device space and
                     * erase the contents of the band.
                     */
                    clearGraphics.fillRect(0, 0, bandWidth, bandHeight);

                    /* Put the band into the correct location on the
                     * page. Once the band is moved we translate the
                     * device transform so that the band will move down
                     * the page on the next iteration of the loop.
                     */
                    bandGraphics.setTransform(uniformTransform);
                    bandGraphics.transform(deviceTransform);
                    deviceTransform.translate(0, -bandHeight);

                    /* Switch the band from device space to user,
                     * 72 dpi, space.
                     */
                    bandGraphics.transform(scaleTransform);
                    bandGraphics.transform(new AffineTransform(page.getMatrix()));

                    Rectangle clip = bandGraphics.getClipBounds();
                    clip = pgAt.createTransformedShape(clip).getBounds();

                    if ((clip == null) || peekGraphics.hitsDrawingArea(clip) &&
                        (bandWidth > 0 && bandHeight > 0)) {

                        /* if the client has specified an imageable X or Y
                         * which is off than the physically addressable
                         * area of the page, then we need to adjust for that
                         * here so that we pass only non -ve band coordinates
                         * We also need to translate by the adjusted amount
                         * so that printing appears in the correct place.
                         */
                        int bandX = deviceLeft - deviceAddressableX;
                        if (bandX < 0) {
                            bandGraphics.translate(bandX/xScale,0);
                            bandX = 0;
                        }
                        int bandY = deviceTop + bandTop - deviceAddressableY;
                        if (bandY < 0) {
                            bandGraphics.translate(0,bandY/yScale);
                            bandY = 0;
                        }
                        /* Have the app's painter image into the band
                         * and then send the band to the printer.
                         */
                        painterGraphics.setDelegate((Graphics2D) bandGraphics.create());
                        painter.print(painterGraphics, origPage, pageIndex);
                        painterGraphics.dispose();
                        printBand(data, bandX, bandY, bandWidth, bandHeight);
                    }
                }

                clearGraphics.dispose();
                bandGraphics.dispose();

            }
            debug_println("calling endPage "+pageIndex);
            endPage(page, painter, pageIndex);
        }

        return pageResult;
    }

    /**
     * If a print job is in progress, print() has been
     * called but has not returned, then this signals
     * that the job should be cancelled and the next
     * chance. If there is no print job in progress then
     * this call does nothing.
     */
    public void cancel() {
        synchronized (this) {
            if (performingPrinting) {
                userCancelled = true;
            }
            notify();
        }
    }

    /**
     * Returns true is a print job is ongoing but will
     * be cancelled and the next opportunity. false is
     * returned otherwise.
     */
    public boolean isCancelled() {

        boolean cancelled = false;

        synchronized (this) {
            cancelled = (performingPrinting && userCancelled);
            notify();
        }

        return cancelled;
    }

    /**
     * Return the Pageable describing the pages to be printed.
     */
    protected Pageable getPageable() {
        return mDocument;
    }

    /**
     * Examine the metrics captured by the
     * <code>PeekGraphics</code> instance and
     * if capable of directly converting this
     * print job to the printer's control language
     * or the native OS's graphics primitives, then
     * return a <code>PathGraphics</code> to perform
     * that conversion. If there is not an object
     * capable of the conversion then return
     * <code>null</code>. Returning <code>null</code>
     * causes the print job to be rasterized.
     */
    protected Graphics2D createPathGraphics(PeekGraphics graphics,
                                            PrinterJob printerJob,
                                            Printable painter,
                                            PageFormat pageFormat,
                                            int pageIndex) {

        return null;
    }

    /**
     * Create and return an object that will
     * gather and hold metrics about the print
     * job. This method is passed a <code>Graphics2D</code>
     * object that can be used as a proxy for the
     * object gathering the print job matrics. The
     * method is also supplied with the instance
     * controlling the print job, <code>printerJob</code>.
     */
    protected PeekGraphics createPeekGraphics(Graphics2D graphics,
                                              PrinterJob printerJob) {

        return new PeekGraphics(graphics, printerJob);
    }

    /**
     * Configure the passed in Graphics2D so that
     * is contains the defined initial settings
     * for a print job. These settings are:
     *      color:  black.
     *      clip:   <as passed in>
     */
    void initPrinterGraphics(Graphics2D g, Rectangle2D clip) {

        g.setClip(clip);
        g.setPaint(Color.black);
    }


   /**
    * User dialogs should disable "File" buttons if this returns false.
    *
    */
    public boolean checkAllowedToPrintToFile() {
        try {
            throwPrintToFile();
            return true;
        } catch (SecurityException e) {
            return false;
        }
    }

    /**
     * Break this out as it may be useful when we allow API to
     * specify printing to a file. In that case its probably right
     * to throw a SecurityException if the permission is not granted
     */
    private void throwPrintToFile() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            if (printToFilePermission == null) {
                printToFilePermission =
                    new FilePermission("<<ALL FILES>>", "read,write");
            }
            security.checkPermission(printToFilePermission);
        }
    }

    /* On-screen drawString renders most control chars as the missing glyph
     * and have the non-zero advance of that glyph.
     * Exceptions are \t, \n and \r which are considered zero-width.
     * This is a utility method used by subclasses to remove them so we
     * don't have to worry about platform or font specific handling of them.
     */
    protected String removeControlChars(String s) {
        char[] in_chars = s.toCharArray();
        int len = in_chars.length;
        char[] out_chars = new char[len];
        int pos = 0;

        for (int i = 0; i < len; i++) {
            char c = in_chars[i];
            if (c > '\r' || c < '\t' || c == '\u000b' || c == '\u000c')  {
               out_chars[pos++] = c;
            }
        }
        if (pos == len) {
            return s; // no need to make a new String.
        } else {
            return new String(out_chars, 0, pos);
        }
    }
}
