/*
 * 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;

import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.common.BinaryFileParser;
import org.apache.commons.imaging.common.bytesource.ByteSource;
import org.apache.commons.imaging.util.Debug;

public class JpegUtils extends BinaryFileParser implements JpegConstants
{
    public JpegUtils()
    {
        setByteOrder(BYTE_ORDER_NETWORK);
    }

    public static interface Visitor
    {
        // return false to exit before reading image data.
        public boolean beginSOS();

        public void visitSOS(int marker, byte markerBytes[], byte imageData[]);

        // return false to exit traversal.
        public boolean visitSegment(int marker, byte markerBytes[],
                int segmentLength, byte segmentLengthBytes[],
                byte segmentData[]) throws ImageReadException,
        // ImageWriteException,
                IOException;
    }

    public void traverseJFIF(ByteSource byteSource, Visitor visitor)
            throws ImageReadException,
            // ImageWriteException,
            IOException
    {
        InputStream is = null;

        try
        {
            is = byteSource.getInputStream();

            readAndVerifyBytes(is, SOI,
                    "Not a Valid JPEG File: doesn't begin with 0xffd8");

            int byteOrder = getByteOrder();

            for (int markerCount = 0; true; markerCount++)
            {
                byte[] markerBytes = new byte[2];
                do {
                    markerBytes[0] = markerBytes[1];
                    markerBytes[1] = readByte("marker", is, "Could not read marker");
                } while ((0xff & markerBytes[0]) != 0xff || (0xff & markerBytes[1]) == 0xff);
                int marker = ((0xff & markerBytes[0]) << 8) | (0xff & markerBytes[1]);

//                Debug.debug("marker", marker + " (0x" + Integer.toHexString(marker) + ")");
//                Debug.debug("markerBytes", markerBytes);

                if (marker == EOIMarker || marker == SOS_Marker)
                {
                    if (!visitor.beginSOS())
                        return;

                    byte imageData[] = getStreamBytes(is);
                    visitor.visitSOS(marker, markerBytes, imageData);
                    break;
                }

                byte segmentLengthBytes[] = readByteArray("segmentLengthBytes",
                        2, is, "segmentLengthBytes");
                int segmentLength = convertByteArrayToShort("segmentLength",
                        segmentLengthBytes, byteOrder);

//                Debug.debug("segmentLength", segmentLength + " (0x" + Integer.toHexString(segmentLength) + ")");
//                Debug.debug("segmentLengthBytes", segmentLengthBytes);

                byte segmentData[] = readByteArray("Segment Data",
                        segmentLength - 2, is,
                        "Invalid Segment: insufficient data");

                // Debug.debug("segmentLength", segmentLength);

                if (!visitor.visitSegment(marker, markerBytes, segmentLength,
                        segmentLengthBytes, segmentData))
                    return;
            }

        } finally
        {
            try
            {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e)
            {
                Debug.debug(e);
            }
        }
    }

    public static String getMarkerName(int marker)
    {
        switch (marker)
        {
        case SOS_Marker:
            return "SOS_Marker";
            // case JPEG_APP0 :
            // return "JPEG_APP0";
            // case JPEG_APP0_Marker :
            // return "JPEG_APP0_Marker";
        case JPEG_APP1_Marker:
            return "JPEG_APP1_Marker";
        case JPEG_APP2_Marker:
            return "JPEG_APP2_Marker";
        case JPEG_APP13_Marker:
            return "JPEG_APP13_Marker";
        case JPEG_APP14_Marker:
            return "JPEG_APP14_Marker";
        case JPEG_APP15_Marker:
            return "JPEG_APP15_Marker";
        case JFIFMarker:
            return "JFIFMarker";
        case SOF0Marker:
            return "SOF0Marker";
        case SOF1Marker:
            return "SOF1Marker";
        case SOF2Marker:
            return "SOF2Marker";
        case SOF3Marker:
            return "SOF3Marker";
        case DHTMarker:
            return "SOF4Marker";
        case SOF5Marker:
            return "SOF5Marker";
        case SOF6Marker:
            return "SOF6Marker";
        case SOF7Marker:
            return "SOF7Marker";
        case SOF8Marker:
            return "SOF8Marker";
        case SOF9Marker:
            return "SOF9Marker";
        case SOF10Marker:
            return "SOF10Marker";
        case SOF11Marker:
            return "SOF11Marker";
        case DACMarker:
            return "DACMarker";
        case SOF13Marker:
            return "SOF13Marker";
        case SOF14Marker:
            return "SOF14Marker";
        case SOF15Marker:
            return "SOF15Marker";
        case DQTMarker:
            return "DQTMarker";
        default:
            return "Unknown";
        }
    }

    public void dumpJFIF(ByteSource byteSource) throws ImageReadException,
            IOException
    {
        Visitor visitor = new Visitor() {
            // return false to exit before reading image data.
            public boolean beginSOS()
            {
                return true;
            }

            public void visitSOS(int marker, byte markerBytes[],
                    byte imageData[])
            {
                Debug.debug("SOS marker.  " + imageData.length
                        + " bytes of image data.");
                Debug.debug("");
            }

            // return false to exit traversal.
            public boolean visitSegment(int marker, byte markerBytes[],
                    int segmentLength, byte segmentLengthBytes[],
                    byte segmentData[])
            {
                Debug.debug("Segment marker: " + Integer.toHexString(marker)
                        + " (" + getMarkerName(marker) + "), "
                        + segmentData.length + " bytes of segment data.");
                return true;
            }
        };

        traverseJFIF(byteSource, visitor);
    }
}