/*
 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.lwawt.macosx;

import java.awt.*;
import java.awt.geom.Dimension2D;
import java.awt.image.*;

import java.util.Arrays;
import java.util.List;
import java.awt.image.MultiResolutionImage;
import sun.awt.image.MultiResolutionCachedImage;

import sun.awt.image.SunWritableRaster;

public class CImage extends CFRetainedResource {
    private static native long nativeCreateNSImageFromArray(int[] buffer, int w, int h);
    private static native long nativeCreateNSImageFromBytes(byte[] buffer);
    private static native long nativeCreateNSImageFromArrays(int[][] buffers, int w[], int h[]);
    private static native long nativeCreateNSImageFromFileContents(String file);
    private static native long nativeCreateNSImageOfFileFromLaunchServices(String file);
    private static native long nativeCreateNSImageFromImageName(String name);
    private static native long nativeCreateNSImageFromIconSelector(int selector);
    private static native byte[] nativeGetPlatformImageBytes(int[] buffer, int w, int h);
    private static native void nativeCopyNSImageIntoArray(long image, int[] buffer, int sw, int sh, int dw, int dh);
    private static native Dimension2D nativeGetNSImageSize(long image);
    private static native void nativeSetNSImageSize(long image, double w, double h);
    private static native void nativeResizeNSImageRepresentations(long image, double w, double h);
    private static native Dimension2D[] nativeGetNSImageRepresentationSizes(long image, double w, double h);

    static Creator creator = new Creator();
    static Creator getCreator() {
        return creator;
    }

    // This is used to create a CImage that represents the icon of the given file.
    public static Image createImageOfFile(String file, int width, int height) {
        return getCreator().createImageOfFile(file, width, height);
    }

    public static Image createSystemImageFromSelector(String iconSelector,
            int width, int height) {
        return getCreator().createSystemImageFromSelector(iconSelector, width, height);
    }

    public static Image createImageFromFile(String file, double width, double height) {
        return getCreator().createImageFromFile(file, width, height);
    }

    // This is used to create a CImage from a Image
    public static CImage createFromImage(final Image image) {
        return getCreator().createFromImage(image);
    }

    public static class Creator {
        Creator() { }

        // This is used to create a CImage with an NSImage pointer. It MUST be a CFRetained
        // NSImage, and the CImage takes ownership of the non-GC retain. If callers need the
        // NSImage themselves, they MUST call retain on the NSImage themselves.
        public Image createImageUsingNativeSize(final long image) {
            if (image == 0) return null;
            final Dimension2D size = nativeGetNSImageSize(image);
            return createImage(image, size.getWidth(), size.getHeight());
        }

        // the width and height passed in as a parameter could differ than the width and the height of the NSImage (image), in that case, the image will be scaled
        Image createImage(long image, double width, double height) {
            if (image == 0) throw new Error("Unable to instantiate CImage with null native image reference.");
            return createImageWithSize(image, width, height);
        }

        public Image createImageWithSize(final long image, final double width, final double height) {
            final CImage img = new CImage(image);
            img.resize(width, height);
            return img.toImage();
        }

        // This is used to create a CImage that represents the icon of the given file.
        public Image createImageOfFile(final String file, final int width, final int height) {
            return createImage(nativeCreateNSImageOfFileFromLaunchServices(file), width, height);
        }

        public Image createImageFromFile(final String file, final double width, final double height) {
            final long image = nativeCreateNSImageFromFileContents(file);
            nativeSetNSImageSize(image, width, height);
            return createImage(image, width, height);
        }

        public Image createSystemImageFromSelector(final String iconSelector, final int width, final int height) {
            return createImage(nativeCreateNSImageFromIconSelector(getSelectorAsInt(iconSelector)), width, height);
        }

        public Image createImageFromName(final String name, final int width, final int height) {
            return createImage(nativeCreateNSImageFromImageName(name), width, height);
        }

        public Image createImageFromName(final String name) {
            return createImageUsingNativeSize(nativeCreateNSImageFromImageName(name));
        }

        private static int[] imageToArray(Image image, boolean prepareImage) {
            if (image == null) return null;

            if (prepareImage && !(image instanceof BufferedImage)) {
                final MediaTracker mt = new MediaTracker(new Label());
                final int id = 0;
                mt.addImage(image, id);

                try {
                    mt.waitForID(id);
                } catch (InterruptedException e) {
                    return null;
                }

                if (mt.isErrorID(id)) {
                    return null;
                }
            }

            int w = image.getWidth(null);
            int h = image.getHeight(null);

            if (w < 0 || h < 0) {
                return null;
            }

            BufferedImage bimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
            Graphics2D g2 = bimg.createGraphics();
            g2.setComposite(AlphaComposite.Src);
            g2.drawImage(image, 0, 0, null);
            g2.dispose();

            return ((DataBufferInt)bimg.getRaster().getDataBuffer()).getData();
        }

        public byte[] getPlatformImageBytes(final Image image) {
            int[] buffer = imageToArray(image, false);

            if (buffer == null) {
                return null;
            }

            return nativeGetPlatformImageBytes(buffer, image.getWidth(null), image.getHeight(null));
        }

        /**
         * Translates a byte array which contains platform-specific image data in the given format into an Image.
         */
        public Image createImageFromPlatformImageBytes(final byte[] buffer) {
            return createImageUsingNativeSize(nativeCreateNSImageFromBytes(buffer));
        }

        // This is used to create a CImage from a Image
        public CImage createFromImage(final Image image) {
            return createFromImage(image, true);
        }

        public CImage createFromImageImmediately(final Image image) {
            return createFromImage(image, false);
        }

        // This is used to create a CImage from a Image
        private CImage createFromImage(final Image image, final boolean prepareImage) {
            if (image instanceof MultiResolutionImage) {
                List<Image> resolutionVariants
                        = ((MultiResolutionImage) image).getResolutionVariants();
                return createFromImages(resolutionVariants, prepareImage);
            }

            int[] buffer = imageToArray(image, prepareImage);
            if (buffer == null) {
                return null;
            }
            return new CImage(nativeCreateNSImageFromArray(buffer, image.getWidth(null), image.getHeight(null)));
        }

        public CImage createFromImages(final List<Image> images) {
            return createFromImages(images, true);
        }

        private CImage createFromImages(final List<Image> images, final boolean prepareImage) {
            if (images == null || images.isEmpty()) {
                return null;
            }

            int num = images.size();

            int[][] buffers = new int[num][];
            int[] w = new int[num];
            int[] h = new int[num];

            num = 0;

            for (final Image img : images) {
                buffers[num] = imageToArray(img, prepareImage);
                if (buffers[num] == null) {
                    // Unable to process the image
                    continue;
                }
                w[num] = img.getWidth(null);
                h[num] = img.getHeight(null);
                num++;
            }

            if (num == 0) {
                return null;
            }

            return new CImage(nativeCreateNSImageFromArrays(
                    Arrays.copyOf(buffers, num),
                    Arrays.copyOf(w, num),
                    Arrays.copyOf(h, num)));
        }

        static int getSelectorAsInt(final String fromString) {
            final byte[] b = fromString.getBytes();
            final int len = Math.min(b.length, 4);
            int result = 0;
            for (int i = 0; i < len; i++) {
                if (i > 0) result <<= 8;
                result |= (b[i] & 0xff);
            }
            return result;
        }
    }

    CImage(long nsImagePtr) {
        super(nsImagePtr, true);
    }

    /** @return A MultiResolution image created from nsImagePtr, or null. */
    private Image toImage() {
        if (ptr == 0) return null;

        final Dimension2D size = nativeGetNSImageSize(ptr);
        final int w = (int)size.getWidth();
        final int h = (int)size.getHeight();

        Dimension2D[] sizes
                = nativeGetNSImageRepresentationSizes(ptr,
                        size.getWidth(), size.getHeight());

        return sizes == null || sizes.length < 2 ?
                new MultiResolutionCachedImage(w, h, (width, height)
                        -> toImage(w, h, width, height))
                : new MultiResolutionCachedImage(w, h, sizes, (width, height)
                        -> toImage(w, h, width, height));
    }

    private BufferedImage toImage(int srcWidth, int srcHeight, int dstWidth, int dstHeight) {
        final BufferedImage bimg = new BufferedImage(dstWidth, dstHeight, BufferedImage.TYPE_INT_ARGB_PRE);
        final DataBufferInt dbi = (DataBufferInt)bimg.getRaster().getDataBuffer();
        final int[] buffer = SunWritableRaster.stealData(dbi, 0);
        nativeCopyNSImageIntoArray(ptr, buffer, srcWidth, srcHeight, dstWidth, dstHeight);
        SunWritableRaster.markDirty(dbi);
        return bimg;
    }

    /** If nsImagePtr != 0 then scale this NSImage. @return *this* */
    CImage resize(final double w, final double h) {
        if (ptr != 0) nativeSetNSImageSize(ptr, w, h);
        return this;
    }

    void resizeRepresentations(double w, double h) {
        if (ptr != 0) nativeResizeNSImageRepresentations(ptr, w, h);
    }
}
