/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed 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 com.android.assetstudiolib;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.Raster;
import java.awt.image.RescaleOp;
import java.util.ArrayList;
import java.util.List;

/**
 * A set of utility classes for manipulating {@link BufferedImage} objects and drawing them to
 * {@link Graphics2D} canvases.
 */
public class Util {
    /**
     * Scales the given rectangle by the given scale factor.
     *
     * @param rect        The rectangle to scale.
     * @param scaleFactor The factor to scale by.
     * @return The scaled rectangle.
     */
    public static Rectangle scaleRectangle(Rectangle rect, float scaleFactor) {
        return new Rectangle(
                (int) Math.round(rect.x * scaleFactor),
                (int) Math.round(rect.y * scaleFactor),
                (int) Math.round(rect.width * scaleFactor),
                (int) Math.round(rect.height * scaleFactor));
    }

    /**
     * Creates a new ARGB {@link BufferedImage} of the given width and height.
     *
     * @param width  The width of the new image.
     * @param height The height of the new image.
     * @return The newly created image.
     */
    public static BufferedImage newArgbBufferedImage(int width, int height) {
        return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    }

    /**
     * Smoothly scales the given {@link BufferedImage} to the given width and height using the
     * {@link Image#SCALE_SMOOTH} algorithm (generally bicubic resampling or bilinear filtering).
     *
     * @param source The source image.
     * @param width  The destination width to scale to.
     * @param height The destination height to scale to.
     * @return A new, scaled image.
     */
    public static BufferedImage scaledImage(BufferedImage source, int width, int height) {
        Image scaledImage = source.getScaledInstance(width, height, Image.SCALE_SMOOTH);
        BufferedImage scaledBufImage = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_ARGB);
        Graphics g = scaledBufImage.createGraphics();
        g.drawImage(scaledImage, 0, 0, null);
        g.dispose();
        return scaledBufImage;
    }

    /**
     * Applies a gaussian blur of the given radius to the given {@link BufferedImage} using a kernel
     * convolution.
     *
     * @param source The source image.
     * @param radius The blur radius, in pixels.
     * @return A new, blurred image, or the source image if no blur is performed.
     */
    public static BufferedImage blurredImage(BufferedImage source, double radius) {
        if (radius == 0) {
            return source;
        }

        final int r = (int) Math.ceil(radius);
        final int rows = r * 2 + 1;
        final float[] kernelData = new float[rows * rows];

        final double sigma = radius / 3;
        final double sigma22 = 2 * sigma * sigma;
        final double sqrtPiSigma22 = Math.sqrt(Math.PI * sigma22);
        final double radius2 = radius * radius;

        double total = 0;
        int index = 0;
        double distance2;

        int x, y;
        for (y = -r; y <= r; y++) {
            for (x = -r; x <= r; x++) {
                distance2 = 1.0 * x * x + 1.0 * y * y;
                if (distance2 > radius2) {
                    kernelData[index] = 0;
                } else {
                    kernelData[index] = (float) (Math.exp(-distance2 / sigma22) / sqrtPiSigma22);
                }
                total += kernelData[index];
                ++index;
            }
        }

        for (index = 0; index < kernelData.length; index++) {
            kernelData[index] /= total;
        }

        // We first pad the image so the kernel can operate at the edges.
        BufferedImage paddedSource = paddedImage(source, r);
        BufferedImage blurredPaddedImage = operatedImage(paddedSource, new ConvolveOp(
                new Kernel(rows, rows, kernelData), ConvolveOp.EDGE_ZERO_FILL, null));
        return blurredPaddedImage.getSubimage(r, r, source.getWidth(), source.getHeight());
    }

    /**
     * Inverts the alpha channel of the given {@link BufferedImage}. RGB data for the inverted area
     * are undefined, so it's generally best to fill the resulting image with a color.
     *
     * @param source The source image.
     * @return A new image with an alpha channel inverted from the original.
     */
    public static BufferedImage invertedAlphaImage(BufferedImage source) {
        final float[] scaleFactors = new float[]{1, 1, 1, -1};
        final float[] offsets = new float[]{0, 0, 0, 255};

        return operatedImage(source, new RescaleOp(scaleFactors, offsets, null));
    }

    /**
     * Applies a {@link BufferedImageOp} on the given {@link BufferedImage}.
     *
     * @param source The source image.
     * @param op     The operation to perform.
     * @return A new image with the operation performed.
     */
    public static BufferedImage operatedImage(BufferedImage source, BufferedImageOp op) {
        BufferedImage newImage = newArgbBufferedImage(source.getWidth(), source.getHeight());
        Graphics2D g = (Graphics2D) newImage.getGraphics();
        g.drawImage(source, op, 0, 0);
        return newImage;
    }

    /**
     * Fills the given {@link BufferedImage} with a {@link Paint}, preserving its alpha channel.
     *
     * @param source The source image.
     * @param paint  The paint to fill with.
     * @return A new, painted/filled image.
     */
    public static BufferedImage filledImage(BufferedImage source, Paint paint) {
        BufferedImage newImage = newArgbBufferedImage(source.getWidth(), source.getHeight());
        Graphics2D g = (Graphics2D) newImage.getGraphics();
        g.drawImage(source, 0, 0, null);
        g.setComposite(AlphaComposite.SrcAtop);
        g.setPaint(paint);
        g.fillRect(0, 0, source.getWidth(), source.getHeight());
        return newImage;
    }

    /**
     * Pads the given {@link BufferedImage} on all sides by the given padding amount.
     *
     * @param source  The source image.
     * @param padding The amount to pad on all sides, in pixels.
     * @return A new, padded image, or the source image if no padding is performed.
     */
    public static BufferedImage paddedImage(BufferedImage source, int padding) {
        if (padding == 0) {
            return source;
        }

        BufferedImage newImage = newArgbBufferedImage(
                source.getWidth() + padding * 2, source.getHeight() + padding * 2);
        Graphics2D g = (Graphics2D) newImage.getGraphics();
        g.drawImage(source, padding, padding, null);
        return newImage;
    }

    /**
     * Trims the transparent pixels from the given {@link BufferedImage} (returns a sub-image).
     *
     * @param source The source image.
     * @return A new, trimmed image, or the source image if no trim is performed.
     */
    public static BufferedImage trimmedImage(BufferedImage source) {
        final int minAlpha = 1;
        final int srcWidth = source.getWidth();
        final int srcHeight = source.getHeight();
        Raster raster = source.getRaster();
        int l = srcWidth, t = srcHeight, r = 0, b = 0;

        int alpha, x, y;
        int[] pixel = new int[4];
        for (y = 0; y < srcHeight; y++) {
            for (x = 0; x < srcWidth; x++) {
                raster.getPixel(x, y, pixel);
                alpha = pixel[3];
                if (alpha >= minAlpha) {
                    l = Math.min(x, l);
                    t = Math.min(y, t);
                    r = Math.max(x, r);
                    b = Math.max(y, b);
                }
            }
        }

        if (l > r || t > b) {
            // No pixels, couldn't trim
            return source;
        }

        return source.getSubimage(l, t, r - l + 1, b - t + 1);
    }

    /**
     * Draws the given {@link BufferedImage} to the canvas, at the given coordinates, with the given
     * {@link Effect}s applied. Note that drawn effects may be outside the bounds of the source
     * image.
     *
     * @param g       The destination canvas.
     * @param source  The source image.
     * @param x       The x offset at which to draw the image.
     * @param y       The y offset at which to draw the image.
     * @param effects The list of effects to apply.
     */
    public static void drawEffects(Graphics2D g, BufferedImage source, int x, int y,
            Effect[] effects) {
        List<ShadowEffect> shadowEffects = new ArrayList<ShadowEffect>();
        List<FillEffect> fillEffects = new ArrayList<FillEffect>();

        for (Effect effect : effects) {
            if (effect instanceof ShadowEffect) {
                shadowEffects.add((ShadowEffect) effect);
            } else if (effect instanceof FillEffect) {
                fillEffects.add((FillEffect) effect);
            }
        }

        Composite oldComposite = g.getComposite();
        for (ShadowEffect effect : shadowEffects) {
            if (effect.inner) {
                continue;
            }

            // Outer shadow
            g.setComposite(AlphaComposite.getInstance(
                    AlphaComposite.SRC_OVER, (float) effect.opacity));
            g.drawImage(
                    filledImage(
                            blurredImage(source, effect.radius),
                            effect.color),
                    (int) effect.xOffset, (int) effect.yOffset, null);
        }
        g.setComposite(oldComposite);

        // Inner shadow & fill effects.
        final Rectangle imageRect = new Rectangle(0, 0, source.getWidth(), source.getHeight());
        BufferedImage out = newArgbBufferedImage(imageRect.width, imageRect.height);
        Graphics2D g2 = (Graphics2D) out.getGraphics();
        double fillOpacity = 1.0;

        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
        g2.drawImage(source, 0, 0, null);
        g2.setComposite(AlphaComposite.SrcAtop);

        // Gradient fill
        for (FillEffect effect : fillEffects) {
            g2.setPaint(effect.paint);
            g2.fillRect(0, 0, imageRect.width, imageRect.height);
            fillOpacity = Math.max(0, Math.min(1, effect.opacity));
        }

        // Inner shadows
        for (ShadowEffect effect : shadowEffects) {
            if (!effect.inner) {
                continue;
            }

            BufferedImage innerShadowImage = newArgbBufferedImage(
                    imageRect.width, imageRect.height);
            Graphics2D g3 = (Graphics2D) innerShadowImage.getGraphics();
            g3.drawImage(source, (int) effect.xOffset, (int) effect.yOffset, null);
            g2.setComposite(AlphaComposite.getInstance(
                    AlphaComposite.SRC_ATOP, (float) effect.opacity));
            g2.drawImage(
                    filledImage(
                            blurredImage(invertedAlphaImage(innerShadowImage), effect.radius),
                            effect.color),
                    0, 0, null);
        }

        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) fillOpacity));
        g.drawImage(out, x, y, null);
        g.setComposite(oldComposite);
    }

    /**
     * Draws the given {@link BufferedImage} to the canvas, centered, wholly contained within the
     * bounds defined by the destination rectangle, and with preserved aspect ratio.
     *
     * @param g       The destination canvas.
     * @param source  The source image.
     * @param dstRect The destination rectangle in the destination canvas into which to draw the
     *                image.
     */
    public static void drawCenterInside(Graphics2D g, BufferedImage source, Rectangle dstRect) {
        final int srcWidth = source.getWidth();
        final int srcHeight = source.getHeight();
        if (srcWidth * 1.0 / srcHeight > dstRect.width * 1.0 / dstRect.height) {
            final int scaledWidth = Math.max(1, dstRect.width);
            final int scaledHeight = Math.max(1, dstRect.width * srcHeight / srcWidth);
            Image scaledImage = scaledImage(source, scaledWidth, scaledHeight);
            g.drawImage(scaledImage,
                    dstRect.x,
                    dstRect.y + (dstRect.height - scaledHeight) / 2,
                    dstRect.x + dstRect.width,
                    dstRect.y + (dstRect.height - scaledHeight) / 2 + scaledHeight,
                    0,
                    0,
                    0 + scaledWidth,
                    0 + scaledHeight,
                    null);
        } else {
            final int scaledWidth = Math.max(1, dstRect.height * srcWidth / srcHeight);
            final int scaledHeight = Math.max(1, dstRect.height);
            Image scaledImage = scaledImage(source, scaledWidth, scaledHeight);
            g.drawImage(scaledImage,
                    dstRect.x + (dstRect.width - scaledWidth) / 2,
                    dstRect.y,
                    dstRect.x + (dstRect.width - scaledWidth) / 2 + scaledWidth,
                    dstRect.y + dstRect.height,
                    0,
                    0,
                    0 + scaledWidth,
                    0 + scaledHeight,
                    null);
        }
    }

    /**
     * Draws the given {@link BufferedImage} to the canvas, centered and cropped to fill the
     * bounds defined by the destination rectangle, and with preserved aspect ratio.
     *
     * @param g       The destination canvas.
     * @param source  The source image.
     * @param dstRect The destination rectangle in the destination canvas into which to draw the
     *                image.
     */
    public static void drawCenterCrop(Graphics2D g, BufferedImage source, Rectangle dstRect) {
        final int srcWidth = source.getWidth();
        final int srcHeight = source.getHeight();
        if (srcWidth * 1.0 / srcHeight > dstRect.width * 1.0 / dstRect.height) {
            final int scaledWidth = dstRect.height * srcWidth / srcHeight;
            final int scaledHeight = dstRect.height;
            Image scaledImage = scaledImage(source, scaledWidth, scaledHeight);
            g.drawImage(scaledImage,
                    dstRect.x,
                    dstRect.y,
                    dstRect.x + dstRect.width,
                    dstRect.y + dstRect.height,
                    0 + (scaledWidth - dstRect.width) / 2,
                    0,
                    0 + (scaledWidth - dstRect.width) / 2 + dstRect.width,
                    0 + dstRect.height,
                    null);
        } else {
            final int scaledWidth = dstRect.width;
            final int scaledHeight = dstRect.width * srcHeight / srcWidth;
            Image scaledImage = scaledImage(source, scaledWidth, scaledHeight);
            g.drawImage(scaledImage,
                    dstRect.x,
                    dstRect.y,
                    dstRect.x + dstRect.width,
                    dstRect.y + dstRect.height,
                    0,
                    0 + (scaledHeight - dstRect.height) / 2,
                    0 + dstRect.width,
                    0 + (scaledHeight - dstRect.height) / 2 + dstRect.height,
                    null);
        }
    }

    /**
     * An effect to apply in
     * {@link Util#drawEffects(java.awt.Graphics2D, java.awt.image.BufferedImage, int, int, Util.Effect[])}
     */
    public static abstract class Effect {
    }

    /**
     * An inner or outer shadow.
     */
    public static class ShadowEffect extends Effect {
        public double xOffset;
        public double yOffset;
        public double radius;
        public Color color;
        public double opacity;
        public boolean inner;

        public ShadowEffect(double xOffset, double yOffset, double radius, Color color,
                double opacity, boolean inner) {
            this.xOffset = xOffset;
            this.yOffset = yOffset;
            this.radius = radius;
            this.color = color;
            this.opacity = opacity;
            this.inner = inner;
        }
    }

    /**
     * A fill, defined by a paint.
     */
    public static class FillEffect extends Effect {
        public Paint paint;
        public double opacity;

        public FillEffect(Paint paint, double opacity) {
            this.paint = paint;
            this.opacity = opacity;
        }

        public FillEffect(Paint paint) {
            this.paint = paint;
            this.opacity = 1.0;
        }
    }
}
