/*
 * 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 "CClipboard.h"
#import "CDataTransferer.h"
#import "ThreadUtilities.h"
#import "jni_util.h" 
#import <Cocoa/Cocoa.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>

static CClipboard *sClipboard = nil;

//
// CClipboardUpdate is used for mulitple calls to setData that happen before
// the model and AppKit can get back in sync.
//

@interface CClipboardUpdate : NSObject {
    NSData *fData;
    NSString *fFormat;
}

- (id)initWithData:(NSData *)inData withFormat:(NSString *)inFormat;
- (NSData *)data;
- (NSString *)format;

@end

@implementation CClipboardUpdate

- (id)initWithData:(NSData *)inData withFormat:(NSString *)inFormat
{
    self = [super init];

    if (self != nil) {
        fData = [inData retain];
        fFormat = [inFormat retain];
    }

    return self;
}

- (void)dealloc
{
    [fData release];
    fData = nil;

    [fFormat release];
    fFormat = nil;

    [super dealloc];
}
//- (void)finalize { [super finalize]; }

- (NSData *)data {
    return fData;
}

- (NSString *)format {
    return fFormat;
}
@end

@implementation CClipboard

// Clipboard creation is synchronized at the Java level.
+ (CClipboard *) sharedClipboard
{
    if (sClipboard == nil) {
        sClipboard = [[CClipboard alloc] init];
        [[NSNotificationCenter defaultCenter] addObserver:sClipboard selector: @selector(checkPasteboard:)
                                                     name: NSApplicationDidBecomeActiveNotification
                                                   object: nil];
    }

    return sClipboard;
}

- (id) init
{
    self = [super init];

    if (self != nil) {
        fChangeCount = [[NSPasteboard generalPasteboard] changeCount];
    }

    return self;
}

- (void) javaDeclareTypes:(NSArray *)inTypes withOwner:(jobject)inClipboard jniEnv:(JNIEnv *)inEnv {

    @synchronized(self) {
        if (inClipboard != NULL) {
            if (fClipboardOwner != NULL) {
                JNFDeleteGlobalRef(inEnv, fClipboardOwner);
            }
            fClipboardOwner = JNFNewGlobalRef(inEnv, inClipboard);
        }
    }
    [ThreadUtilities performOnMainThread:@selector(_nativeDeclareTypes:) on:self withObject:inTypes waitUntilDone:YES];
}

- (void) _nativeDeclareTypes:(NSArray *)inTypes {
    AWT_ASSERT_APPKIT_THREAD;

    fChangeCount = [[NSPasteboard generalPasteboard] declareTypes:inTypes owner:self];
}


- (NSArray *) javaGetTypes {

    NSMutableArray *args = [NSMutableArray arrayWithCapacity:1];
    [ThreadUtilities performOnMainThread:@selector(_nativeGetTypes:) on:self withObject:args waitUntilDone:YES];
    return [args lastObject];
}

- (void) _nativeGetTypes:(NSMutableArray *)args {
    AWT_ASSERT_APPKIT_THREAD;

    [args addObject:[[NSPasteboard generalPasteboard] types]];
}

- (void) javaSetData:(NSData *)inData forType:(NSString *) inFormat {

    CClipboardUpdate *newUpdate = [[CClipboardUpdate alloc] initWithData:inData withFormat:inFormat];
    [ThreadUtilities performOnMainThread:@selector(_nativeSetData:) on:self withObject:newUpdate waitUntilDone:YES];
    [newUpdate release];
}

- (void) _nativeSetData:(CClipboardUpdate *)newUpdate {
    AWT_ASSERT_APPKIT_THREAD;

    [[NSPasteboard generalPasteboard] setData:[newUpdate data] forType:[newUpdate format]];
}

- (NSData *) javaGetDataForType:(NSString *) inFormat {

    NSMutableArray *args = [NSMutableArray arrayWithObject:inFormat];
    [ThreadUtilities performOnMainThread:@selector(_nativeGetDataForType:) on:self withObject:args waitUntilDone:YES];
    return [args lastObject];
}

- (void) _nativeGetDataForType:(NSMutableArray *) args {
    AWT_ASSERT_APPKIT_THREAD;

    NSData *returnValue = [[NSPasteboard generalPasteboard] dataForType:[args objectAtIndex:0]];

    if (returnValue) [args replaceObjectAtIndex:0 withObject:returnValue];
    else [args removeLastObject];
}



- (void) checkPasteboard:(id)application {
    AWT_ASSERT_APPKIT_THREAD;
    
    // This is called via NSApplicationDidBecomeActiveNotification.
    
    // If the change count on the general pasteboard is different than when we set it
    // someone else put data on the clipboard.  That means the current owner lost ownership.
    NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount];
    
    if (fChangeCount != newChangeCount) {
        fChangeCount = newChangeCount;    

        // Notify that the content might be changed
        static JNF_CLASS_CACHE(jc_CClipboard, "sun/lwawt/macosx/CClipboard");
        static JNF_STATIC_MEMBER_CACHE(jm_contentChanged, jc_CClipboard, "notifyChanged", "()V");
        JNIEnv *env = [ThreadUtilities getJNIEnv];
        JNFCallStaticVoidMethod(env, jm_contentChanged);

        // If we have a Java pasteboard owner, tell it that it doesn't own the pasteboard anymore.
        static JNF_MEMBER_CACHE(jm_lostOwnership, jc_CClipboard, "notifyLostOwnership", "()V");
        @synchronized(self) {
            if (fClipboardOwner) {
                JNIEnv *env = [ThreadUtilities getJNIEnv];
                JNFCallVoidMethod(env, fClipboardOwner, jm_lostOwnership); // AWT_THREADING Safe (event)
                JNFDeleteGlobalRef(env, fClipboardOwner);
                fClipboardOwner = NULL;
            }
        }
    }
}

- (BOOL) checkPasteboardWithoutNotification:(id)application {
    AWT_ASSERT_APPKIT_THREAD;
    
    NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount];
    
    if (fChangeCount != newChangeCount) {
        fChangeCount = newChangeCount;    
        return YES;
    } else {
        return NO;
    }
}

@end

/*
 * Class:     sun_lwawt_macosx_CClipboard
 * Method:    declareTypes
 * Signature: ([JLsun/awt/datatransfer/SunClipboard;)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_declareTypes
(JNIEnv *env, jobject inObject, jlongArray inTypes, jobject inJavaClip)
{
JNF_COCOA_ENTER(env);

    jint i;
    jint nElements = (*env)->GetArrayLength(env, inTypes);
    NSMutableArray *formatArray = [NSMutableArray arrayWithCapacity:nElements];
    jlong *elements = (*env)->GetPrimitiveArrayCritical(env, inTypes, NULL);

    for (i = 0; i < nElements; i++) {
        NSString *pbFormat = formatForIndex(elements[i]);
        if (pbFormat)
            [formatArray addObject:pbFormat];
    }

    (*env)->ReleasePrimitiveArrayCritical(env, inTypes, elements, JNI_ABORT);
    [[CClipboard sharedClipboard] javaDeclareTypes:formatArray withOwner:inJavaClip jniEnv:env];
JNF_COCOA_EXIT(env);
}

/*
 * Class:     sun_lwawt_macosx_CClipboard
 * Method:    setData
 * Signature: ([BJ)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_setData
(JNIEnv *env, jobject inObject, jbyteArray inBytes, jlong inFormat)
{
    if (inBytes == NULL) {
        return;
    }

JNF_COCOA_ENTER(env);
    jint nBytes = (*env)->GetArrayLength(env, inBytes);
    jbyte *rawBytes = (*env)->GetPrimitiveArrayCritical(env, inBytes, NULL);
    CHECK_NULL(rawBytes);
    NSData *bytesAsData = [NSData dataWithBytes:rawBytes length:nBytes];
    (*env)->ReleasePrimitiveArrayCritical(env, inBytes, rawBytes, JNI_ABORT);
    NSString *format = formatForIndex(inFormat);
    [[CClipboard sharedClipboard] javaSetData:bytesAsData forType:format];
JNF_COCOA_EXIT(env);
}

/*
 * Class:     sun_lwawt_macosx_CClipboard
 * Method:    getClipboardFormats
 * Signature: (J)[J
     */
JNIEXPORT jlongArray JNICALL Java_sun_lwawt_macosx_CClipboard_getClipboardFormats
(JNIEnv *env, jobject inObject)
{
    jlongArray returnValue = NULL;
JNF_COCOA_ENTER(env);

    NSArray *dataTypes = [[CClipboard sharedClipboard] javaGetTypes];
    NSUInteger nFormats = [dataTypes count];
    NSUInteger knownFormats = 0;
    NSUInteger i;

    // There can be any number of formats on the general pasteboard.  Find out which ones
    // we know about (i.e., live in the flavormap.properties).
    for (i = 0; i < nFormats; i++) {
        NSString *format = (NSString *)[dataTypes objectAtIndex:i];
        if (indexForFormat(format) != -1)
            knownFormats++;
    }

    returnValue = (*env)->NewLongArray(env, knownFormats);
    if (returnValue == NULL) {
        return NULL;
    }

    if (knownFormats == 0) {
        return returnValue;
    }

    // Now go back and map the formats we found back to Java indexes.
    jboolean isCopy;
    jlong *lFormats = (*env)->GetLongArrayElements(env, returnValue, &isCopy);
    jlong *saveFormats = lFormats;

    for (i = 0; i < nFormats; i++) {
        NSString *format = (NSString *)[dataTypes objectAtIndex:i];
        jlong index = indexForFormat(format);

        if (index != -1) {
            *lFormats = index;
            lFormats++;
        }
    }

    (*env)->ReleaseLongArrayElements(env, returnValue, saveFormats, JNI_COMMIT);
JNF_COCOA_EXIT(env);
    return returnValue;
}

/*
 * Class:     sun_lwawt_macosx_CClipboard
 * Method:    getClipboardData
 * Signature: (JJ)[B
     */
JNIEXPORT jbyteArray JNICALL Java_sun_lwawt_macosx_CClipboard_getClipboardData
(JNIEnv *env, jobject inObject, jlong format)
{
    jbyteArray returnValue = NULL;

    // Note that this routine makes no attempt to interpret the data, since we're returning
    // a byte array back to Java.  CDataTransferer will do that if necessary.
JNF_COCOA_ENTER(env);

    NSString *formatAsString = formatForIndex(format);
    NSData *clipData = [[CClipboard sharedClipboard] javaGetDataForType:formatAsString];

    if (clipData == NULL) {
        [JNFException raise:env as:"java/io/IOException" reason:"Font transform has NaN position"];
        return NULL;
    }

    NSUInteger dataSize = [clipData length];
    returnValue = (*env)->NewByteArray(env, dataSize);
    if (returnValue == NULL) {
        return NULL;
    }

    if (dataSize != 0) {
        const void *dataBuffer = [clipData bytes];
        (*env)->SetByteArrayRegion(env, returnValue, 0, dataSize, (jbyte *)dataBuffer);
    }

JNF_COCOA_EXIT(env);
    return returnValue;
}

/*
 * Class:     sun_lwawt_macosx_CClipboard
 * Method:    checkPasteboard
 * Signature: ()V
 */
JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CClipboard_checkPasteboardWithoutNotification
(JNIEnv *env, jobject inObject)
{
    __block BOOL ret = NO;
    JNF_COCOA_ENTER(env);
    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
        ret = [[CClipboard sharedClipboard] checkPasteboardWithoutNotification:nil];
    }];
     
    JNF_COCOA_EXIT(env);
    return ret;
}


