/*
 * Copyright (c) 2000, 2005, 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.OutputStream;
import java.util.Iterator;
import java.util.Locale;

import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.StreamPrintService;
import javax.print.StreamPrintServiceFactory;
import javax.print.ServiceUIFactory;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.AttributeSetUtilities;
import javax.print.attribute.HashAttributeSet;
import javax.print.attribute.HashPrintServiceAttributeSet;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.Size2DSyntax;
import javax.print.event.PrintServiceAttributeListener;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.RequestingUserName;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.ColorSupported;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.CopiesSupported;
import javax.print.attribute.standard.Fidelity;
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.SheetCollate;
import javax.print.attribute.standard.Sides;

public class PSStreamPrintService extends StreamPrintService
    implements SunPrinterJobService {

    private static final Class[] suppAttrCats = {
        Chromaticity.class,
        Copies.class,
        Fidelity.class,
        JobName.class,
        Media.class,
        MediaPrintableArea.class,
        OrientationRequested.class,
        PageRanges.class,
        RequestingUserName.class,
        SheetCollate.class,
        Sides.class,
    };

    private static int MAXCOPIES = 1000;

    private static final MediaSizeName mediaSizes[] = {
        MediaSizeName.NA_LETTER,
        MediaSizeName.TABLOID,
        MediaSizeName.LEDGER,
        MediaSizeName.NA_LEGAL,
        MediaSizeName.EXECUTIVE,
        MediaSizeName.ISO_A3,
        MediaSizeName.ISO_A4,
        MediaSizeName.ISO_A5,
        MediaSizeName.ISO_B4,
        MediaSizeName.ISO_B5,
    };

    public PSStreamPrintService(OutputStream out) {
        super(out);
    }

    public String getOutputFormat() {
        return PSStreamPrinterFactory.psMimeType;
    }


    public DocFlavor[] getSupportedDocFlavors() {
        return PSStreamPrinterFactory.getFlavors();
    }

    public DocPrintJob createPrintJob() {
        return new PSStreamPrintJob(this);
    }

    public boolean usesClass(Class c) {
        return (c == sun.print.PSPrinterJob.class);
    }

    public String getName() {
        return "Postscript output";
    }

    public void addPrintServiceAttributeListener(
                         PrintServiceAttributeListener listener) {
        return;
    }

    public void removePrintServiceAttributeListener(
                            PrintServiceAttributeListener listener) {
        return;
    }


    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) {
            return (T)ColorSupported.SUPPORTED;
        } else {
            return null;
        }
    }
    public PrintServiceAttributeSet getAttributes() {
        PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
        attrs.add(ColorSupported.SUPPORTED);

        return AttributeSetUtilities.unmodifiableView(attrs);
    }

    public boolean isDocFlavorSupported(DocFlavor flavor) {
        DocFlavor [] flavors = getSupportedDocFlavors();
        for (int f=0; f<flavors.length; f++) {
            if (flavor.equals(flavors[f])) {
                return true;
            }
        }
        return false;
    }


    public Class<?>[] getSupportedAttributeCategories() {
        Class []cats = new Class[suppAttrCats.length];
        System.arraycopy(suppAttrCats, 0, cats, 0, cats.length);
        return cats;
    }

    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");
        }

        for (int i=0;i<suppAttrCats.length;i++) {
            if (category == suppAttrCats[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;
        }

        if (category == Copies.class) {
            return new Copies(1);
        } else if (category == Chromaticity.class) {
            return Chromaticity.COLOR;
        } else if (category == Fidelity.class) {
            return Fidelity.FIDELITY_FALSE;
        } else if (category == Media.class) {
            String defaultCountry = Locale.getDefault().getCountry();
            if (defaultCountry != null &&
                (defaultCountry.equals("") ||
                 defaultCountry.equals(Locale.US.getCountry()) ||
                 defaultCountry.equals(Locale.CANADA.getCountry()))) {
                return MediaSizeName.NA_LETTER;
            } else {
                 return MediaSizeName.ISO_A4;
            }
        } else if (category == MediaPrintableArea.class) {
            String defaultCountry = Locale.getDefault().getCountry();
            float iw, ih;
            float margin = 0.5f; // both these papers > 5" in all dimensions
            if (defaultCountry != null &&
                (defaultCountry.equals("") ||
                 defaultCountry.equals(Locale.US.getCountry()) ||
                 defaultCountry.equals(Locale.CANADA.getCountry()))) {
                iw = MediaSize.NA.LETTER.getX(Size2DSyntax.INCH) - 2*margin;
                ih = MediaSize.NA.LETTER.getY(Size2DSyntax.INCH) - 2*margin;
            } else {
                iw = MediaSize.ISO.A4.getX(Size2DSyntax.INCH) - 2*margin;
                ih = MediaSize.ISO.A4.getY(Size2DSyntax.INCH) - 2*margin;
            }
            return new MediaPrintableArea(margin, margin, iw, ih,
                                          MediaPrintableArea.INCH);
        } else if (category == OrientationRequested.class) {
            return OrientationRequested.PORTRAIT;
        } else if (category == PageRanges.class) {
            return new PageRanges(1, Integer.MAX_VALUE);
        } else if (category == SheetCollate.class) {
            return SheetCollate.UNCOLLATED;
        } else if (category == Sides.class) {
            return Sides.ONE_SIDED;

        } else
            return null;
    }


    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 && !isDocFlavorSupported(flavor)) {
            throw new IllegalArgumentException(flavor +
                                               " is an unsupported flavor");
        }

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

        if (category == Chromaticity.class) {
            Chromaticity[]arr = new Chromaticity[1];
            arr[0] = Chromaticity.COLOR;
            //arr[1] = Chromaticity.MONOCHROME;
            return (arr);
        } else if (category == JobName.class) {
            return new JobName("", null);
        } else if (category == RequestingUserName.class) {
            return new RequestingUserName("", null);
        } else if (category == OrientationRequested.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
                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)) {
            return new CopiesSupported(1, MAXCOPIES);
        } else if (category == Media.class) {
            Media []arr = new Media[mediaSizes.length];
            System.arraycopy(mediaSizes, 0, arr, 0, mediaSizes.length);
            return arr;
        } else if (category == Fidelity.class) {
            Fidelity []arr = new Fidelity[2];
            arr[0] = Fidelity.FIDELITY_FALSE;
            arr[1] = Fidelity.FIDELITY_TRUE;
            return arr;
        } else if (category == MediaPrintableArea.class) {
            if (attributes == null) {
                return null;
            }
            MediaSize mediaSize = (MediaSize)attributes.get(MediaSize.class);
            if (mediaSize == null) {
                Media media = (Media)attributes.get(Media.class);
                if (media != null && media instanceof MediaSizeName) {
                    MediaSizeName msn = (MediaSizeName)media;
                    mediaSize = MediaSize.getMediaSizeForName(msn);
                }
            }
            if (mediaSize == null) {
                return null;
            } else {
                MediaPrintableArea []arr = new MediaPrintableArea[1];
                float w = mediaSize.getX(MediaSize.INCH);
                float h = mediaSize.getY(MediaSize.INCH);
                /* For dimensions >= 5 inches use 0.5 inch margins.
                 * For smaller dimensions, use 10% margins.
                 */
                float xmargin = 0.5f;
                float ymargin = 0.5f;
                if (w < 5f) {
                    xmargin = w/10;
                }
                if (h < 5f) {
                    ymargin = h/10;
                }
                arr[0] = new MediaPrintableArea(xmargin, ymargin,
                                                w - 2*xmargin,
                                                h - 2*ymargin,
                                                MediaSize.INCH);
                return arr;
            }
        } 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 == 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.UNCOLLATED;
                arr[1] = SheetCollate.COLLATED;
                return arr;
            } else {
                SheetCollate []arr = new SheetCollate[1];
                arr[0] = SheetCollate.UNCOLLATED;
                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 {
            return null;
        }
    }

    private boolean isSupportedCopies(Copies copies) {
        int numCopies = copies.getValue();
        return (numCopies > 0 && numCopies < MAXCOPIES);
    }

    private boolean isSupportedMedia(MediaSizeName msn) {
        for (int i=0; i<mediaSizes.length; i++) {
            if (msn.equals(mediaSizes[i])) {
                return true;
            }
        }
        return false;
    }

    public boolean isAttributeValueSupported(Attribute attr,
                                             DocFlavor flavor,
                                             AttributeSet attributes) {
        if (attr == null) {
            throw new NullPointerException("null attribute");
        }
        if (flavor != null && !isDocFlavorSupported(flavor)) {
            throw new IllegalArgumentException(flavor +
                                               " is an unsupported flavor");
        }
        Class category = attr.getCategory();
        if (!isAttributeCategorySupported(category)) {
            return false;
        }
        else if (attr.getCategory() == Chromaticity.class) {
            return attr == Chromaticity.COLOR;
        }
        else if (attr.getCategory() == Copies.class) {
            return isSupportedCopies((Copies)attr);
        } else if (attr.getCategory() == Media.class &&
                   attr instanceof MediaSizeName) {
            return isSupportedMedia((MediaSizeName)attr);
        } else if (attr.getCategory() == OrientationRequested.class) {
            if (attr == OrientationRequested.REVERSE_PORTRAIT ||
                (flavor != null) &&
                !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
                return false;
            }
        } else if (attr.getCategory() == PageRanges.class) {
            if (flavor != null &&
                !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
                return false;
            }
        } else if (attr.getCategory() == SheetCollate.class) {
            if (flavor != null &&
                !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
                return false;
            }
        } else if (attr.getCategory() == Sides.class) {
            if (flavor != null &&
                !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
                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 "PSStreamPrintService: " + getName();
    }

    /* Stream services have an output stream which cannot be shared,
     * so two services are equal only if they are the same object.
     */
    public boolean equals(Object obj) {
        return (obj == this ||
                 (obj instanceof PSStreamPrintService &&
                 ((PSStreamPrintService)obj).getName().equals(getName())));
    }

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

}
