/*
 * 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.
 */
package org.apache.commons.imaging.formats.jpeg.xmp;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.ImageWriteException;
import org.apache.commons.imaging.common.bytesource.ByteSource;
import org.apache.commons.imaging.common.bytesource.ByteSourceArray;
import org.apache.commons.imaging.common.bytesource.ByteSourceFile;
import org.apache.commons.imaging.common.bytesource.ByteSourceInputStream;

/**
 * Interface for Exif write/update/remove functionality for Jpeg/JFIF images.
 * <p>
 * <p>
 * See the source of the XmpXmlUpdateExample class for example usage.
 *
 * @see org.apache.commons.sanselan.examples.WriteXmpXmlExample
 */
public class JpegXmpRewriter extends JpegRewriter
{

    /**
     * Reads a Jpeg image, removes all XMP XML (by removing the APP1 segment),
     * and writes the result to a stream.
     * <p>
     *
     * @param src
     *            Image file.
     * @param os
     *            OutputStream to write the image to.
     *
     * @see java.io.File
     * @see java.io.OutputStream
     */
    public void removeXmpXml(File src, OutputStream os)
            throws ImageReadException, IOException
    {
        ByteSource byteSource = new ByteSourceFile(src);
        removeXmpXml(byteSource, os);
    }

    /**
     * Reads a Jpeg image, removes all XMP XML (by removing the APP1 segment),
     * and writes the result to a stream.
     * <p>
     *
     * @param src
     *            Byte array containing Jpeg image data.
     * @param os
     *            OutputStream to write the image to.
     */
    public void removeXmpXml(byte src[], OutputStream os)
            throws ImageReadException, IOException
    {
        ByteSource byteSource = new ByteSourceArray(src);
        removeXmpXml(byteSource, os);
    }

    /**
     * Reads a Jpeg image, removes all XMP XML (by removing the APP1 segment),
     * and writes the result to a stream.
     * <p>
     *
     * @param src
     *            InputStream containing Jpeg image data.
     * @param os
     *            OutputStream to write the image to.
     */
    public void removeXmpXml(InputStream src, OutputStream os)
            throws ImageReadException, IOException
    {
        ByteSource byteSource = new ByteSourceInputStream(src, null);
        removeXmpXml(byteSource, os);
    }

    /**
     * Reads a Jpeg image, removes all XMP XML (by removing the APP1 segment),
     * and writes the result to a stream.
     * <p>
     *
     * @param byteSource
     *            ByteSource containing Jpeg image data.
     * @param os
     *            OutputStream to write the image to.
     */
    public void removeXmpXml(ByteSource byteSource, OutputStream os)
            throws ImageReadException, IOException
    {
        JFIFPieces jfifPieces = analyzeJFIF(byteSource);
        List<JFIFPiece> pieces = jfifPieces.pieces;
        pieces = removeXmpSegments(pieces);
        writeSegments(os, pieces);
    }

    /**
     * Reads a Jpeg image, replaces the XMP XML and writes the result to a
     * stream.
     *
     * @param src
     *            Byte array containing Jpeg image data.
     * @param os
     *            OutputStream to write the image to.
     * @param xmpXml
     *            String containing XMP XML.
     */
    public void updateXmpXml(byte src[], OutputStream os, String xmpXml)
            throws ImageReadException, IOException, ImageWriteException
    {
        ByteSource byteSource = new ByteSourceArray(src);
        updateXmpXml(byteSource, os, xmpXml);
    }

    /**
     * Reads a Jpeg image, replaces the XMP XML and writes the result to a
     * stream.
     *
     * @param src
     *            InputStream containing Jpeg image data.
     * @param os
     *            OutputStream to write the image to.
     * @param xmpXml
     *            String containing XMP XML.
     */
    public void updateXmpXml(InputStream src, OutputStream os, String xmpXml)
            throws ImageReadException, IOException, ImageWriteException
    {
        ByteSource byteSource = new ByteSourceInputStream(src, null);
        updateXmpXml(byteSource, os, xmpXml);
    }

    /**
     * Reads a Jpeg image, replaces the XMP XML and writes the result to a
     * stream.
     *
     * @param src
     *            Image file.
     * @param os
     *            OutputStream to write the image to.
     * @param xmpXml
     *            String containing XMP XML.
     */
    public void updateXmpXml(File src, OutputStream os, String xmpXml)
            throws ImageReadException, IOException, ImageWriteException
    {
        ByteSource byteSource = new ByteSourceFile(src);
        updateXmpXml(byteSource, os, xmpXml);
    }

    /**
     * Reads a Jpeg image, replaces the XMP XML and writes the result to a
     * stream.
     *
     * @param byteSource
     *            ByteSource containing Jpeg image data.
     * @param os
     *            OutputStream to write the image to.
     * @param xmpXml
     *            String containing XMP XML.
     */
    public void updateXmpXml(ByteSource byteSource, OutputStream os,
            String xmpXml) throws ImageReadException, IOException,
            ImageWriteException
    {
        JFIFPieces jfifPieces = analyzeJFIF(byteSource);
        List<JFIFPiece> pieces = jfifPieces.pieces;
        pieces = removeXmpSegments(pieces);

        List<JFIFPieceSegment> newPieces = new ArrayList<JFIFPieceSegment>();
        byte xmpXmlBytes[] = xmpXml.getBytes("utf-8");
        int index = 0;
        while (index < xmpXmlBytes.length)
        {
            int segmentSize = Math.min(xmpXmlBytes.length, MAX_SEGMENT_SIZE);
            byte segmentData[] = writeXmpSegment(xmpXmlBytes, index,
                    segmentSize);
            newPieces.add(new JFIFPieceSegment(JPEG_APP1_Marker, segmentData));
            index += segmentSize;
        }

        pieces = insertAfterLastAppSegments(pieces, newPieces);

        writeSegments(os, pieces);
    }

    private byte[] writeXmpSegment(byte xmpXmlData[], int start, int length)
            throws IOException
    {
        ByteArrayOutputStream os = new ByteArrayOutputStream();

        XMP_IDENTIFIER.writeTo(os);
        os.write(xmpXmlData, start, length);

        return os.toByteArray();
    }

}