/*
 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
 */

#import "GlassHelper.h"
#import "GlassMacros.h"

@implementation GlassHelper

static volatile jobject glassClassLoader = NULL;
+ (void)SetGlassClassLoader:(jobject)classLoader withEnv:(JNIEnv*)env
{
    glassClassLoader = (*env)->NewGlobalRef(env, classLoader);
}

/*
 * Function to find a glass class using the glass class loader. All glass
 * classes must be looked up using this function rather than FindClass so that
 * the correct ClassLoader is used.
 *
 * Note that the className passed to this function must use "." rather than "/"
 * as a package separator.
 */
+ (jclass)ClassForName:(char*)className withEnv:(JNIEnv*)env
{
    static jclass classCls = NULL;
    if (classCls == NULL)
    {
        classCls = (*env)->FindClass(env, "java/lang/Class");
    }
    if (classCls == NULL)
    {
        NSLog(@"GlassHelper error: classCls == NULL");
        return NULL;
    }

    static jmethodID forNameMID = NULL;
    if (forNameMID == NULL)
    {
        forNameMID = (*env)->GetStaticMethodID(env, classCls, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
    }
    if (forNameMID == NULL)
    {
        NSLog(@"GlassHelper error: forNameMID == NULL");
        return NULL;
    }

    jstring classNameStr = (*env)->NewStringUTF(env, className);
    if (classNameStr == NULL)
    {
        NSLog(@"GlassHelper error: classNameStrs == NULL");
        return NULL;
    }

    jclass foundClass = (*env)->CallStaticObjectMethod(env, classCls,
        forNameMID,classNameStr, JNI_TRUE, glassClassLoader);

    return foundClass;
}

+ (jclass)ApplicationClass
{
    static jclass _ApplicationClass = NULL;
    if (_ApplicationClass == NULL)
    {
        GET_MAIN_JENV;
        _ApplicationClass = [GlassHelper ClassForName:"com.sun.glass.ui.Application" withEnv:env];
        GLASS_CHECK_EXCEPTION(env);
    }
    if (_ApplicationClass == NULL)
    {
        NSLog(@"GlassHelper error: _ApplicationClass == NULL");
    }
    return _ApplicationClass;
}

+ (jmethodID)ApplicationNotifyWillFinishLaunchingMethod
{
    static jmethodID _ApplicationNotifyWillFinishLaunchingMethod = NULL;
    if (_ApplicationNotifyWillFinishLaunchingMethod == NULL)
    {
        GET_MAIN_JENV;
        _ApplicationNotifyWillFinishLaunchingMethod = (*env)->GetMethodID(env, [GlassHelper ApplicationClass], "notifyWillFinishLaunching", "()V");
        GLASS_CHECK_EXCEPTION(env);
    }
    if (_ApplicationNotifyWillFinishLaunchingMethod == NULL)
    {
        NSLog(@"GlassHelper error: _ApplicationNotifyWillFinishLaunchingMethod == NULL");
    }
    return _ApplicationNotifyWillFinishLaunchingMethod;
}

+ (jmethodID)ApplicationNotifyDidFinishLaunchingMethod
{
    static jmethodID _ApplicationNotifyDidFinishLaunchingMethod = NULL;
    if (_ApplicationNotifyDidFinishLaunchingMethod == NULL)
    {
        GET_MAIN_JENV;
        _ApplicationNotifyDidFinishLaunchingMethod = (*env)->GetMethodID(env, [GlassHelper ApplicationClass], "notifyDidFinishLaunching", "()V");
        GLASS_CHECK_EXCEPTION(env);
    }
    if (_ApplicationNotifyDidFinishLaunchingMethod == NULL)
    {
        NSLog(@"GlassHelper error: _ApplicationNotifyDidFinishLaunchingMethod == NULL");
    }
    return _ApplicationNotifyDidFinishLaunchingMethod;
}

+ (jmethodID)ApplicationNotifyWillBecomeActiveMethod
{
    static jmethodID _ApplicationNotifyWillBecomeActiveMethod = NULL;
    if (_ApplicationNotifyWillBecomeActiveMethod == NULL)
    {
        GET_MAIN_JENV;
        _ApplicationNotifyWillBecomeActiveMethod = (*env)->GetMethodID(env, [GlassHelper ApplicationClass], "notifyWillBecomeActive", "()V");
        GLASS_CHECK_EXCEPTION(env);
    }
    if (_ApplicationNotifyWillBecomeActiveMethod == NULL)
    {
        NSLog(@"GlassHelper error: _ApplicationNotifyWillBecomeActiveMethod == NULL");
    }
    return _ApplicationNotifyWillBecomeActiveMethod;
}

+ (jmethodID)ApplicationNotifyDidBecomeActiveMethod
{
    static jmethodID _ApplicationNotifyDidBecomeActiveMethod = NULL;
    if (_ApplicationNotifyDidBecomeActiveMethod == NULL)
    {
        GET_MAIN_JENV;
        _ApplicationNotifyDidBecomeActiveMethod = (*env)->GetMethodID(env, [GlassHelper ApplicationClass], "notifyDidBecomeActive", "()V");
        GLASS_CHECK_EXCEPTION(env);
    }
    if (_ApplicationNotifyDidBecomeActiveMethod == NULL)
    {
        NSLog(@"GlassHelper error: _ApplicationNotifyDidBecomeActiveMethod == NULL");
    }
    return _ApplicationNotifyDidBecomeActiveMethod;
}

+ (jmethodID)ApplicationNotifyWillResignActiveMethod
{
    static jmethodID _ApplicationNotifyWillResignActiveMethod = NULL;
    if (_ApplicationNotifyWillResignActiveMethod == NULL)
    {
        GET_MAIN_JENV;
        _ApplicationNotifyWillResignActiveMethod = (*env)->GetMethodID(env, [GlassHelper ApplicationClass], "notifyWillResignActive", "()V");
        GLASS_CHECK_EXCEPTION(env);
    }
    if (_ApplicationNotifyWillResignActiveMethod == NULL)
    {
        NSLog(@"GlassHelper error: _ApplicationNotifyWillResignActiveMethod == NULL");
    }
    return _ApplicationNotifyWillResignActiveMethod;
}

+ (jmethodID)ApplicationNotifyDidResignActiveMethod
{
    static jmethodID _ApplicationNotifyDidResignActiveMethod = NULL;
    if (_ApplicationNotifyDidResignActiveMethod == NULL)
    {
        GET_MAIN_JENV;
        _ApplicationNotifyDidResignActiveMethod = (*env)->GetMethodID(env, [GlassHelper ApplicationClass], "notifyDidResignActive", "()V");
        GLASS_CHECK_EXCEPTION(env);
    }
    if (_ApplicationNotifyDidResignActiveMethod == NULL)
    {
        NSLog(@"GlassHelper error: _ApplicationNotifyDidResignActiveMethod == NULL");
    }
    return _ApplicationNotifyDidResignActiveMethod;
}

+ (jmethodID)ApplicationNotifyWillHideMethod
{
    static jmethodID _ApplicationNotifyWillHideMethod = NULL;
    if (_ApplicationNotifyWillHideMethod == NULL)
    {
        GET_MAIN_JENV;
        _ApplicationNotifyWillHideMethod = (*env)->GetMethodID(env, [GlassHelper ApplicationClass], "notifyWillHide", "()V");
        GLASS_CHECK_EXCEPTION(env);
    }
    if (_ApplicationNotifyWillHideMethod == NULL)
    {
        NSLog(@"GlassHelper error: _ApplicationNotifyWillHideMethod == NULL");
    }
    return _ApplicationNotifyWillHideMethod;
}

+ (jmethodID)ApplicationNotifyDidHideMethod
{
    static jmethodID _ApplicationNotifyDidHideMethod = NULL;
    if (_ApplicationNotifyDidHideMethod == NULL)
    {
        GET_MAIN_JENV;
        _ApplicationNotifyDidHideMethod = (*env)->GetMethodID(env, [GlassHelper ApplicationClass], "notifyDidHide", "()V");
        GLASS_CHECK_EXCEPTION(env);
    }
    if (_ApplicationNotifyDidHideMethod == NULL)
    {
        NSLog(@"GlassHelper error: _ApplicationNotifyDidHideMethod == NULL");
    }
    return _ApplicationNotifyDidHideMethod;
}

+ (jmethodID)ApplicationNotifyWillUnhideMethod
{
    static jmethodID _ApplicationNotifyWillUnhideMethod = NULL;
    if (_ApplicationNotifyWillUnhideMethod == NULL)
    {
        GET_MAIN_JENV;
        _ApplicationNotifyWillUnhideMethod = (*env)->GetMethodID(env, [GlassHelper ApplicationClass], "notifyWillUnhide", "()V");
        GLASS_CHECK_EXCEPTION(env);
    }
    if (_ApplicationNotifyWillUnhideMethod == NULL)
    {
        NSLog(@"GlassHelper error: _ApplicationNotifyWillUnhideMethod == NULL");
    }
    return _ApplicationNotifyWillUnhideMethod;
}

+ (jmethodID)ApplicationNotifyDidUnhideMethod
{
    static jmethodID _ApplicationNotifyDidUnhideMethod = NULL;
    if (_ApplicationNotifyDidUnhideMethod == NULL)
    {
        GET_MAIN_JENV;
        _ApplicationNotifyDidUnhideMethod = (*env)->GetMethodID(env, [GlassHelper ApplicationClass], "notifyDidUnhide", "()V");
        GLASS_CHECK_EXCEPTION(env);
    }
    if (_ApplicationNotifyDidUnhideMethod == NULL)
    {
        NSLog(@"GlassHelper error: _ApplicationNotifyDidUnhideMethod == NULL");
    }
    return _ApplicationNotifyDidUnhideMethod;
}

+ (jmethodID)ApplicationNotifyOpenFilesMethod
{
    static jmethodID _ApplicationNotifyOpenFilesMethod = NULL;
    if (_ApplicationNotifyOpenFilesMethod == NULL)
    {
        GET_MAIN_JENV;
        _ApplicationNotifyOpenFilesMethod = (*env)->GetMethodID(env, [GlassHelper ApplicationClass], "notifyOpenFiles", "([Ljava/lang/String;)V");
        GLASS_CHECK_EXCEPTION(env);
    }
    if (_ApplicationNotifyOpenFilesMethod == NULL)
    {
        NSLog(@"GlassHelper error: _ApplicationNotifyOpenFilesMethod == NULL");
    }
    return _ApplicationNotifyOpenFilesMethod;
}

@end
