/*
 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
 */
#import "common.h"

#import "GlassMacros.h"
#import "GlassDialogs.h"
#import "GlassApplication.h"

//#define VERBOSE
#ifndef VERBOSE
    #define LOG(MSG, ...)
#else
    #define LOG(MSG, ...) GLASS_LOG(MSG, ## __VA_ARGS__);
#endif

static inline NSString* getNSString(JNIEnv* env, jstring jstring)
{
    NSString *string = nil;
    if (jstring != NULL)
    {
        const jchar* jstrChars = (*env)->GetStringChars(env, jstring, NULL);
        string = [[[NSString alloc] initWithCharacters: jstrChars length: (*env)->GetStringLength(env, jstring)] autorelease];
        (*env)->ReleaseStringChars(env, jstring, jstrChars);
    }
    return string;
}

// NSSavePanel is the super class for NSLoadPanel
static inline void applyExtensions(JNIEnv* env, jobjectArray jExtensions, NSSavePanel *panel)
{
    if (jExtensions != NULL)
    {
        int itemCount = (*env)->GetArrayLength(env, jExtensions);
        if (itemCount > 0)
        {
            NSMutableArray *types = [NSMutableArray arrayWithCapacity:itemCount];
            for (int i=0; i<itemCount; i++)
            {
                jstring type = (*env)->GetObjectArrayElement(env, jExtensions, i);
                NSString *string = getNSString(env, type);
                [types addObject:[string pathExtension]];
            }
            [panel setAllowedFileTypes:types];
        }
    }
}

#pragma mark --- Dispatcher

@interface DialogDispatcher : NSObject
{
    NSSavePanel *panel;
    NSWindow    *owner;
    NSInteger   button;
}

- initWithPanel:(NSSavePanel*)panel owner:(NSWindow*)owner;
@end

@implementation DialogDispatcher

- (id)initWithPanel:(NSSavePanel*)p owner:(NSWindow*)o
{
    self = [super init];

    self->panel = p;
    self->owner = o;

    return self;
}

- (void)exitModalWithEnv:(JNIEnv*)env result:(NSInteger)result
{
    self->button = result;
    [GlassApplication leaveNestedEventLoopWithEnv:env retValue:NULL];
}

- (void)runModal
{
    GET_MAIN_JENV;
    DialogDispatcher *dd = self;

    if (owner) {
        [panel beginSheetModalForWindow: owner completionHandler:^(NSInteger result)
        {
            [dd exitModalWithEnv:env result:result];
        }
        ];
    } else {
        [panel beginWithCompletionHandler:^(NSInteger result)
        {
            [dd exitModalWithEnv:env result:result];
        }
        ];
    }

    [GlassApplication enterNestedEventLoopWithEnv:env];
}

- (NSInteger)getButton
{
    return self->button;
}

@end

#pragma mark --- JNI

/*
 * Class:     com_sun_glass_ui_mac_MacCommonDialogs
 * Method:    _initIDs
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacCommonDialogs__1initIDs
(JNIEnv *env, jclass cls)
{
    
}

/*
 * Class:     com_sun_glass_ui_mac_MacCommonDialogs
 * Method:    _showFileOpenChooser
 * Signature: (JLjava/lang/String;Ljava/lang/String;Z[Lcom/sun/glass/ui/CommonDialogs$ExtensionFilter;)[Ljava/lang/String;
 */
JNIEXPORT jobjectArray JNICALL Java_com_sun_glass_ui_mac_MacCommonDialogs__1showFileOpenChooser
(JNIEnv *env, jclass cls, jlong owner, jstring jFolder, jstring jTitle, jboolean jMultipleMode, jobjectArray jExtensionFilters)
{
    LOG("Java_com_sun_glass_ui_mac_MacCommonDialogs__1showFileOpenChooser");
    
    jobjectArray chosen = NULL;
    
    GLASS_ASSERT_MAIN_JAVA_THREAD(env);
    GLASS_POOL_ENTER;
    {
        NSOpenPanel *panel = [NSOpenPanel openPanel];
        [panel setAllowsMultipleSelection:jMultipleMode];
        [panel setTitle:getNSString(env, jTitle)];
        //[panel setPrompt:getNSString(env, jTitle)];
        //[panel setMessage:getNSString(env, jTitle)];
        NSString *folder = getNSString(env, jFolder);
        if (folder != nil)
        {
            [panel setDirectoryURL:[NSURL URLWithString:folder]];
        }
        
        [panel setResolvesAliases:YES];
        [panel setCanChooseFiles:YES];
        [panel setCanChooseDirectories:NO];
        [panel setShowsHiddenFiles:YES];
        [panel setExtensionHidden:NO];
        [panel setCanSelectHiddenExtension:YES];
        [panel setAllowsOtherFileTypes:NO];
        [panel setCanCreateDirectories:NO];
        applyExtensions(env, jExtensionFilters, panel);
        
        DialogDispatcher *dispatcher = [[DialogDispatcher alloc] initWithPanel:panel owner:(NSWindow*)jlong_to_ptr(owner)];
        {
            [dispatcher performSelectorOnMainThread:@selector(runModal) withObject:nil waitUntilDone:YES];
            NSArray *urls = [panel URLs];
            if (([dispatcher getButton] == NSFileHandlingPanelOKButton) && ([urls count] > 0))
            {
                chosen = (*env)->NewObjectArray(env, [urls count], (*env)->FindClass(env, "java/lang/String"), NULL);
                for (int i=0; i<[urls count]; i++)
                {
                    NSURL *url = [urls objectAtIndex:i];
                    (*env)->SetObjectArrayElement(env, chosen, i, (*env)->NewStringUTF(env, [[url path] UTF8String]));
                }
            }
            else
            {
                chosen = (*env)->NewObjectArray(env, 0, (*env)->FindClass(env, "java/lang/String"), NULL);
            }
        }
        [dispatcher release];
    }
    GLASS_POOL_EXIT;
    GLASS_CHECK_EXCEPTION(env);
    
    return chosen;
}

/*
 * Class:     com_sun_glass_ui_mac_MacCommonDialogs
 * Method:    _showFileSaveChooser
 * Signature: (JLjava/lang/String;Ljava/lang/String;[Lcom/sun/glass/ui/CommonDialogs$ExtensionFilter;)[Ljava/lang/String;
 */
JNIEXPORT jobjectArray JNICALL Java_com_sun_glass_ui_mac_MacCommonDialogs__1showFileSaveChooser
(JNIEnv *env, jclass cls, jlong owner, jstring jFolder, jstring jTitle, jobjectArray jExtensionFilters)
{
    LOG("Java_com_sun_glass_ui_mac_MacCommonDialogs__1showFileSaveChooser");
    
    jobjectArray chosen = NULL;
    
    GLASS_ASSERT_MAIN_JAVA_THREAD(env);
    GLASS_POOL_ENTER;
    {
        NSSavePanel *panel = [NSSavePanel savePanel];
        [panel setTitle:getNSString(env, jTitle)];
        //[panel setPrompt:getNSString(env, jTitle)];
        //[panel setMessage:getNSString(env, jTitle)];
        NSString *folder = getNSString(env, jFolder);
        if (folder != nil)
        {
            [panel setDirectoryURL:[NSURL URLWithString:folder]];
        }
        
        [panel setShowsHiddenFiles:YES];
        [panel setExtensionHidden:NO];
        [panel setCanSelectHiddenExtension:YES];
        [panel setAllowsOtherFileTypes:NO];
        [panel setCanCreateDirectories:NO];
        applyExtensions(env, jExtensionFilters, panel);
        
        DialogDispatcher *dispatcher = [[DialogDispatcher alloc] initWithPanel:panel owner:(NSWindow*)jlong_to_ptr(owner)];
        {
            [dispatcher performSelectorOnMainThread:@selector(runModal) withObject:nil waitUntilDone:YES];
            NSURL *url = [panel URL];
            if (([dispatcher getButton] == NSFileHandlingPanelOKButton) && (url != nil))
            {
                chosen = (*env)->NewObjectArray(env, 1, (*env)->FindClass(env, "java/lang/String"), NULL);
                (*env)->SetObjectArrayElement(env, chosen, 0, (*env)->NewStringUTF(env, [[url path] UTF8String]));
            }
            else
            {
                chosen = (*env)->NewObjectArray(env, 0, (*env)->FindClass(env, "java/lang/String"), NULL);
            }
        }
        [dispatcher release];
    }
    GLASS_POOL_EXIT;
    GLASS_CHECK_EXCEPTION(env);
    
    return chosen;
}

/*
 * Class:     com_sun_glass_ui_mac_MacCommonDialogs
 * Method:    _showFolderChooser
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_sun_glass_ui_mac_MacCommonDialogs__1showFolderChooser
(JNIEnv *env, jclass cls, jstring jFolder, jstring jTitle)
{
    LOG("Java_com_sun_glass_ui_mac_MacCommonDialogs__1showFolderChooser");
    
    jstring chosen = NULL;
    
    GLASS_ASSERT_MAIN_JAVA_THREAD(env);
    GLASS_POOL_ENTER;
    {
        NSOpenPanel *panel = [NSOpenPanel openPanel];
        [panel setTitle:getNSString(env, jTitle)];
        //[panel setPrompt:getNSString(env, jTitle)];
        //[panel setMessage:getNSString(env, jTitle)];
        NSString *folder = getNSString(env, jFolder);
        if (folder != nil)
        {
            [panel setDirectoryURL:[NSURL URLWithString:folder]];
        }
        
        [panel setAllowsMultipleSelection:NO];
        [panel setResolvesAliases:YES];
        [panel setCanChooseFiles:NO];
        [panel setCanChooseDirectories:YES];
        [panel setShowsHiddenFiles:NO];
        [panel setExtensionHidden:YES];
        [panel setCanSelectHiddenExtension:NO];
        [panel setAllowsOtherFileTypes:NO];
        [panel setCanCreateDirectories:YES];
        
        DialogDispatcher *dispatcher = [[DialogDispatcher alloc] initWithPanel:panel owner:nil];
        {
            [dispatcher performSelectorOnMainThread:@selector(runModal) withObject:panel waitUntilDone:YES];
            NSArray *urls = [panel URLs];
            if (([dispatcher getButton] == NSFileHandlingPanelOKButton) && ([urls count] >= 1))
            {
                NSURL *url = [urls objectAtIndex:0];
                LOG("   url: %s", [[url path] UTF8String]);
                chosen = (*env)->NewStringUTF(env, [[url path] UTF8String]);
            }
        }
        [dispatcher release];
    }
    GLASS_POOL_EXIT;
    GLASS_CHECK_EXCEPTION(env);
    
    return chosen;
}
