/*
 * Copyright (c) 2011, 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 "CSystemColors.h"

#import "java_awt_SystemColor.h"
#import "sun_lwawt_macosx_LWCToolkit.h"

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

#import "ThreadUtilities.h"

NSColor **sColors = nil;
NSColor **appleColors = nil;

@implementation CSystemColors

+ (void)initialize {
    JNIEnv *env = [ThreadUtilities getJNIEnv];
JNF_COCOA_ENTER(env);
    [CSystemColors reloadColors];
    [[NSNotificationCenter defaultCenter] addObserver:[CSystemColors class] selector:@selector(systemColorsDidChange:) name:NSSystemColorsDidChangeNotification object:nil];
JNF_COCOA_EXIT(env);
}

static JNF_CLASS_CACHE(jc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit");
static JNF_STATIC_MEMBER_CACHE(jm_systemColorsChanged, jc_LWCToolkit, "systemColorsChanged", "()V");

+ (void)systemColorsDidChange:(NSNotification *)notification {
    AWT_ASSERT_APPKIT_THREAD;

    [CSystemColors reloadColors];

    // Call LWCToolkit with the news. LWCToolkit makes certain to do its duties
    // from a new thread.
    JNIEnv* env = [ThreadUtilities getJNIEnv];
    JNFCallStaticVoidMethod(env, jm_systemColorsChanged); // AWT_THREADING Safe (event)
}


+ (void)reloadColors {
    // NOTE: <rdar://problem/3447825> was filed to make this code even lazier. Each
    //  color below could be set lazily when it was first accessed. This way the
    //  arrays would be sparse, and filled in as SystemColors were used.
    int i;
    if (sColors == nil) {
        sColors = (NSColor**)malloc(sizeof(NSColor*) * java_awt_SystemColor_NUM_COLORS);
    } else {
        for (i = 0; i < java_awt_SystemColor_NUM_COLORS; i++) {
            if (sColors[i] != NULL) CFRelease(sColors[i]); // GC
        }
    }

    sColors[java_awt_SystemColor_DESKTOP] =                    [NSColor greenColor];
    sColors[java_awt_SystemColor_ACTIVE_CAPTION] =            [NSColor whiteColor];
    sColors[java_awt_SystemColor_ACTIVE_CAPTION_TEXT] =        [NSColor blackColor];
    sColors[java_awt_SystemColor_ACTIVE_CAPTION_BORDER] =    [NSColor whiteColor];
    sColors[java_awt_SystemColor_INACTIVE_CAPTION] =        [NSColor grayColor];
    sColors[java_awt_SystemColor_INACTIVE_CAPTION_TEXT] =    [NSColor grayColor];
    sColors[java_awt_SystemColor_INACTIVE_CAPTION_BORDER] =    [NSColor grayColor];
    const CGFloat color = (CGFloat)0xEE/(CGFloat)0xFF;
    sColors[java_awt_SystemColor_WINDOW] = [NSColor colorWithCalibratedRed:color green:color blue:color alpha:1.0f];
    sColors[java_awt_SystemColor_WINDOW_BORDER] =            [NSColor windowFrameColor];
    sColors[java_awt_SystemColor_WINDOW_TEXT] =                [NSColor windowFrameTextColor];
    sColors[java_awt_SystemColor_MENU] =                    [NSColor controlBackgroundColor];
    sColors[java_awt_SystemColor_MENU_TEXT] =                [NSColor controlTextColor];
    sColors[java_awt_SystemColor_TEXT] =                    [NSColor textBackgroundColor];
    sColors[java_awt_SystemColor_TEXT_TEXT] =                [NSColor textColor];
    sColors[java_awt_SystemColor_TEXT_HIGHLIGHT] =            [NSColor selectedTextBackgroundColor];
    sColors[java_awt_SystemColor_TEXT_HIGHLIGHT_TEXT] =        [NSColor selectedTextColor];
    sColors[java_awt_SystemColor_TEXT_INACTIVE_TEXT] =        [NSColor disabledControlTextColor];
    sColors[java_awt_SystemColor_CONTROL] =                    [NSColor controlColor];
    sColors[java_awt_SystemColor_CONTROL_TEXT] =            [NSColor controlTextColor];
    sColors[java_awt_SystemColor_CONTROL_HIGHLIGHT] =        [NSColor alternateSelectedControlColor];
    sColors[java_awt_SystemColor_CONTROL_LT_HIGHLIGHT] =    [NSColor alternateSelectedControlTextColor];
    sColors[java_awt_SystemColor_CONTROL_SHADOW] =            [NSColor controlShadowColor];
    sColors[java_awt_SystemColor_CONTROL_DK_SHADOW] =        [NSColor controlDarkShadowColor];
    sColors[java_awt_SystemColor_SCROLLBAR] =                [NSColor scrollBarColor];
    sColors[java_awt_SystemColor_INFO] =                    [NSColor textBackgroundColor];
    sColors[java_awt_SystemColor_INFO_TEXT] =                [NSColor textColor];

    for (i = 0; i < java_awt_SystemColor_NUM_COLORS; i++) {
        if (sColors[i] != NULL) CFRetain(sColors[i]); // GC
    }

    if (appleColors == nil) {
        appleColors = (NSColor**)malloc(sizeof(NSColor*) * sun_lwawt_macosx_LWCToolkit_NUM_APPLE_COLORS);
    } else {
        for (i = 0; i < sun_lwawt_macosx_LWCToolkit_NUM_APPLE_COLORS; i++) {
            if (appleColors[i] != NULL) CFRelease(appleColors[i]); // GC
        }
    }

    appleColors[sun_lwawt_macosx_LWCToolkit_KEYBOARD_FOCUS_COLOR] =                    [NSColor keyboardFocusIndicatorColor];
    appleColors[sun_lwawt_macosx_LWCToolkit_INACTIVE_SELECTION_BACKGROUND_COLOR] =    [NSColor secondarySelectedControlColor];
    appleColors[sun_lwawt_macosx_LWCToolkit_INACTIVE_SELECTION_FOREGROUND_COLOR] =    [NSColor controlDarkShadowColor];

    for (i = 0; i < sun_lwawt_macosx_LWCToolkit_NUM_APPLE_COLORS; i++) {
        if (appleColors[i] != NULL) CFRetain(appleColors[i]); // GC
    }
}

+ (NSColor*)getColor:(NSUInteger)colorIndex useAppleColor:(BOOL)useAppleColor {
    NSColor* result = nil;

    if (colorIndex < (useAppleColor) ? sun_lwawt_macosx_LWCToolkit_NUM_APPLE_COLORS : java_awt_SystemColor_NUM_COLORS) {
        result = (useAppleColor ? appleColors : sColors)[colorIndex];
    }
    else {
        NSLog(@"%s: %s %sColor: %ld not found, returning black.", __FILE__, __FUNCTION__, (useAppleColor) ? "Apple" : "System", colorIndex);
        result = [NSColor blackColor];
    }

    return result;
}
@end
