/*
 * Copyright 2000-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 sun.print;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import java.util.Vector;

import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.ServiceUIFactory;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.AttributeSetUtilities;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.HashAttributeSet;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.HashPrintServiceAttributeSet;
import javax.print.attribute.standard.PrinterName;
import javax.print.attribute.standard.PrinterIsAcceptingJobs;
import javax.print.attribute.standard.QueuedJobCount;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.RequestingUserName;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.CopiesSupported;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.Fidelity;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaTray;
import javax.print.attribute.standard.MediaPrintableArea;
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.Severity;
import javax.print.attribute.standard.Sides;
import javax.print.attribute.standard.ColorSupported;
import javax.print.attribute.standard.PrintQuality;
import javax.print.attribute.ResolutionSyntax;
import javax.print.attribute.standard.PrinterResolution;
import javax.print.attribute.standard.SheetCollate;
import javax.print.event.PrintServiceAttributeListener;
import java.util.ArrayList;

import sun.print.SunPrinterJobService;

public class Win32PrintService implements PrintService, AttributeUpdater,
                                          SunPrinterJobService {

    public static MediaSize[] predefMedia;

    static {
        Class c = Win32MediaSize.class;
    }

    private static final DocFlavor[] supportedFlavors = {
        DocFlavor.BYTE_ARRAY.GIF,
        DocFlavor.INPUT_STREAM.GIF,
        DocFlavor.URL.GIF,
        DocFlavor.BYTE_ARRAY.JPEG,
        DocFlavor.INPUT_STREAM.JPEG,
        DocFlavor.URL.JPEG,
        DocFlavor.BYTE_ARRAY.PNG,
        DocFlavor.INPUT_STREAM.PNG,
        DocFlavor.URL.PNG,
        DocFlavor.SERVICE_FORMATTED.PAGEABLE,
        DocFlavor.SERVICE_FORMATTED.PRINTABLE,
        DocFlavor.BYTE_ARRAY.AUTOSENSE,
        DocFlavor.URL.AUTOSENSE,
        DocFlavor.INPUT_STREAM.AUTOSENSE
    };

    /* let's try to support a few of these */
    private static final Class[] serviceAttrCats = {
        PrinterName.class,
        PrinterIsAcceptingJobs.class,
        QueuedJobCount.class,
        ColorSupported.class,
    };

    /*  it turns out to be inconvenient to store the other categories
     *  separately because many attributes are in multiple categories.
     */
    private static Class[] otherAttrCats = {
        JobName.class,
        RequestingUserName.class,
        Copies.class,
        Destination.class,
        OrientationRequested.class,
        PageRanges.class,
        Media.class,
        MediaPrintableArea.class,
        Fidelity.class,
        // We support collation on 2D printer jobs, even if the driver can't.
        SheetCollate.class,
        SunAlternateMedia.class,
        Chromaticity.class
    };


    /*
     * This table together with methods findWin32Media and
     * findMatchingMediaSizeNameMM are declared public as these are also
     * used in WPrinterJob.java.
     */
    public static final MediaSizeName[] dmPaperToPrintService = {
      MediaSizeName.NA_LETTER, MediaSizeName.NA_LETTER,
      MediaSizeName.TABLOID, MediaSizeName.LEDGER,
      MediaSizeName.NA_LEGAL, MediaSizeName.INVOICE,
      MediaSizeName.EXECUTIVE, MediaSizeName.ISO_A3,
      MediaSizeName.ISO_A4, MediaSizeName.ISO_A4,
      MediaSizeName.ISO_A5, MediaSizeName.JIS_B4,
      MediaSizeName.JIS_B5, MediaSizeName.FOLIO,
      MediaSizeName.QUARTO, MediaSizeName.NA_10X14_ENVELOPE,
      MediaSizeName.B, MediaSizeName.NA_LETTER,
      MediaSizeName.NA_NUMBER_9_ENVELOPE, MediaSizeName.NA_NUMBER_10_ENVELOPE,
      MediaSizeName.NA_NUMBER_11_ENVELOPE, MediaSizeName.NA_NUMBER_12_ENVELOPE,
      MediaSizeName.NA_NUMBER_14_ENVELOPE, MediaSizeName.C,
      MediaSizeName.D, MediaSizeName.E,
      MediaSizeName.ISO_DESIGNATED_LONG, MediaSizeName.ISO_C5,
      MediaSizeName.ISO_C3, MediaSizeName.ISO_C4,
      MediaSizeName.ISO_C6, MediaSizeName.ITALY_ENVELOPE,
      MediaSizeName.ISO_B4, MediaSizeName.ISO_B5,
      MediaSizeName.ISO_B6, MediaSizeName.ITALY_ENVELOPE,
      MediaSizeName.MONARCH_ENVELOPE, MediaSizeName.PERSONAL_ENVELOPE,
      MediaSizeName.NA_10X15_ENVELOPE, MediaSizeName.NA_9X12_ENVELOPE,
      MediaSizeName.FOLIO, MediaSizeName.ISO_B4,
      MediaSizeName.JAPANESE_POSTCARD, MediaSizeName.NA_9X11_ENVELOPE,
    };

    private static final MediaTray[] dmPaperBinToPrintService = {
      MediaTray.TOP, MediaTray.BOTTOM, MediaTray.MIDDLE,
      MediaTray.MANUAL, MediaTray.ENVELOPE, Win32MediaTray.ENVELOPE_MANUAL,
      Win32MediaTray.AUTO, Win32MediaTray.TRACTOR,
      Win32MediaTray.SMALL_FORMAT, Win32MediaTray.LARGE_FORMAT,
      MediaTray.LARGE_CAPACITY, null, null,
      MediaTray.MAIN, Win32MediaTray.FORMSOURCE,
    };

    // from wingdi.h
    private static int DM_PAPERSIZE = 0x2;
    private static int DM_PRINTQUALITY = 0x400;
    private static int DM_YRESOLUTION = 0x2000;
    private static final int DMRES_MEDIUM = -3;
    private static final int DMRES_HIGH = -4;
    private static final int DMORIENT_LANDSCAPE = 2;
    private static final int DMDUP_VERTICAL = 2;
    private static final int DMDUP_HORIZONTAL = 3;
    private static final int DMCOLLATE_TRUE = 1;

    // media sizes with indices above dmPaperToPrintService' length
    private static final int DMPAPER_A2 = 66;
    private static final int DMPAPER_A6 = 70;
    private static final int DMPAPER_B6_JIS = 88;


    // Bit settings for getPrinterCapabilities which matches that
    // of native getCapabilities in WPrinterJob.cpp
    private static final int DEVCAP_COLOR = 0x0001;
    private static final int DEVCAP_DUPLEX = 0x0002;
    private static final int DEVCAP_COLLATE = 0x0004;
    private static final int DEVCAP_QUALITY = 0x0008;
    private static final int DEVCAP_POSTSCRIPT = 0x0010;

    private String printer;
    private PrinterName name;
    private String port;

    transient private PrintServiceAttributeSet lastSet;
    transient private ServiceNotifier notifier = null;

    private MediaSizeName[] mediaSizeNames;
    private MediaPrintableArea[] mediaPrintables;
    private MediaTray[] mediaTrays;
    private PrinterResolution[] printRes;
    private int nCopies;
    private int prnCaps;
    private int[] defaultSettings;

    private boolean gotTrays;
    private boolean gotCopies;
    private boolean mediaInitialized;

    private ArrayList idList;
    private MediaSize[] mediaSizes;

    private boolean isInvalid;

    Win32PrintService(String name) {
        if (name == null) {
            throw new IllegalArgumentException("null printer name");
        }
        printer = name;

        // initialize flags
        mediaInitialized = false;
        gotTrays = false;
        gotCopies = false;
        isInvalid = false;
        printRes = null;
        prnCaps = 0;
        defaultSettings = null;
        port = null;
    }

    public void invalidateService() {
        isInvalid = true;
    }

    public String getName() {
        return printer;
    }

    private PrinterName getPrinterName() {
        if (name == null) {
            name = new PrinterName(printer, null);
        }
        return name;
    }

    public int findPaperID(MediaSizeName msn) {
        if (msn instanceof Win32MediaSize) {
            Win32MediaSize winMedia = (Win32MediaSize)msn;
            return winMedia.getDMPaper();
        } else {
            for (int id=0; id<dmPaperToPrintService.length;id++) {
                if (dmPaperToPrintService[id].equals(msn)) {
                    return id+1; // DMPAPER_LETTER == 1
                }
            }
            if (msn.equals(MediaSizeName.ISO_A2)) {
                return DMPAPER_A2;
            }
            else if (msn.equals(MediaSizeName.ISO_A6)) {
                return DMPAPER_A6;
            }
            else if (msn.equals(MediaSizeName.JIS_B6)) {
                return DMPAPER_B6_JIS;
            }
        }
        return 0;
    }

    public MediaTray findMediaTray(int dmBin) {
        if (dmBin >= 1 && dmBin <= dmPaperBinToPrintService.length) {
            return dmPaperBinToPrintService[dmBin-1];
        }
        MediaTray[] trays = getMediaTrays();
        if (trays != null) {
            for (int i=0;i<trays.length;i++) {
                if(trays[i] instanceof Win32MediaTray) {
                    Win32MediaTray win32Tray = (Win32MediaTray)trays[i];
                    if (win32Tray.winID == dmBin) {
                        return win32Tray;
                    }
                }
            }
        }
        return Win32MediaTray.AUTO;
    }

    public MediaSizeName findWin32Media(int dmIndex) {
        if (dmIndex >= 1 && dmIndex <= dmPaperToPrintService.length) {
           switch(dmIndex) {
            /* matching media sizes with indices beyond
               dmPaperToPrintService's length */
            case DMPAPER_A2:
                return MediaSizeName.ISO_A2;
            case DMPAPER_A6:
                return MediaSizeName.ISO_A6;
            case DMPAPER_B6_JIS:
                return MediaSizeName.JIS_B6;
            default:
                return dmPaperToPrintService[dmIndex - 1];
            }
        }

        return null;
    }

    private boolean addToUniqueList(ArrayList msnList, MediaSizeName mediaName) {
        MediaSizeName msn;
        for (int i=0; i< msnList.size(); i++) {
            msn = (MediaSizeName)msnList.get(i);
            if (msn == mediaName) {
                return false;
            }
        }
        msnList.add(mediaName);
        return true;
    }

    private synchronized void initMedia() {
        if (mediaInitialized == true) {
            return;
        }
        mediaInitialized = true;
        int[] media = getAllMediaIDs(printer, getPort());
        if (media == null) {
            return;
        }

        ArrayList msnList = new ArrayList();
        ArrayList printableList = new ArrayList();
        MediaSizeName mediaName;
        boolean added;
        boolean queryFailure = false;
        float[] prnArea;

        // Get all mediaSizes supported by the printer.
        // We convert media to ArrayList idList and pass this to the
        // function for getting mediaSizes.
        // This is to ensure that mediaSizes and media IDs have 1-1 correspondence.
        // We remove from ID list any invalid mediaSize.  Though this is rare,
        // it happens in HP 4050 German driver.

        idList = new ArrayList();
        for (int i=0; i < media.length; i++) {
          idList.add(new Integer(media[i]));
        }

        mediaSizes = getMediaSizes(idList, media);
        for (int i = 0; i < idList.size(); i++) {

            // match Win ID with our predefined ID using table
            mediaName = findWin32Media(((Integer)idList.get(i)).intValue());
            // Verify that this standard size is the same size as that
            // reported by the driver. This should be the case except when
            // the driver is mis-using a standard windows paper ID.
            if (mediaName != null &&
                idList.size() == mediaSizes.length) {
                MediaSize win32Size = MediaSize.getMediaSizeForName(mediaName);
                MediaSize driverSize = mediaSizes[i];
                int error = 2540; // == 1/10"
                if (Math.abs(win32Size.getX(1)-driverSize.getX(1)) > error ||
                    Math.abs(win32Size.getY(1)-driverSize.getY(1)) > error)
                {
                   mediaName = null;
                }
            }

            // No match found, then we get the MediaSizeName out of the MediaSize
            // This requires 1-1 correspondence, lengths must be checked.
            if ((mediaName == null) && (idList.size() == mediaSizes.length)) {
                mediaName = mediaSizes[i].getMediaSizeName();
            }

            // Add mediaName to the msnList
            if (mediaName != null) {
                added = addToUniqueList(msnList, mediaName);

                // get MediaPrintableArea only for supported MediaSizeName ?
                if (added && !queryFailure) {
                    prnArea=getMediaPrintableArea(printer,
                                                  ((Integer)idList.get(i)).intValue());
                    if (prnArea != null) {
                        try {
                            MediaPrintableArea mpa =
                                new MediaPrintableArea(prnArea[0],
                                                       prnArea[1],
                                                       prnArea[2],
                                                       prnArea[3],
                                                       MediaPrintableArea.INCH);
                            printableList.add(mpa);
                        } catch (IllegalArgumentException iae) {
                        }
                    } else {
                        // Calling getMediaPrintableArea causes
                        // much overhead so if first attempt failed, we should
                        // just bail out.
                        if (i==0) {
                            queryFailure = true;
                        }
                    }
                }
            }
        }

        // init mediaSizeNames
        mediaSizeNames = new MediaSizeName[msnList.size()];
        msnList.toArray(mediaSizeNames);

        // init mediaPrintables
        mediaPrintables = new MediaPrintableArea[printableList.size()];
        printableList.toArray(mediaPrintables);
    }

    private synchronized MediaTray[] getMediaTrays() {
        if (gotTrays == true && mediaTrays != null) {
            return mediaTrays;
        }
        String prnPort = getPort();
        int[] mediaTr = getAllMediaTrays(printer, prnPort);
        String[] winMediaTrayNames = getAllMediaTrayNames(printer, prnPort);

        if ((mediaTr == null) || (winMediaTrayNames == null)){
            return null;
        }

        /* first count how many valid bins there are so we can allocate
         * an array of the correct size
         */
        int nTray = 0;
        for (int i=0; i < mediaTr.length ; i++) {
            if (mediaTr[i] > 0) nTray++;
        }

        MediaTray[] arr = new MediaTray[nTray];
        int dmBin;
        for (int i = 0, j=0; i < mediaTr.length; i++) {
            dmBin = mediaTr[i];
            if (dmBin > 0) {
                // check for unsupported DMBINs and create new Win32MediaTray
                if ((dmBin > dmPaperBinToPrintService.length)
                    || (dmPaperBinToPrintService[dmBin-1] == null)) {
                    arr[j++] = new Win32MediaTray(dmBin, winMediaTrayNames[i]);
                } else {
                    arr[j++] = dmPaperBinToPrintService[dmBin-1];
                }
            }
            // no else - For invalid ids, just ignore it because assigning a "default"
            // value may result in duplicate trays.
        }
        mediaTrays = arr;
        gotTrays = true;
        return mediaTrays;
    }

    private boolean isSameSize(float w1, float h1, float w2, float h2) {
        float diffX = w1 - w2;
        float diffY = h1 - h2;
        // Get diff of reverse dimensions
        // EPSON Stylus COLOR 860 reverses envelope's width & height
        float diffXrev = w1 - h2;
        float diffYrev = h1 - w2;

        if (((Math.abs(diffX)<=1) && (Math.abs(diffY)<=1)) ||
            ((Math.abs(diffXrev)<=1) && (Math.abs(diffYrev)<=1))){
          return true;
        } else {
          return false;
        }
    }

    public MediaSizeName findMatchingMediaSizeNameMM (float w, float h){
        if (predefMedia != null) {
            for (int k=0; k<predefMedia.length;k++) {
                if (predefMedia[k] == null) {
                    continue;
                }

                if (isSameSize(predefMedia[k].getX(MediaSize.MM),
                               predefMedia[k].getY(MediaSize.MM),
                               w, h)) {
                  return predefMedia[k].getMediaSizeName();
                }
            }
        }
        return null;
    }


    private MediaSize[] getMediaSizes(ArrayList idList, int[] media) {
        String prnPort = getPort();
        int[] mediaSz = getAllMediaSizes(printer, prnPort);
        String[] winMediaNames = getAllMediaNames(printer, prnPort);
        MediaSizeName msn = null;
        MediaSize ms = null;
        float wid, ht;

        if ((mediaSz == null) || (winMediaNames == null)) {
            return null;
        }

        int nMedia = mediaSz.length/2;
        ArrayList msList = new ArrayList();

        for (int i = 0; i < nMedia; i++, ms=null) {
            wid = mediaSz[i*2]/10f;
            ht = mediaSz[i*2+1]/10f;

          // Make sure to validate wid & ht.
          // HP LJ 4050 (german) causes IAE in Sonderformat paper, wid & ht
          // returned is not constant.
          if ((wid <= 0) || (ht <= 0)) {
            //Remove corresponding ID from list
            if (nMedia == media.length) {
              Integer remObj = new Integer(media[i]);
              idList.remove(idList.indexOf(remObj));
            }
            continue;
          }
          // Find matching media using dimensions.
          // This call matches only with our own predefined sizes.
          msn = findMatchingMediaSizeNameMM(wid, ht);
          if (msn != null) {
            ms = MediaSize.getMediaSizeForName(msn);
          }

          if (ms != null) {
            msList.add(ms);
          } else {
              Win32MediaSize wms =
                new Win32MediaSize(winMediaNames[i], media[i]);
            try {
              ms = new MediaSize(wid, ht, MediaSize.MM, wms);
              msList.add(ms);
            } catch(IllegalArgumentException e) {
              if (nMedia == media.length) {
                Integer remObj = new Integer(media[i]);
                idList.remove(idList.indexOf(remObj));
              }
            }
          }

        }

        MediaSize[] arr2 = new MediaSize[msList.size()];
        msList.toArray(arr2);

        return arr2;
    }


    private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {
        if (getJobStatus(printer, 2) != 1) {
            return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;
        }
        else {
            return PrinterIsAcceptingJobs.ACCEPTING_JOBS;
        }
    }

    private PrinterState getPrinterState() {
        if (isInvalid) {
            return PrinterState.STOPPED;
        } else {
            return null;
        }
    }

    private PrinterStateReasons getPrinterStateReasons() {
        if (isInvalid) {
            PrinterStateReasons psr = new PrinterStateReasons();
            psr.put(PrinterStateReason.SHUTDOWN, Severity.ERROR);
            return psr;
        } else {
            return null;
        }
    }

    private QueuedJobCount getQueuedJobCount() {

        int count = getJobStatus(printer, 1);
        if (count != -1) {
            return new QueuedJobCount(count);
        }
        else {
            return new QueuedJobCount(0);
        }
    }

    private boolean isSupportedCopies(Copies copies) {
        synchronized (this) {
            if (gotCopies == false) {
                nCopies = getCopiesSupported(printer, getPort());
                gotCopies = true;
            }
        }
        int numCopies = copies.getValue();
        return (numCopies > 0 && numCopies <= nCopies);
    }

    private boolean isSupportedMedia(MediaSizeName msn) {

        initMedia();

        if (mediaSizeNames != null) {
            for (int i=0; i<mediaSizeNames.length; i++) {
                if (msn.equals(mediaSizeNames[i])) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean isSupportedMediaPrintableArea(MediaPrintableArea mpa) {

        initMedia();

        if (mediaPrintables != null) {
            for (int i=0; i<mediaPrintables.length; i++) {
                if (mpa.equals(mediaPrintables[i])) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean isSupportedMediaTray(MediaTray msn) {
        MediaTray[] trays = getMediaTrays();

        if (trays != null) {
            for (int i=0; i<trays.length; i++) {
                if (msn.equals(trays[i])) {
                    return true;
                }
            }
        }
        return false;
    }

    private int getPrinterCapabilities() {
        if (prnCaps == 0) {
            prnCaps = getCapabilities(printer, getPort());
        }
        return prnCaps;
    }

    private String getPort() {
        if (port == null) {
            port = getPrinterPort(printer);
        }
        return port;
    }

   /*
    * NOTE: defaults indices must match those in WPrinterJob.cpp
    */
    private int[] getDefaultPrinterSettings() {
        if (defaultSettings == null) {
            defaultSettings = getDefaultSettings(printer, getPort());
        }
        return defaultSettings;
    }

    private PrinterResolution[] getPrintResolutions() {
        if (printRes == null) {
            int[] prnRes = getAllResolutions(printer, getPort());
            if (prnRes == null) {
                printRes = new PrinterResolution[0];
            } else {
                int nRes = prnRes.length/2;

                ArrayList arrList = new ArrayList();
                PrinterResolution pr;

                for (int i=0; i<nRes; i++) {
                  try {
                        pr = new PrinterResolution(prnRes[i*2],
                                       prnRes[i*2+1], PrinterResolution.DPI);
                        arrList.add(pr);
                    } catch (IllegalArgumentException e) {
                    }
                }

                printRes = (PrinterResolution[])arrList.toArray(
                                        new PrinterResolution[arrList.size()]);
            }
        }
        return printRes;
    }

    private boolean isSupportedResolution(PrinterResolution res) {
        PrinterResolution[] supportedRes = getPrintResolutions();
        if (supportedRes != null) {
            for (int i=0; i<supportedRes.length; i++) {
                if (res.equals(supportedRes[i])) {
                    return true;
                }
            }
        }
        return false;
    }

    public DocPrintJob createPrintJob() {
      SecurityManager security = System.getSecurityManager();
      if (security != null) {
        security.checkPrintJobAccess();
      }
        return new Win32PrintJob(this);
    }

    private PrintServiceAttributeSet getDynamicAttributes() {
        PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
        attrs.add(getPrinterIsAcceptingJobs());
        attrs.add(getQueuedJobCount());
        return attrs;
    }

    public PrintServiceAttributeSet getUpdatedAttributes() {
        PrintServiceAttributeSet currSet = getDynamicAttributes();
        if (lastSet == null) {
            lastSet = currSet;
            return AttributeSetUtilities.unmodifiableView(currSet);
        } else {
            PrintServiceAttributeSet updates =
                new HashPrintServiceAttributeSet();
            Attribute []attrs =  currSet.toArray();
            for (int i=0; i<attrs.length; i++) {
                Attribute attr = attrs[i];
                if (!lastSet.containsValue(attr)) {
                    updates.add(attr);
                }
            }
            lastSet = currSet;
            return AttributeSetUtilities.unmodifiableView(updates);
        }
    }

    public void wakeNotifier() {
        synchronized (this) {
            if (notifier != null) {
                notifier.wake();
            }
        }
    }

    public void addPrintServiceAttributeListener(PrintServiceAttributeListener
                                                 listener) {
        synchronized (this) {
            if (listener == null) {
                return;
            }
            if (notifier == null) {
                notifier = new ServiceNotifier(this);
            }
            notifier.addListener(listener);
        }
    }

    public void removePrintServiceAttributeListener(
                                      PrintServiceAttributeListener listener) {
        synchronized (this) {
            if (listener == null || notifier == null ) {
                return;
            }
            notifier.removeListener(listener);
            if (notifier.isEmpty()) {
                notifier.stopNotifier();
                notifier = null;
            }
        }
    }

    public <T extends PrintServiceAttribute> T
        getAttribute(Class<T> category)
    {
        if (category == null) {
            throw new NullPointerException("category");
        }
        if (!(PrintServiceAttribute.class.isAssignableFrom(category))) {
            throw new IllegalArgumentException("Not a PrintServiceAttribute");
        }
        if (category == ColorSupported.class) {
            int caps = getPrinterCapabilities();
            if ((caps & DEVCAP_COLOR) != 0) {
                return (T)ColorSupported.SUPPORTED;
            } else {
                return (T)ColorSupported.NOT_SUPPORTED;
            }
        } else if (category == PrinterName.class) {
            return (T)getPrinterName();
        } else if (category == PrinterState.class) {
            return (T)getPrinterState();
        } else if (category == PrinterStateReasons.class) {
            return (T)getPrinterStateReasons();
        } else if (category == QueuedJobCount.class) {
            return (T)getQueuedJobCount();
        } else if (category == PrinterIsAcceptingJobs.class) {
            return (T)getPrinterIsAcceptingJobs();
        } else {
            return null;
        }
    }

    public PrintServiceAttributeSet getAttributes() {

        PrintServiceAttributeSet attrs = new  HashPrintServiceAttributeSet();
        attrs.add(getPrinterName());
        attrs.add(getPrinterIsAcceptingJobs());
        PrinterState prnState = getPrinterState();
        if (prnState != null) {
            attrs.add(prnState);
        }
        PrinterStateReasons prnStateReasons = getPrinterStateReasons();
        if (prnStateReasons != null) {
            attrs.add(prnStateReasons);
        }
        attrs.add(getQueuedJobCount());
        int caps = getPrinterCapabilities();
        if ((caps & DEVCAP_COLOR) != 0) {
            attrs.add(ColorSupported.SUPPORTED);
        } else {
            attrs.add(ColorSupported.NOT_SUPPORTED);
        }

        return AttributeSetUtilities.unmodifiableView(attrs);
    }

    public DocFlavor[] getSupportedDocFlavors() {
        int len = supportedFlavors.length;
        DocFlavor[] supportedDocFlavors;
        int caps = getPrinterCapabilities();
        // doc flavors supported
        // if PostScript is supported
        if ((caps & DEVCAP_POSTSCRIPT) != 0) {
            supportedDocFlavors = new DocFlavor[len+3];
            System.arraycopy(supportedFlavors, 0, supportedDocFlavors, 0, len);
            supportedDocFlavors[len] = DocFlavor.BYTE_ARRAY.POSTSCRIPT;
            supportedDocFlavors[len+1] = DocFlavor.INPUT_STREAM.POSTSCRIPT;
            supportedDocFlavors[len+2] = DocFlavor.URL.POSTSCRIPT;
        } else {
            supportedDocFlavors = new DocFlavor[len];
            System.arraycopy(supportedFlavors, 0, supportedDocFlavors, 0, len);
        }
        return supportedDocFlavors;
    }

    public boolean isDocFlavorSupported(DocFlavor flavor) {
        /* To avoid a native query which may be time-consuming
         * do not invoke native unless postscript support is being queried.
         * Instead just check the ones we 'always' support
         */
        DocFlavor[] supportedDocFlavors;
        if (isPostScriptFlavor(flavor)) {
            supportedDocFlavors = getSupportedDocFlavors();
        } else {
            supportedDocFlavors = supportedFlavors;
        }
        for (int f=0; f<supportedDocFlavors.length; f++) {
            if (flavor.equals(supportedDocFlavors[f])) {
                return true;
            }
        }
        return false;
    }

    public Class<?>[] getSupportedAttributeCategories() {
        ArrayList categList = new ArrayList(otherAttrCats.length+3);
        for (int i=0; i < otherAttrCats.length; i++) {
            categList.add(otherAttrCats[i]);
        }

        int caps = getPrinterCapabilities();

        if ((caps & DEVCAP_DUPLEX) != 0) {
            categList.add(Sides.class);
        }

        if ((caps & DEVCAP_QUALITY) != 0) {
            int[] defaults = getDefaultPrinterSettings();
            // Added check: if supported, we should be able to get the default.
            if ((defaults[3] >= DMRES_HIGH) && (defaults[3] < 0)) {
                categList.add(PrintQuality.class);
            }
        }

        PrinterResolution[] supportedRes = getPrintResolutions();
        if ((supportedRes!=null) && (supportedRes.length>0)) {
            categList.add(PrinterResolution.class);
        }

        return (Class[])categList.toArray(new Class[categList.size()]);
    }

    public boolean
        isAttributeCategorySupported(Class<? extends Attribute> category)
    {

        if (category == null) {
            throw new NullPointerException("null category");
        }

        if (!(Attribute.class.isAssignableFrom(category))) {
            throw new IllegalArgumentException(category +
                                               " is not an Attribute");
        }

        Class[] classList = getSupportedAttributeCategories();
        for (int i = 0; i < classList.length; i++) {
            if (category.equals(classList[i])) {
                return true;
            }
        }

        return false;
    }

    public Object
        getDefaultAttributeValue(Class<? extends Attribute> category)
    {
        if (category == null) {
            throw new NullPointerException("null category");
        }
        if (!Attribute.class.isAssignableFrom(category)) {
            throw new IllegalArgumentException(category +
                                               " is not an Attribute");
        }

        if (!isAttributeCategorySupported(category)) {
            return null;
        }

        int[] defaults = getDefaultPrinterSettings();
        // indices must match those in WPrinterJob.cpp
        int defPaper = defaults[0];
        int defYRes = defaults[2];
        int defQuality = defaults[3];
        int defCopies = defaults[4];
        int defOrient = defaults[5];
        int defSides = defaults[6];
        int defCollate = defaults[7];

        if (category == Copies.class) {
            if (defCopies > 0) {
                return new Copies(defCopies);
            } else {
                return new Copies(1);
            }
        } else if (category == Chromaticity.class) {
            int caps = getPrinterCapabilities();
            if ((caps & DEVCAP_COLOR) == 0) {
                return Chromaticity.MONOCHROME;
            } else {
                return Chromaticity.COLOR;
            }
        } else if (category == JobName.class) {
            return new JobName("Java Printing", null);
        } else if (category == OrientationRequested.class) {
            if (defOrient == DMORIENT_LANDSCAPE) {
                return OrientationRequested.LANDSCAPE;
            } else {
                return OrientationRequested.PORTRAIT;
            }
        } else if (category == PageRanges.class) {
            return new PageRanges(1, Integer.MAX_VALUE);
        } else if (category == Media.class) {
            MediaSizeName msn = findWin32Media(defPaper);
            if (msn != null) {
                if (!isSupportedMedia(msn) && mediaSizeNames != null) {
                    msn = mediaSizeNames[0];
                    defPaper = findPaperID(msn);
                }
                return msn;
             } else {
                 initMedia();
                 if ((mediaSizeNames != null) && (mediaSizeNames.length > 0)) {
                     // if 'mediaSizeNames' is not null, idList and mediaSizes
                     // cannot be null but to be safe, add a check
                     if ((idList != null) && (mediaSizes != null) &&
                         (idList.size() == mediaSizes.length)) {
                         Integer defIdObj = new Integer(defPaper);
                         int index = idList.indexOf(defIdObj);
                         if (index>=0 && index<mediaSizes.length) {
                             return mediaSizes[index].getMediaSizeName();
                         }
                     }

                     return mediaSizeNames[0];
                 }
             }
        } else if (category == MediaPrintableArea.class) {
            /* Verify defPaper */
            MediaSizeName msn = findWin32Media(defPaper);
            if (msn != null &&
                !isSupportedMedia(msn) && mediaSizeNames != null) {
                defPaper = findPaperID(mediaSizeNames[0]);
            }
            float[] prnArea = getMediaPrintableArea(printer, defPaper);
            if (prnArea != null) {
                MediaPrintableArea printableArea = null;
                try {
                    printableArea = new MediaPrintableArea(prnArea[0],
                                                           prnArea[1],
                                                           prnArea[2],
                                                           prnArea[3],
                                                           MediaPrintableArea.INCH);
                } catch (IllegalArgumentException e) {
                }
                return printableArea;
            }
            return null;
        } else if (category == SunAlternateMedia.class) {
            return null;
        } else if (category == Destination.class) {
            try {
                return new Destination((new File("out.prn")).toURI());
            } catch (SecurityException se) {
                try {
                    return new Destination(new URI("file:out.prn"));
                } catch (URISyntaxException e) {
                    return null;
                }
            }
        } else if (category == Sides.class) {
            switch(defSides) {
            case DMDUP_VERTICAL :
                return Sides.TWO_SIDED_LONG_EDGE;
            case DMDUP_HORIZONTAL :
                return Sides.TWO_SIDED_SHORT_EDGE;
            default :
                return Sides.ONE_SIDED;
            }
        } else if (category == PrinterResolution.class) {
            int yRes = defYRes;
            int xRes = defQuality;
            if ((xRes < 0) || (yRes < 0)) {
                int res = (yRes > xRes) ? yRes : xRes;
                if (res > 0) {
                 return new PrinterResolution(res, res, PrinterResolution.DPI);
                }
            }
            else {
               return new PrinterResolution(xRes, yRes, PrinterResolution.DPI);
            }
        } else if (category == ColorSupported.class) {
            int caps = getPrinterCapabilities();
            if ((caps & DEVCAP_COLOR) != 0) {
                return ColorSupported.SUPPORTED;
            } else {
                return ColorSupported.NOT_SUPPORTED;
            }
        } else if (category == PrintQuality.class) {
            if ((defQuality < 0) && (defQuality >= DMRES_HIGH)) {
                switch (defQuality) {
                case DMRES_HIGH:
                    return PrintQuality.HIGH;
                case DMRES_MEDIUM:
                    return PrintQuality.NORMAL;
                default:
                    return PrintQuality.DRAFT;
                }
            }
        } else if (category == RequestingUserName.class) {
            String userName = "";
            try {
              userName = System.getProperty("user.name", "");
            } catch (SecurityException se) {
            }
            return new RequestingUserName(userName, null);
        } else if (category == SheetCollate.class) {
            if (defCollate == DMCOLLATE_TRUE) {
                return SheetCollate.COLLATED;
            } else {
                return SheetCollate.UNCOLLATED;
            }
        } else if (category == Fidelity.class) {
            return Fidelity.FIDELITY_FALSE;
        }
        return null;
    }

    private boolean isPostScriptFlavor(DocFlavor flavor) {
        if (flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT) ||
            flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT) ||
            flavor.equals(DocFlavor.URL.POSTSCRIPT)) {
            return true;
        }
        else {
            return false;
        }
    }

    private boolean isPSDocAttr(Class category) {
        if (category == OrientationRequested.class || category == Copies.class) {
                return true;
        }
        else {
            return false;
        }
    }

    private boolean isAutoSense(DocFlavor flavor) {
        if (flavor.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE) ||
            flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE) ||
            flavor.equals(DocFlavor.URL.AUTOSENSE)) {
            return true;
        }
        else {
            return false;
        }
    }

    public Object
        getSupportedAttributeValues(Class<? extends Attribute> category,
                                    DocFlavor flavor,
                                    AttributeSet attributes)
    {
        if (category == null) {
            throw new NullPointerException("null category");
        }
        if (!Attribute.class.isAssignableFrom(category)) {
            throw new IllegalArgumentException(category +
                                             " does not implement Attribute");
        }
        if (flavor != null) {
            if (!isDocFlavorSupported(flavor)) {
                throw new IllegalArgumentException(flavor +
                                                  " is an unsupported flavor");
                // if postscript & category is already specified within the
                //  PostScript data we return null
            } else if (isAutoSense(flavor) ||(isPostScriptFlavor(flavor) &&
                       (isPSDocAttr(category)))){
                return null;
            }
        }
        if (!isAttributeCategorySupported(category)) {
            return null;
        }

        if (category == JobName.class) {
            return new JobName("Java Printing", null);
        } else if (category == RequestingUserName.class) {
          String userName = "";
          try {
            userName = System.getProperty("user.name", "");
          } catch (SecurityException se) {
          }
            return new RequestingUserName(userName, null);
        } else if (category == ColorSupported.class) {
            int caps = getPrinterCapabilities();
            if ((caps & DEVCAP_COLOR) != 0) {
                return ColorSupported.SUPPORTED;
            } else {
                return ColorSupported.NOT_SUPPORTED;
            }
        } else if (category == Chromaticity.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
                flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
                flavor.equals(DocFlavor.URL.GIF) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
                flavor.equals(DocFlavor.URL.JPEG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
                flavor.equals(DocFlavor.URL.PNG)) {
                int caps = getPrinterCapabilities();
                if ((caps & DEVCAP_COLOR) == 0) {
                    Chromaticity []arr = new Chromaticity[1];
                    arr[0] = Chromaticity.MONOCHROME;
                    return (arr);
                } else {
                    Chromaticity []arr = new Chromaticity[2];
                    arr[0] = Chromaticity.MONOCHROME;
                    arr[1] = Chromaticity.COLOR;
                    return (arr);
                }
            } else {
                return null;
            }
        } else if (category == Destination.class) {
            try {
                return new Destination((new File("out.prn")).toURI());
            } catch (SecurityException se) {
                try {
                    return new Destination(new URI("file:out.prn"));
                } catch (URISyntaxException e) {
                    return null;
                }
            }
        } else if (category == OrientationRequested.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
                flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
                flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
                flavor.equals(DocFlavor.URL.GIF) ||
                flavor.equals(DocFlavor.URL.JPEG) ||
                flavor.equals(DocFlavor.URL.PNG)) {
                OrientationRequested []arr = new OrientationRequested[3];
                arr[0] = OrientationRequested.PORTRAIT;
                arr[1] = OrientationRequested.LANDSCAPE;
                arr[2] = OrientationRequested.REVERSE_LANDSCAPE;
                return arr;
            } else {
                return null;
            }
        } else if ((category == Copies.class) ||
                   (category == CopiesSupported.class)) {
            synchronized (this) {
                if (gotCopies == false) {
                    nCopies = getCopiesSupported(printer, getPort());
                    gotCopies = true;
                }
            }
            return new CopiesSupported(1, nCopies);
        } else if (category == Media.class) {

            initMedia();

            int len = (mediaSizeNames == null) ? 0 : mediaSizeNames.length;

            MediaTray[] trays = getMediaTrays();

            len += (trays == null) ? 0 : trays.length;

            Media []arr = new Media[len];
            if (mediaSizeNames != null) {
                System.arraycopy(mediaSizeNames, 0, arr,
                                 0, mediaSizeNames.length);
            }
            if (trays != null) {
                System.arraycopy(trays, 0, arr,
                                 mediaSizeNames.length, trays.length);
            }
            return arr;
        } else if (category == MediaPrintableArea.class) {
            initMedia();

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

            // if getting printable area for a specific media size
            Media mediaName;
            if ((attributes != null) &&
                ((mediaName =
                  (Media)attributes.get(Media.class)) != null)) {

                if (mediaName instanceof MediaSizeName) {
                    MediaPrintableArea []arr = new MediaPrintableArea[1];

                    if (mediaSizeNames.length == mediaPrintables.length) {

                        for (int j=0; j < mediaSizeNames.length; j++) {

                            if (mediaName.equals(mediaSizeNames[j])) {
                                arr[0] = mediaPrintables[j];
                                return arr;
                            }
                        }
                    }

                    MediaSize ms =
                      MediaSize.getMediaSizeForName((MediaSizeName)mediaName);

                    if (ms != null) {
                        arr[0] = new MediaPrintableArea(0, 0,
                                                        ms.getX(MediaSize.INCH),
                                                        ms.getY(MediaSize.INCH),
                                                        MediaPrintableArea.INCH);
                        return arr;
                    } else {
                        return null;
                    }
                }
                // else an instance of MediaTray, fall thru returning
                // all MediaPrintableAreas
            }

            MediaPrintableArea []arr =
                new MediaPrintableArea[mediaPrintables.length];
            System.arraycopy(mediaPrintables, 0, arr, 0, mediaPrintables.length);
            return arr;
        } else if (category == SunAlternateMedia.class) {
            return new SunAlternateMedia(
                              (Media)getDefaultAttributeValue(Media.class));
        } else if (category == PageRanges.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
                PageRanges []arr = new PageRanges[1];
                arr[0] = new PageRanges(1, Integer.MAX_VALUE);
                return arr;
            } else {
                return null;
            }
        } else if (category == PrinterResolution.class) {
            PrinterResolution[] supportedRes = getPrintResolutions();
            if (supportedRes == null) {
                return null;
            }
            PrinterResolution []arr =
                new PrinterResolution[supportedRes.length];
            System.arraycopy(supportedRes, 0, arr, 0, supportedRes.length);
            return arr;
        } else if (category == Sides.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
                Sides []arr = new Sides[3];
                arr[0] = Sides.ONE_SIDED;
                arr[1] = Sides.TWO_SIDED_LONG_EDGE;
                arr[2] = Sides.TWO_SIDED_SHORT_EDGE;
                return arr;
            } else {
                return null;
            }
        } else if (category == PrintQuality.class) {
            PrintQuality []arr = new PrintQuality[3];
            arr[0] = PrintQuality.DRAFT;
            arr[1] = PrintQuality.HIGH;
            arr[2] = PrintQuality.NORMAL;
            return arr;
        } else if (category == SheetCollate.class) {
            if (flavor == null ||
                (flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                 flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
                SheetCollate []arr = new SheetCollate[2];
                arr[0] = SheetCollate.COLLATED;
                arr[1] = SheetCollate.UNCOLLATED;
                return arr;
            } else {
                return null;
            }
        } else if (category == Fidelity.class) {
            Fidelity []arr = new Fidelity[2];
            arr[0] = Fidelity.FIDELITY_FALSE;
            arr[1] = Fidelity.FIDELITY_TRUE;
            return arr;
        } else {
            return null;
        }
    }

    public boolean isAttributeValueSupported(Attribute attr,
                                             DocFlavor flavor,
                                             AttributeSet attributes) {

        if (attr == null) {
            throw new NullPointerException("null attribute");
        }
        Class category = attr.getCategory();
        if (flavor != null) {
            if (!isDocFlavorSupported(flavor)) {
                throw new IllegalArgumentException(flavor +
                                                   " is an unsupported flavor");
                // if postscript & category is already specified within the PostScript data
                // we return false
            } else if (isAutoSense(flavor) || (isPostScriptFlavor(flavor) &&
                       (isPSDocAttr(category)))) {
                return false;
            }
        }

        if (!isAttributeCategorySupported(category)) {
            return false;
        }
        else if (category == Chromaticity.class) {
            if ((flavor == null) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
                flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
                flavor.equals(DocFlavor.URL.GIF) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
                flavor.equals(DocFlavor.URL.JPEG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
                flavor.equals(DocFlavor.URL.PNG)) {
                int caps = getPrinterCapabilities();
                if ((caps & DEVCAP_COLOR) != 0) {
                    return true;
                } else {
                    return attr == Chromaticity.MONOCHROME;
                }
            } else {
                return false;
            }
        } else if (category == Copies.class) {
            return isSupportedCopies((Copies)attr);

        } else if (category == Destination.class) {
            URI uri = ((Destination)attr).getURI();
            if ("file".equals(uri.getScheme()) &&
                !(uri.getSchemeSpecificPart().equals(""))) {
                return true;
            } else {
            return false;
            }

        } else if (category == Media.class) {
            if (attr instanceof MediaSizeName) {
                return isSupportedMedia((MediaSizeName)attr);
            }
            if (attr instanceof MediaTray) {
                return isSupportedMediaTray((MediaTray)attr);
            }

        } else if (category == MediaPrintableArea.class) {
            return isSupportedMediaPrintableArea((MediaPrintableArea)attr);

        } else if (category == SunAlternateMedia.class) {
            Media media = ((SunAlternateMedia)attr).getMedia();
            return isAttributeValueSupported(media, flavor, attributes);

        } else if (category == PageRanges.class ||
                   category == SheetCollate.class ||
                   category == Sides.class) {
            if (flavor != null &&
                !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
                return false;
            }
        } else if (category == PrinterResolution.class) {
            if (attr instanceof PrinterResolution) {
                return isSupportedResolution((PrinterResolution)attr);
            }
        } else if (category == OrientationRequested.class) {
            if (attr == OrientationRequested.REVERSE_PORTRAIT ||
                (flavor != null) &&
                !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
                flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
                flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
                flavor.equals(DocFlavor.URL.GIF) ||
                flavor.equals(DocFlavor.URL.JPEG) ||
                flavor.equals(DocFlavor.URL.PNG))) {
                return false;
            }

        } else if (category == ColorSupported.class) {
            int caps = getPrinterCapabilities();
            boolean isColorSup = ((caps & DEVCAP_COLOR) != 0);
            if  ((!isColorSup && (attr == ColorSupported.SUPPORTED)) ||
                (isColorSup && (attr == ColorSupported.NOT_SUPPORTED))) {
                return false;
            }
        }
        return true;
    }

    public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
                                                 AttributeSet attributes) {

        if (flavor != null && !isDocFlavorSupported(flavor)) {
            throw new IllegalArgumentException("flavor " + flavor +
                                               "is not supported");
        }

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

        Attribute attr;
        AttributeSet unsupp = new HashAttributeSet();
        Attribute []attrs = attributes.toArray();
        for (int i=0; i<attrs.length; i++) {
            try {
                attr = attrs[i];
                if (!isAttributeCategorySupported(attr.getCategory())) {
                    unsupp.add(attr);
                }
                else if (!isAttributeValueSupported(attr, flavor, attributes)) {
                    unsupp.add(attr);
                }
            } catch (ClassCastException e) {
            }
        }
        if (unsupp.isEmpty()) {
            return null;
        } else {
            return unsupp;
        }
    }

    public ServiceUIFactory getServiceUIFactory() {
        return null;
    }

    public String toString() {
        return "Win32 Printer : " + getName();
    }

    public boolean equals(Object obj) {
        return  (obj == this ||
                 (obj instanceof Win32PrintService &&
                  ((Win32PrintService)obj).getName().equals(getName())));
    }

   public int hashCode() {
        return this.getClass().hashCode()+getName().hashCode();
    }

    public boolean usesClass(Class c) {
        return (c == sun.awt.windows.WPrinterJob.class);
    }

    private native int[] getAllMediaIDs(String printerName, String port);
    private native int[] getAllMediaSizes(String printerName, String port);
    private native int[] getAllMediaTrays(String printerName, String port);
    private native float[] getMediaPrintableArea(String printerName,
                                                 int paperSize);
    private native String[] getAllMediaNames(String printerName, String port);
    private native String[] getAllMediaTrayNames(String printerName, String port);
    private native int getCopiesSupported(String printerName, String port);
    private native int[] getAllResolutions(String printerName, String port);
    private native int getCapabilities(String printerName, String port);

    private native int[] getDefaultSettings(String printerName, String port);
    private native int getJobStatus(String printerName, int type);
    private native String getPrinterPort(String printerName);
}


class Win32MediaSize extends MediaSizeName {
    private static ArrayList winStringTable = new ArrayList();
    private static ArrayList winEnumTable = new ArrayList();

    private int dmPaperID; // driver ID for this paper.

    private Win32MediaSize(int x) {
        super(x);

    }

    private synchronized static int nextValue(String name) {
      winStringTable.add(name);
      return (winStringTable.size()-1);
    }

    public Win32MediaSize(String name, int dmPaper) {
        super(nextValue(name));
        dmPaperID = dmPaper;
        winEnumTable.add(this);
    }

    private MediaSizeName[] getSuperEnumTable() {
      return (MediaSizeName[])super.getEnumValueTable();
    }

    static {
         /* initialize Win32PrintService.predefMedia */
        {
            Win32MediaSize winMedia = new Win32MediaSize(-1);

            // cannot call getSuperEnumTable directly because of static context
            MediaSizeName[] enumMedia = winMedia.getSuperEnumTable();
            if (enumMedia != null) {
                Win32PrintService.predefMedia = new MediaSize[enumMedia.length];

                for (int i=0; i<enumMedia.length; i++) {
                    Win32PrintService.predefMedia[i] =
                        MediaSize.getMediaSizeForName(enumMedia[i]);
                }
            }
        }
    }

    int getDMPaper() {
        return dmPaperID;
    }

    protected String[] getStringTable() {
      String[] nameTable = new String[winStringTable.size()];
      return (String[])winStringTable.toArray(nameTable);
    }

    protected EnumSyntax[] getEnumValueTable() {
      MediaSizeName[] enumTable = new MediaSizeName[winEnumTable.size()];
      return (MediaSizeName[])winEnumTable.toArray(enumTable);
    }

}
