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

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.imaging.ImageFormat;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.ImageWriteException;
import org.apache.commons.imaging.Sanselan;
import org.apache.commons.imaging.SanselanConstants;
import org.apache.commons.imaging.SanselanTest;
import org.apache.commons.imaging.common.RgbBufferedImageFactory;
import org.apache.commons.imaging.util.Debug;
import org.apache.commons.imaging.util.IoUtils;

public class RoundtripTest extends SanselanTest
{
    private static final int COLOR_FULL_RGB = 0;
    private static final int COLOR_LIMITED_INDEX = 1;
    private static final int COLOR_GRAYSCALE = 2;
    private static final int COLOR_BITMAP = 3;

    private static class FormatInfo
    {

        public final ImageFormat format;
        public final boolean canRead;
        public final boolean canWrite;
        public final int colorSupport;
        public final boolean identicalSecondWrite;

        public FormatInfo(ImageFormat format, boolean canRead,
                boolean canWrite, int colorSupport,
                final boolean identicalSecondWrite)
        {
            this.canRead = canRead;
            this.canWrite = canWrite;
            this.colorSupport = colorSupport;
            this.format = format;
            this.identicalSecondWrite = identicalSecondWrite;
        }
    }

    private static final FormatInfo FORMAT_INFOS[] = { //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_PNG, true, true,
                    COLOR_FULL_RGB, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_GIF, true, true,
                    COLOR_LIMITED_INDEX, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_ICO, true, true,
                    COLOR_FULL_RGB, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_TIFF, true, true,
                    COLOR_FULL_RGB, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_JPEG, true, false,
                    COLOR_FULL_RGB, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_BMP, true, true,
                    COLOR_FULL_RGB, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_PSD, true, false,
                    COLOR_FULL_RGB, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_PBM, true, true,
                    COLOR_BITMAP, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_PGM, true, true,
                    COLOR_GRAYSCALE, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_PPM, true, true,
                    COLOR_FULL_RGB, true), //
            // new FormatInfo(ImageFormat.IMAGE_FORMAT_PNM, true, true,
            // COLOR_FULL_RGB, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_TGA, false, false,
                    COLOR_FULL_RGB, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_WBMP, true, true,
                    COLOR_BITMAP, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_PCX, true, true,
                    COLOR_FULL_RGB, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_DCX, true, true,
                    COLOR_FULL_RGB, true), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_XBM, true, true,
                    COLOR_BITMAP, false), //
            new FormatInfo(ImageFormat.IMAGE_FORMAT_XPM, true, true,
                    COLOR_FULL_RGB, false), //
    };

    private BufferedImage createArgbBitmapImage(int width, int height)
    {
        BufferedImage result = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_ARGB);
        for (int x = 0; x < width; x++)
            for (int y = 0; y < height; y++)
            {
                // alternating black and white.
                int modulator = y + 2; // make sure lines vary.
                int argb = (x + y) % modulator == 0 ? 0xff000000 : 0xffffffff;
                result.setRGB(x, y, argb);
            }
        return result;
    }

    private BufferedImage createBitmapBitmapImage(int width, int height)
    {
        BufferedImage result = new BufferedImage(width, height,
                BufferedImage.TYPE_BYTE_BINARY);
        for (int x = 0; x < width; x++)
            for (int y = 0; y < height; y++)
            {
                // alternating black and white.
                int modulator = y + 2; // make sure lines vary.
                int argb = (x + y) % modulator == 0 ? 0xff000000 : 0xffffffff;
                result.setRGB(x, y, argb);
            }
        return result;
    }

    private BufferedImage createArgbGrayscaleImage(int width, int height)
    {
        BufferedImage result = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_ARGB);
        for (int x = 0; x < width; x++)
            for (int y = 0; y < height; y++)
            {
                int value = (256 * (x + y)) / (width + height);
                int argb = (0xff << 24) | (value << 16) | (value << 8)
                        | (value << 0);

                result.setRGB(x, y, argb);
            }
        return result;
    }

    private BufferedImage createGrayscaleGrayscaleImage(int width, int height)
    {
        BufferedImage result = new BufferedImage(width, height,
                BufferedImage.TYPE_BYTE_GRAY);
        for (int x = 0; x < width; x++)
            for (int y = 0; y < height; y++)
            {
                int value = (256 * (x + y)) / (width + height);
                int argb = (0xff << 24) | (value << 16) | (value << 8)
                        | (value << 0);

                result.setRGB(x, y, argb);
            }
        return result;
    }

    private BufferedImage createLimitedColorImage(int width, int height)
    {
        int colors[] = { 0xffffffff, 0xff000000, 0xfff00000, 0xff0000ff,
                0xff123456, 0xfffefeff, 0xff7f817f, };

        BufferedImage result = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_ARGB);
        for (int x = 0; x < width; x++)
            for (int y = 0; y < height; y++)
            {
                int argb = colors[(x + y) % colors.length];
                result.setRGB(x, y, argb);
            }
        return result;
    }

    private BufferedImage createFullColorImage(int width, int height)
    {
        BufferedImage result = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_ARGB);
        for (int x = 0; x < width; x++)
            for (int y = 0; y < height; y++)
            {
                int red = (x * 255) / width;
                int green = (y * 255) / height;
                int blue = ((x + y) * 255) / (width + height);
                int argb = (0xff << 24) | (red << 16) | (green << 8)
                        | (blue << 0);
                result.setRGB(x, y, argb);
            }
        return result;
    }

    private void compareImagesExact(BufferedImage a, BufferedImage b)
    {
        compareImages(a, b, 0);
    }

    // private void compareImagesOffByOne(BufferedImage a, BufferedImage b)
    // {
    // compareImages(a, b, 3); // one bit of rounding error for each channel
    // }

    private void compareImages(BufferedImage a, BufferedImage b, int tolerance)
    {
        assertEquals(a.getWidth(), b.getWidth());
        assertEquals(a.getHeight(), b.getHeight());

        for (int x = 0; x < a.getWidth(); x++)
            for (int y = 0; y < a.getHeight(); y++)
            {
                int a_argb = a.getRGB(x, y);
                int b_argb = b.getRGB(x, y);
                if (a_argb != b_argb)
                {
                    if (calculateARGBDistance(a_argb, b_argb) <= tolerance)
                        continue; // ignore.
                }
                if (a_argb != b_argb)
                {
                    Debug.debug("width", a.getWidth());
                    Debug.debug("height", a.getHeight());
                    Debug.debug("distance", calculateARGBDistance(a_argb,
                            b_argb));
                    Debug.debug("x", x);
                    Debug.debug("y", y);
                    Debug.debug("a_argb", a_argb + " (0x"
                            + Integer.toHexString(a_argb) + ")");
                    Debug.debug("b_argb", b_argb + " (0x"
                            + Integer.toHexString(b_argb) + ")");
                }
                assertEquals(a_argb, b_argb);
            }
    }

    private int calculateARGBDistance(int a, int b)
    {
        int aAlpha = 0xff & (a >> 24);
        int aRed = 0xff & (a >> 16);
        int aGreen = 0xff & (a >> 8);
        int aBlue = 0xff & (a >> 0);
        int bAlpha = 0xff & (b >> 24);
        int bRed = 0xff & (b >> 16);
        int bGreen = 0xff & (b >> 8);
        int bBlue = 0xff & (b >> 0);
        int diff = Math.abs(aAlpha - bAlpha) + Math.abs(aRed - bRed)
                + Math.abs(aGreen - bGreen) + Math.abs(aBlue - bBlue);
        return diff;

    }

    private void compareFilesExact(File a, File b) throws IOException
    {
        assertTrue(a.exists() && a.isFile());
        assertTrue(b.exists() && b.isFile());
        assertEquals(a.length(), b.length());

        byte aData[] = IoUtils.getFileBytes(a);
        byte bData[] = IoUtils.getFileBytes(b);

        for (int i = 0; i < a.length(); i++)
        {
            int aByte = 0xff & aData[i];
            int bByte = 0xff & bData[i];

            if (aByte != bByte)
            {
                Debug.debug("a", a);
                Debug.debug("b", b);
                Debug.debug("i", i);
                Debug.debug("aByte", aByte + " (0x"
                        + Integer.toHexString(aByte) + ")");
                Debug.debug("bByte", bByte + " (0x"
                        + Integer.toHexString(bByte) + ")");
            }
            assertEquals(aByte, bByte);
        }
    }

    public void testBitmapRoundtrip() throws Exception
    {
        BufferedImage testImages[] = { //

        createArgbBitmapImage(1, 1), // minimal
                createArgbBitmapImage(2, 2), //
                createArgbBitmapImage(10, 10), // larger than 8
                createArgbBitmapImage(300, 300), // larger than 256

                createBitmapBitmapImage(1, 1), // minimal
                createBitmapBitmapImage(2, 2), //
                createBitmapBitmapImage(10, 10), // larger than 8
                createBitmapBitmapImage(300, 300), // larger than 256
        };

        for (int j = 0; j < testImages.length; j++)
        {
            BufferedImage testImage = testImages[j];

            for (int i = 0; i < FORMAT_INFOS.length; i++)
            {
                FormatInfo formatInfo = FORMAT_INFOS[i];
                if ((!formatInfo.canRead) || (!formatInfo.canWrite))
                    continue;

                Debug.debug("bitmap test: " + formatInfo.format.name);

                roundtrip(formatInfo, testImage, "bitmap", true);
            }
        }
    }

    public void testGrayscaleRoundtrip() throws Exception
    {
        BufferedImage testImages[] = { //

        createArgbBitmapImage(1, 1), // minimal
                createArgbGrayscaleImage(2, 2), //
                createArgbGrayscaleImage(10, 10), // larger than 8
                createArgbGrayscaleImage(300, 300), // larger than 256

                createGrayscaleGrayscaleImage(1, 1), // minimal
                createGrayscaleGrayscaleImage(2, 2), //
                createGrayscaleGrayscaleImage(10, 10), // larger than 8
                createGrayscaleGrayscaleImage(300, 300), // larger than 256
        };

        for (int j = 0; j < testImages.length; j++)
        {
            BufferedImage testImage = testImages[j];

            for (int i = 0; i < FORMAT_INFOS.length; i++)
            {
                FormatInfo formatInfo = FORMAT_INFOS[i];
                if ((!formatInfo.canRead) || (!formatInfo.canWrite))
                    continue;

                Debug.debug("grayscale test: " + formatInfo.format.name);

                boolean imageExact = true;
                if (formatInfo.colorSupport == COLOR_BITMAP)
                    imageExact = false;

                roundtrip(formatInfo, testImage, "gray", imageExact);
            }
        }
    }

    public void testLimitedColorRoundtrip() throws Exception
    {
        BufferedImage testImages[] = { //

        createLimitedColorImage(1, 1), // minimal
                createLimitedColorImage(2, 2), //
                createLimitedColorImage(10, 10), // larger than 8
                createLimitedColorImage(300, 300), // larger than 256
        };

        for (int j = 0; j < testImages.length; j++)
        {
            BufferedImage testImage = testImages[j];

            for (int i = 0; i < FORMAT_INFOS.length; i++)
            {
                FormatInfo formatInfo = FORMAT_INFOS[i];
                if ((!formatInfo.canRead) || (!formatInfo.canWrite))
                    continue;

                Debug.debug("indexable test: " + formatInfo.format.name);

                boolean imageExact = true;
                if (formatInfo.colorSupport == COLOR_BITMAP)
                    imageExact = false;
                if (formatInfo.colorSupport == COLOR_GRAYSCALE)
                    imageExact = false;

                roundtrip(formatInfo, testImage, "indexable", imageExact);
            }
        }
    }

    public void testFullColorRoundtrip() throws Exception
    {
        BufferedImage testImages[] = { //

        createFullColorImage(1, 1), // minimal
                createFullColorImage(2, 2), //
                createFullColorImage(10, 10), // larger than 8
                createFullColorImage(300, 300), // larger than 256
        };

        for (int j = 0; j < testImages.length; j++)
        {
            BufferedImage testImage = testImages[j];

            for (int i = 0; i < FORMAT_INFOS.length; i++)
            {
                FormatInfo formatInfo = FORMAT_INFOS[i];
                if ((!formatInfo.canRead) || (!formatInfo.canWrite))
                    continue;

                Debug.debug("fullColor test: " + formatInfo.format.name);

                boolean imageExact = true;
                if (formatInfo.colorSupport == COLOR_BITMAP)
                    imageExact = false;
                if (formatInfo.colorSupport == COLOR_GRAYSCALE)
                    imageExact = false;
                if (formatInfo.colorSupport == COLOR_LIMITED_INDEX)
                    imageExact = false;

                roundtrip(formatInfo, testImage, "fullColor", imageExact);
            }
        }
    }

    private void roundtrip(FormatInfo formatInfo, BufferedImage testImage,
            String tempPrefix, boolean imageExact) throws IOException,
            ImageReadException, ImageWriteException
    {
        File temp1 = createTempFile(tempPrefix + ".", "."
                + formatInfo.format.extension);
        // Debug.debug("tempFile: " + tempFile.getName());

        Map params = new HashMap();
        Sanselan.writeImage(testImage, temp1, formatInfo.format, params);

        Map readParams = new HashMap();
        readParams.put(SanselanConstants.BUFFERED_IMAGE_FACTORY,
                new RgbBufferedImageFactory());
        BufferedImage image2 = Sanselan.getBufferedImage(temp1, readParams);
        assertNotNull(image2);

        if (imageExact)
        {
            // note tolerance when comparing grayscale images
            // BufferedImages of
            compareImagesExact(testImage, image2);
        }

        if (formatInfo.identicalSecondWrite)
        {
            File temp2 = createTempFile(tempPrefix + ".", "."
                    + formatInfo.format.extension);
            // Debug.debug("tempFile: " + tempFile.getName());
            Sanselan.writeImage(image2, temp2, formatInfo.format, params);

            compareFilesExact(temp1, temp2);
        }
    }

}
