/*
 * Copyright (c) 2011, 2014, 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.
 */
#import "jni_util.h"

#import <Cocoa/Cocoa.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>

#import "GeomUtilities.h"
#import "ThreadUtilities.h"

#import "sun_lwawt_macosx_CImage.h"


static void CImage_CopyArrayIntoNSImageRep
(jint *srcPixels, jint *dstPixels, int width, int height)
{
    int x, y;
    // TODO: test this on big endian systems (not sure if its correct)...
    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {
            jint pix = srcPixels[x];
            jint a = (pix >> 24) & 0xff;
            jint r = (pix >> 16) & 0xff;
            jint g = (pix >>  8) & 0xff;
            jint b = (pix      ) & 0xff;
            dstPixels[x] = (b << 24) | (g << 16) | (r << 8) | a;
        }
        srcPixels += width; // TODO: use explicit scanStride
        dstPixels += width;
    }
}

static void CImage_CopyNSImageIntoArray
(NSImage *srcImage, jint *dstPixels, NSRect fromRect, NSRect toRect)
{
    int width = toRect.size.width;
    int height = toRect.size.height;
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    CGContextRef cgRef = CGBitmapContextCreate(dstPixels, width, height,
                                8, width * 4, colorspace,
                                kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);
    CGColorSpaceRelease(colorspace);
    NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:cgRef flipped:NO];
    CGContextRelease(cgRef);
    NSGraphicsContext *oldContext = [[NSGraphicsContext currentContext] retain];
    [NSGraphicsContext setCurrentContext:context];
    [srcImage drawInRect:toRect
                fromRect:fromRect
               operation:NSCompositeSourceOver
                fraction:1.0];
    [NSGraphicsContext setCurrentContext:oldContext];
    [oldContext release];
}

static NSBitmapImageRep* CImage_CreateImageRep(JNIEnv *env, jintArray buffer, jint width, jint height)
{
    NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
                                                                         pixelsWide:width
                                                                         pixelsHigh:height
                                                                      bitsPerSample:8
                                                                    samplesPerPixel:4
                                                                           hasAlpha:YES
                                                                           isPlanar:NO
                                                                     colorSpaceName:NSDeviceRGBColorSpace
                                                                       bitmapFormat:NSAlphaFirstBitmapFormat
                                                                        bytesPerRow:width*4 // TODO: use explicit scanStride
                                                                       bitsPerPixel:32];

    jint *imgData = (jint *)[imageRep bitmapData];
    if (imgData == NULL) return 0L;

    jint *src = (*env)->GetPrimitiveArrayCritical(env, buffer, NULL);
    if (src == NULL) return 0L;

    CImage_CopyArrayIntoNSImageRep(src, imgData, width, height);

    (*env)->ReleasePrimitiveArrayCritical(env, buffer, src, JNI_ABORT);

    return imageRep;
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeCreateNSImageFromArray
 * Signature: ([III)J
 */
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromArray
(JNIEnv *env, jclass klass, jintArray buffer, jint width, jint height)
{
    jlong result = 0L;

JNF_COCOA_ENTER(env);
    
    NSBitmapImageRep* imageRep = CImage_CreateImageRep(env, buffer, width, height);
    if (imageRep) {
        NSImage *nsImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
        [nsImage addRepresentation:imageRep];
        [imageRep release];

        if (nsImage != nil) {
            CFRetain(nsImage); // GC
        }

        result = ptr_to_jlong(nsImage);
    }

JNF_COCOA_EXIT(env);

    return result;
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeCreateNSImageFromArrays
 * Signature: ([[I[I[I)J
 */
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromArrays
(JNIEnv *env, jclass klass, jobjectArray buffers, jintArray widths, jintArray heights)
{
    jlong result = 0L;

JNF_COCOA_ENTER(env);

    jsize num = (*env)->GetArrayLength(env, buffers);
    NSMutableArray * reps = [NSMutableArray arrayWithCapacity: num];

    jint * ws = (*env)->GetIntArrayElements(env, widths, NULL);
    if (ws != NULL) {
        jint * hs = (*env)->GetIntArrayElements(env, heights, NULL);
        if (hs != NULL) {
            jsize i;
            for (i = 0; i < num; i++) {
                jintArray buffer = (*env)->GetObjectArrayElement(env, buffers, i);

                NSBitmapImageRep* imageRep = CImage_CreateImageRep(env, buffer, ws[i], hs[i]);
                if (imageRep) {
                    [reps addObject: imageRep];
                }
            }

            (*env)->ReleaseIntArrayElements(env, heights, hs, JNI_ABORT);
        }
        (*env)->ReleaseIntArrayElements(env, widths, ws, JNI_ABORT);
    }
    if ([reps count]) {
        NSImage *nsImage = [[NSImage alloc] initWithSize:NSMakeSize(0, 0)];
        [nsImage addRepresentations: reps];

        if (nsImage != nil) {
            CFRetain(nsImage); // GC
        }

        result = ptr_to_jlong(nsImage);
    }

JNF_COCOA_EXIT(env);

    return result;
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeCreateNSImageFromIconSelector
 * Signature: (I)J
 */
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromIconSelector
(JNIEnv *env, jclass klass, jint selector)
{
    NSImage *image = nil;

JNF_COCOA_ENTER(env);

    IconRef iconRef;
    if (noErr == GetIconRef(kOnSystemDisk, kSystemIconsCreator, selector, &iconRef)) {
        image = [[NSImage alloc] initWithIconRef:iconRef];
        if (image) CFRetain(image); // GC
        ReleaseIconRef(iconRef);
    }

JNF_COCOA_EXIT(env);

    return ptr_to_jlong(image);
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeCreateNSImageFromFileContents
 * Signature: (Ljava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromFileContents
(JNIEnv *env, jclass klass, jstring file)
{
    NSImage *image = nil;

JNF_COCOA_ENTER(env);

    NSString *path = JNFNormalizedNSStringForPath(env, file);
    image = [[NSImage alloc] initByReferencingFile:path];
    if (image) CFRetain(image); // GC

JNF_COCOA_EXIT(env);

    return ptr_to_jlong(image);
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeCreateNSImageOfFileFromLaunchServices
 * Signature: (Ljava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageOfFileFromLaunchServices
(JNIEnv *env, jclass klass, jstring file)
{
    __block NSImage *image = nil;

JNF_COCOA_ENTER(env);

    NSString *path = JNFNormalizedNSStringForPath(env, file);
    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
        image = [[NSWorkspace sharedWorkspace] iconForFile:path];
        [image setScalesWhenResized:TRUE];
        if (image) CFRetain(image); // GC
    }];

JNF_COCOA_EXIT(env);

    return ptr_to_jlong(image);
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeCreateNSImageFromImageName
 * Signature: (Ljava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromImageName
(JNIEnv *env, jclass klass, jstring name)
{
    NSImage *image = nil;

JNF_COCOA_ENTER(env);

    image = [NSImage imageNamed:JNFJavaToNSString(env, name)];
    if (image) CFRetain(image); // GC

JNF_COCOA_EXIT(env);

    return ptr_to_jlong(image);
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeCopyNSImageIntoArray
 * Signature: (J[IIIII)V
 */
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CImage_nativeCopyNSImageIntoArray
(JNIEnv *env, jclass klass, jlong nsImgPtr, jintArray buffer, jint sw, jint sh,
                 jint dw, jint dh)
{
JNF_COCOA_ENTER(env);

    NSImage *img = (NSImage *)jlong_to_ptr(nsImgPtr);
    jint *dst = (*env)->GetPrimitiveArrayCritical(env, buffer, NULL);
    if (dst) {
        NSRect fromRect = NSMakeRect(0, 0, sw, sh);
        NSRect toRect = NSMakeRect(0, 0, dw, dh);
        CImage_CopyNSImageIntoArray(img, dst, fromRect, toRect);
        (*env)->ReleasePrimitiveArrayCritical(env, buffer, dst, JNI_ABORT);
    }

JNF_COCOA_EXIT(env);
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeGetNSImageSize
 * Signature: (J)Ljava/awt/geom/Dimension2D;
 */
JNIEXPORT jobject JNICALL Java_sun_lwawt_macosx_CImage_nativeGetNSImageSize
(JNIEnv *env, jclass klass, jlong nsImgPtr)
{
    jobject size = NULL;

JNF_COCOA_ENTER(env);

    size = NSToJavaSize(env, [(NSImage *)jlong_to_ptr(nsImgPtr) size]);

JNF_COCOA_EXIT(env);

    return size;
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeSetNSImageSize
 * Signature: (JDD)V
 */
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CImage_nativeSetNSImageSize
(JNIEnv *env, jclass clazz, jlong image, jdouble w, jdouble h)
{
    if (!image) return;
    NSImage *i = (NSImage *)jlong_to_ptr(image);

JNF_COCOA_ENTER(env);

    [i setScalesWhenResized:TRUE];
    [i setSize:NSMakeSize(w, h)];

JNF_COCOA_EXIT(env);
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeResizeNSImageRepresentations
 * Signature: (JDD)V
 */
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CImage_nativeResizeNSImageRepresentations
(JNIEnv *env, jclass clazz, jlong image, jdouble w, jdouble h)
{
    if (!image) return;
    NSImage *i = (NSImage *)jlong_to_ptr(image);
    
JNF_COCOA_ENTER(env);
    
    NSImageRep *imageRep = nil;
    NSArray *imageRepresentations = [i representations];
    NSEnumerator *imageEnumerator = [imageRepresentations objectEnumerator];
    while ((imageRep = [imageEnumerator nextObject]) != nil) {
        [imageRep setSize:NSMakeSize(w, h)];
    }
    
JNF_COCOA_EXIT(env);
}

NSComparisonResult getOrder(BOOL order){
    return (NSComparisonResult) (order ? NSOrderedAscending : NSOrderedDescending);
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeGetNSImageRepresentationsCount
 * Signature: (JDD)[Ljava/awt/geom/Dimension2D;
 */
JNIEXPORT jobjectArray JNICALL
                  Java_sun_lwawt_macosx_CImage_nativeGetNSImageRepresentationSizes
(JNIEnv *env, jclass clazz, jlong image, jdouble w, jdouble h)
{
    if (!image) return NULL;
    jobjectArray jreturnArray = NULL;
    NSImage *img = (NSImage *)jlong_to_ptr(image);

JNF_COCOA_ENTER(env);
        
    NSArray *imageRepresentations = [img representations];
    if([imageRepresentations count] == 0){
        return NULL;
    }
    
    NSArray *sortedImageRepresentations = [imageRepresentations
                    sortedArrayUsingComparator: ^(id obj1, id obj2) {
        
        NSImageRep *imageRep1 = (NSImageRep *) obj1;
        NSImageRep *imageRep2 = (NSImageRep *) obj2;
        NSSize size1 = [imageRep1 size];
        NSSize size2 = [imageRep2 size];
        
        if (NSEqualSizes(size1, size2)) {
            return getOrder([imageRep1 pixelsWide] <= [imageRep2 pixelsWide] &&
                            [imageRep1 pixelsHigh] <= [imageRep2 pixelsHigh]);
        }

        return getOrder(size1.width <= size2.width && size1.height <= size2.height);
    }];

    NSMutableArray *sortedPixelSizes = [[[NSMutableArray alloc] init] autorelease];
    NSSize lastSize = [[sortedImageRepresentations lastObject] size];
    
    NSUInteger i = [sortedImageRepresentations indexOfObjectPassingTest:
               ^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        NSSize imageRepSize = [obj size];
        return (w <= imageRepSize.width && h <= imageRepSize.height)
                   || NSEqualSizes(imageRepSize, lastSize);
    }];

    NSUInteger count = [sortedImageRepresentations count];
    i = (i == NSNotFound) ? count - 1 : i;
    NSSize bestFitSize = [[sortedImageRepresentations objectAtIndex: i] size];

    for(; i < count; i++){
        NSImageRep *imageRep = [sortedImageRepresentations objectAtIndex: i];

        if (!NSEqualSizes([imageRep size], bestFitSize)) {
            break;
        }

        NSSize pixelSize = NSMakeSize(
                                [imageRep pixelsWide], [imageRep pixelsHigh]);
        [sortedPixelSizes addObject: [NSValue valueWithSize: pixelSize]];
    }

    count = [sortedPixelSizes count];
    static JNF_CLASS_CACHE(jc_Dimension, "java/awt/Dimension");
    jreturnArray = JNFNewObjectArray(env, &jc_Dimension, count);
    CHECK_NULL_RETURN(jreturnArray, NULL);

    for(i = 0; i < count; i++){
        NSSize pixelSize = [[sortedPixelSizes objectAtIndex: i] sizeValue];

        (*env)->SetObjectArrayElement(env, jreturnArray, i,
                                      NSToJavaSize(env, pixelSize));
        JNU_CHECK_EXCEPTION_RETURN(env, NULL);
    }

JNF_COCOA_EXIT(env);

    return jreturnArray;
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeGetPlatformImageBytes
 * Signature: ([III)[B
 */
JNIEXPORT jbyteArray JNICALL Java_sun_lwawt_macosx_CImage_nativeGetPlatformImageBytes
(JNIEnv *env, jclass klass, jintArray buffer, jint width, jint height)
{
    jbyteArray result = 0L;
    
    JNF_COCOA_ENTER(env);
    
    NSBitmapImageRep* imageRep = [CImage_CreateImageRep(env, buffer, width, height) autorelease];
    if (imageRep) {
        NSData *tiffImage = [imageRep TIFFRepresentation];
        jsize tiffSize = (jsize)[tiffImage length];
        result = (*env)->NewByteArray(env, tiffSize);
        CHECK_NULL_RETURN(result, nil);
        jbyte *tiffData = (jbyte *)(*env)->GetPrimitiveArrayCritical(env, result, 0);
        CHECK_NULL_RETURN(tiffData, nil);
        [tiffImage getBytes:tiffData];
        (*env)->ReleasePrimitiveArrayCritical(env, result, tiffData, 0);
    }
    
    JNF_COCOA_EXIT(env);
    
    return result;
}

/*
 * Class:     sun_lwawt_macosx_CImage
 * Method:    nativeCreateNSImageFromBytes
 * Signature: ([B)J
 */
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CImage_nativeCreateNSImageFromBytes
(JNIEnv *env, jclass klass, jbyteArray sourceData)
{
    jlong result = 0L;
    CHECK_NULL_RETURN(sourceData, 0L);
    
    JNF_COCOA_ENTER(env);
    
    jsize sourceSize = (*env)->GetArrayLength(env, sourceData);
    if (sourceSize == 0) return 0L;
    
    jbyte *sourceBytes = (*env)->GetPrimitiveArrayCritical(env, sourceData, NULL);
    CHECK_NULL_RETURN(sourceBytes, 0L);
    NSData *rawData = [NSData dataWithBytes:sourceBytes length:sourceSize];    
    NSImage *newImage = [[NSImage alloc] initWithData:rawData];
    
    (*env)->ReleasePrimitiveArrayCritical(env, sourceData, sourceBytes, JNI_ABORT);
    CHECK_NULL_RETURN(newImage, 0L);
    
    result = ptr_to_jlong(newImage);
    JNF_COCOA_EXIT(env);
    
    return result;
}

