/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.xmlgraphics.image.writer.internal;

import java.awt.color.ColorSpace;
import java.awt.image.ColorModel;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.xmlgraphics.image.codec.tiff.TIFFEncodeParam;
import org.apache.xmlgraphics.image.codec.tiff.TIFFField;
import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder;
import org.apache.xmlgraphics.image.codec.tiff.TIFFImageEncoder;
import org.apache.xmlgraphics.image.writer.AbstractImageWriter;
import org.apache.xmlgraphics.image.writer.ImageWriter;
import org.apache.xmlgraphics.image.writer.ImageWriterParams;
import org.apache.xmlgraphics.image.writer.MultiImageWriter;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;

/**
 * ImageWriter implementation that uses the internal TIFF codec to 
 * write TIFF files.
 *
 * @version $Id$
 */
public class TIFFImageWriter extends AbstractImageWriter {

    /**
     * @see ImageWriter#writeImage(java.awt.image.RenderedImage, java.io.OutputStream)
     */
    public void writeImage(RenderedImage image, OutputStream out)
            throws IOException {
        writeImage(image, out, null);
    }

    /**
     * @see ImageWriter#writeImage(java.awt.image.RenderedImage, java.io.OutputStream, ImageWriterParams)
     */
    public void writeImage(RenderedImage image, OutputStream out,
            ImageWriterParams params) throws IOException {
        TIFFEncodeParam encodeParams = createTIFFEncodeParams(params);
        updateParams(encodeParams, params, image);
        TIFFImageEncoder encoder = new TIFFImageEncoder(out, encodeParams);
        encoder.encode(image);
    }

    /**
     * This method updates the encode parameters based on the image to be encoded. One thing done
     * here is to initialize the JPEG encoding parameters if JPEG compression is selected.
     * @param encodeParams the TIFF encoding parameters
     * @param image the image to be encoded
     */
    private void updateParams(TIFFEncodeParam encodeParams, ImageWriterParams params, 
            RenderedImage image) {
        if (encodeParams.getCompression() == TIFFEncodeParam.COMPRESSION_JPEG_TTN2) {
            ColorModel cm = image.getColorModel();
            int imageType = cm.getColorSpace().getType();
            int colorID;
            //The following translation table is taken from the Javadoc for JPEGEncodeParam.
            switch (imageType) {
            case ColorSpace.TYPE_GRAY:
                colorID = JPEGEncodeParam.COLOR_ID_GRAY;
                break;
            case ColorSpace.TYPE_RGB:
                if (cm.hasAlpha()) {
                    colorID = JPEGEncodeParam.COLOR_ID_YCbCrA;
                } else {
                    colorID = JPEGEncodeParam.COLOR_ID_YCbCr;
                }
                break;
            case ColorSpace.TYPE_YCbCr:
                if (cm.hasAlpha()) {
                    colorID = JPEGEncodeParam.COLOR_ID_YCbCrA;
                } else {
                    colorID = JPEGEncodeParam.COLOR_ID_YCbCr;
                }
                break;
            case ColorSpace.TYPE_CMYK:
                colorID = JPEGEncodeParam.COLOR_ID_CMYK;
                break;
            default:
                //TODO Don't know how to determine whether image is PYCC or not 
                //(see JPEGEncodeParam)
                colorID = JPEGEncodeParam.COLOR_ID_UNKNOWN;
            }
            JPEGEncodeParam jpegParam = JPEGCodec.getDefaultJPEGEncodeParam(
                    image.getData(), colorID);
            if (params.getJPEGQuality() != null || params.getJPEGForceBaseline() != null) {
                float qual = (params.getJPEGQuality() != null 
                        ? params.getJPEGQuality().floatValue() : 0.75f);
                boolean force = (params.getJPEGForceBaseline() != null
                        ? params.getJPEGForceBaseline().booleanValue() : false);
                jpegParam.setQuality(qual, force); 
            }
            encodeParams.setJPEGEncodeParam(jpegParam);
        }
    }

    private TIFFEncodeParam createTIFFEncodeParams(ImageWriterParams params) {
        TIFFEncodeParam encodeParams = new TIFFEncodeParam();
        if (params == null) {
            encodeParams.setCompression(TIFFEncodeParam.COMPRESSION_NONE);
        } else {
            if (params.getCompressionMethod() == null) {
                //PackBits as default
                encodeParams.setCompression(TIFFEncodeParam.COMPRESSION_PACKBITS);
            } else if ("PackBits".equalsIgnoreCase(params.getCompressionMethod())) {
                encodeParams.setCompression(TIFFEncodeParam.COMPRESSION_PACKBITS);
            } else if ("NONE".equalsIgnoreCase(params.getCompressionMethod())) {
                encodeParams.setCompression(TIFFEncodeParam.COMPRESSION_NONE);
            } else if ("JPEG".equalsIgnoreCase(params.getCompressionMethod())) {
                encodeParams.setCompression(TIFFEncodeParam.COMPRESSION_JPEG_TTN2);
            } else if ("Deflate".equalsIgnoreCase(params.getCompressionMethod())) {
                encodeParams.setCompression(TIFFEncodeParam.COMPRESSION_DEFLATE);
            } else {
                throw new UnsupportedOperationException("Compression method not supported: "
                        + params.getCompressionMethod());
            }
            
            if (params.getResolution() != null) {
                // Set target resolution
                float pixSzMM = 25.4f / params.getResolution().floatValue();
                // num Pixs in 100 Meters
                int numPix = (int)(((1000 * 100) / pixSzMM) + 0.5); 
                int denom = 100 * 100;  // Centimeters per 100 Meters;
                long [] rational = {numPix, denom};
                TIFFField [] fields = {
                    new TIFFField(TIFFImageDecoder.TIFF_RESOLUTION_UNIT, 
                                  TIFFField.TIFF_SHORT, 1, 
                                  new char[] {(char)3}),
                    new TIFFField(TIFFImageDecoder.TIFF_X_RESOLUTION, 
                                  TIFFField.TIFF_RATIONAL, 1, 
                                  new long[][] {rational}),
                    new TIFFField(TIFFImageDecoder.TIFF_Y_RESOLUTION, 
                                  TIFFField.TIFF_RATIONAL, 1, 
                                  new long[][] {rational}) 
                        };
                encodeParams.setExtraFields(fields);
            }
        }
        return encodeParams;
    }
    
    /**
     * @see ImageWriter#getMIMEType()
     */
    public String getMIMEType() {
        return "image/tiff";
    }
    
    /**
     * @see org.apache.xmlgraphics.image.writer.ImageWriter#createMultiImageWriter(
     *          java.io.OutputStream)
     */
    public MultiImageWriter createMultiImageWriter(OutputStream out) throws IOException {
        return new TIFFMultiImageWriter(out);
    }

    /** @see org.apache.xmlgraphics.image.writer.ImageWriter#supportsMultiImageWriter() */
    public boolean supportsMultiImageWriter() {
        return true;
    }

    private class TIFFMultiImageWriter implements MultiImageWriter {

        private OutputStream out;
        private TIFFEncodeParam encodeParams;
        private TIFFImageEncoder encoder;
        private Object context;
        
        public TIFFMultiImageWriter(OutputStream out) throws IOException {
            this.out = out;
        }
        
        public void writeImage(RenderedImage image, ImageWriterParams params) throws IOException {
            if (encoder == null) {
                encodeParams = createTIFFEncodeParams(params);
                updateParams(encodeParams, params, image);
                encoder = new TIFFImageEncoder(out, encodeParams);
            }
            context = encoder.encodeMultiple(context, image);
        }
        
        public void close() throws IOException {
            if (encoder != null) {
                encoder.finishMultiple(context);
            }
            encoder = null;
            encodeParams = null;
            out.flush();
        }

    }

    
}
