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

#import "CDataTransferer.h"
#include "sun_lwawt_macosx_CDataTransferer.h"

#import <AppKit/AppKit.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import "jni_util.h"

#include "ThreadUtilities.h"


// ***** NOTE ***** This dictionary corresponds to the static array predefinedClipboardNames
// in CDataTransferer.java.
NSMutableDictionary *sStandardMappings = nil;

NSMutableDictionary *getMappingTable() {
    if (sStandardMappings == nil) {
        sStandardMappings = [[NSMutableDictionary alloc] init];
        [sStandardMappings setObject:NSStringPboardType
                              forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_STRING]];
        [sStandardMappings setObject:NSFilenamesPboardType
                              forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_FILE]];
        [sStandardMappings setObject:NSTIFFPboardType
                              forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_TIFF]];
        [sStandardMappings setObject:NSRTFPboardType
                              forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_RICH_TEXT]];
        [sStandardMappings setObject:NSHTMLPboardType
                              forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_HTML]];
        [sStandardMappings setObject:NSPDFPboardType
                              forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_PDF]];
        [sStandardMappings setObject:NSURLPboardType
                              forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_URL]];
        [sStandardMappings setObject:NSPasteboardTypePNG
                              forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_PNG]];
        [sStandardMappings setObject:(NSString*)kUTTypeJPEG
                              forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_JPEG]];
        [sStandardMappings setObject:NSPICTPboardType
                              forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_XPICT]];
    }
    return sStandardMappings;
}

/*
 * Convert from a standard NSPasteboard data type to an index in our mapping table.
 */
jlong indexForFormat(NSString *format) {
    jlong returnValue = -1;

    NSMutableDictionary *mappingTable = getMappingTable();
    NSArray *matchingKeys = [mappingTable allKeysForObject:format];

    // There should only be one matching key here...
    if ([matchingKeys count] > 0) {
        NSNumber *formatID = (NSNumber *)[matchingKeys objectAtIndex:0];
        returnValue = [formatID longValue];
    }

    // If we don't recognize the format, but it's a Java "custom" format register it
    if (returnValue == -1 && ([format hasPrefix:@"JAVA_DATAFLAVOR:"]) ) {
        returnValue = registerFormatWithPasteboard(format);
    }

    return returnValue;
}

/*
 * Inverse of above -- given a long int index, get the matching data format NSString.
 */
NSString *formatForIndex(jlong inFormatCode) {
    return [getMappingTable() objectForKey:[NSNumber numberWithLong:inFormatCode]];
}

jlong registerFormatWithPasteboard(NSString *format) {
    NSMutableDictionary *mappingTable = getMappingTable();
    NSUInteger nextID = [mappingTable count] + 1;
    [mappingTable setObject:format forKey:[NSNumber numberWithLong:nextID]];
    return nextID;
}


/*
 * Class:     sun_lwawt_macosx_CDataTransferer
 * Method:    registerFormatWithPasteboard
 * Signature: (Ljava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDataTransferer_registerFormatWithPasteboard
(JNIEnv *env, jobject jthis, jstring newformat)
{
    jlong returnValue = -1;
JNF_COCOA_ENTER(env);
    returnValue = registerFormatWithPasteboard(JNFJavaToNSString(env, newformat));
JNF_COCOA_EXIT(env);
    return returnValue;
}

/*
 * Class:     sun_lwawt_macosx_CDataTransferer
 * Method:    formatForIndex
 * Signature: (J)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_lwawt_macosx_CDataTransferer_formatForIndex
  (JNIEnv *env, jobject jthis, jlong index)
{
    jstring returnValue = NULL;
JNF_COCOA_ENTER(env);
    returnValue = JNFNSToJavaString(env, formatForIndex(index));
JNF_COCOA_EXIT(env);
    return returnValue;
}

static jobjectArray CreateJavaFilenameArray(JNIEnv *env, NSArray *filenameArray)
{
    NSUInteger filenameCount = [filenameArray count];
    if (filenameCount == 0) return nil;

    // Get the java.lang.String class object:
    jclass stringClazz = (*env)->FindClass(env, "java/lang/String");
    CHECK_NULL_RETURN(stringClazz, nil);
    jobject jfilenameArray = (*env)->NewObjectArray(env, filenameCount, stringClazz, NULL); // AWT_THREADING Safe (known object)
    if ((*env)->ExceptionOccurred(env)) {
        (*env)->ExceptionDescribe(env);
        (*env)->ExceptionClear(env);
        return nil;
    }
    if (!jfilenameArray) {
        NSLog(@"CDataTransferer_CreateJavaFilenameArray: couldn't create jfilenameArray.");
        return nil;
    }
    (*env)->DeleteLocalRef(env, stringClazz);

    // Iterate through all the filenames:
    NSUInteger i;
    for (i = 0; i < filenameCount; i++) {
        NSMutableString *stringVal = [[NSMutableString alloc] initWithString:[filenameArray objectAtIndex:i]];
        CFStringNormalize((CFMutableStringRef)stringVal, kCFStringNormalizationFormC);
        const char* stringBytes = [stringVal UTF8String];

        // Create a Java String:
        jstring string = (*env)->NewStringUTF(env, stringBytes);
        if ((*env)->ExceptionOccurred(env)) {
            (*env)->ExceptionDescribe(env);
            (*env)->ExceptionClear(env);
            continue;
        }
        if (!string) {
            NSLog(@"CDataTransferer_CreateJavaFilenameArray: couldn't create jstring[%lu] for [%@].", (unsigned long) i, stringVal);
            continue;
        }

        // Set the Java array element with our String:
        (*env)->SetObjectArrayElement(env, jfilenameArray, i, string);
        if ((*env)->ExceptionOccurred(env)) {
            (*env)->ExceptionDescribe(env);
            (*env)->ExceptionClear(env);
            continue;
        }

        // Release local String reference:
        (*env)->DeleteLocalRef(env, string);
    }

    return jfilenameArray;
}

/*
 * Class:     sun_lwawt_macosx_CDataTransferer
 * Method:    draqQueryFile
 * Signature: ([B)[Ljava/lang/String;
 */
JNIEXPORT jobjectArray JNICALL
Java_sun_lwawt_macosx_CDataTransferer_nativeDragQueryFile
(JNIEnv *env, jclass clazz, jbyteArray jbytearray)
{
    // Decodes a byte array into a set of String filenames.
    // bytes here is an XML property list containing all of the filenames in the drag.
    // Parse the XML list into strings and return an array of Java strings matching all of the
    // files in the list.

    jobjectArray jreturnArray = NULL;

JNF_COCOA_ENTER(env);
    // Get byte array elements:
    jboolean isCopy;
    jbyte* jbytes = (*env)->GetByteArrayElements(env, jbytearray, &isCopy);
    if (jbytes == NULL) {
        return NULL;
    }

    // Wrap jbytes in an NSData object:
    jsize jbytesLength = (*env)->GetArrayLength(env, jbytearray);
    NSData *xmlData = [NSData dataWithBytesNoCopy:jbytes length:jbytesLength freeWhenDone:NO];

    // Create a property list from the Java data:
    NSString *errString = nil;
    NSPropertyListFormat plistFormat = 0;
    id plist = [NSPropertyListSerialization propertyListFromData:xmlData mutabilityOption:NSPropertyListImmutable
        format:&plistFormat errorDescription:&errString];

    // The property list must be an array of strings:
    if (plist == nil || [plist isKindOfClass:[NSArray class]] == FALSE) {
        NSLog(@"CDataTransferer_dragQueryFile: plist not a valid NSArray (error %@):\n%@", errString, plist);
        (*env)->ReleaseByteArrayElements(env, jbytearray, jbytes, JNI_ABORT);
        return NULL;
    }

    // Transfer all string items from the plistArray to filenameArray. This wouldn't be necessary
    // if we could trust the array to contain all valid elements but this way we'll be sure.
    NSArray *plistArray = (NSArray *)plist;
    NSUInteger plistItemCount = [plistArray count];
    NSMutableArray *filenameArray = [[NSMutableArray alloc] initWithCapacity:plistItemCount];

    NSUInteger i;
    for (i = 0; i < plistItemCount; i++) {
        // Filenames must be strings:
        id idVal = [plistArray objectAtIndex:i];
        if ([idVal isKindOfClass:[NSString class]] == FALSE) {
            NSLog(@"CDataTransferer_dragQueryFile: plist[%lu] not an NSString:\n%@", (unsigned long) i, idVal);
            continue;
        }

        [filenameArray addObject:idVal];
    }

    // Convert our array of filenames into a Java array of String filenames:
    jreturnArray = CreateJavaFilenameArray(env, filenameArray);

    [filenameArray release];

    // We're done with the jbytes (backing the plist/plistArray):
    (*env)->ReleaseByteArrayElements(env, jbytearray, jbytes, JNI_ABORT);
JNF_COCOA_EXIT(env);
    return jreturnArray;
}
