/*
 * Copyright (c) 2012, 2013, 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 "LWCToolkit.h"
#import "ThreadUtilities.h"

/*
 * Convert the mode string to the more convinient bits per pixel value
 */
static int getBPPFromModeString(CFStringRef mode)
{
    if ((CFStringCompare(mode, CFSTR(kIO30BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)) {
        // This is a strange mode, where we using 10 bits per RGB component and pack it into 32 bits
        // Java is not ready to work with this mode but we have to specify it as supported
        return 30;
    }
    else if (CFStringCompare(mode, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
        return 32;
    }
    else if (CFStringCompare(mode, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
        return 16;
    }
    else if (CFStringCompare(mode, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
        return 8;
    }

    return 0;
}

static BOOL isValidDisplayMode(CGDisplayModeRef mode){
    return (1 < CGDisplayModeGetWidth(mode) && 1 < CGDisplayModeGetHeight(mode));
}

static CFMutableArrayRef getAllValidDisplayModes(jint displayID){
    CFArrayRef allModes = CGDisplayCopyAllDisplayModes(displayID, NULL);

    CFIndex numModes = CFArrayGetCount(allModes);
    CFMutableArrayRef validModes = CFArrayCreateMutable(kCFAllocatorDefault, numModes + 1, &kCFTypeArrayCallBacks);

    CFIndex n;
    for (n=0; n < numModes; n++) {
        CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n);
        if (cRef != NULL && isValidDisplayMode(cRef)) {
            CFArrayAppendValue(validModes, cRef);
        }
    }
    CFRelease(allModes);
    
    CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(displayID);

    BOOL containsCurrentMode = NO;
    numModes = CFArrayGetCount(validModes);
    for (n=0; n < numModes; n++) {
        if(CFArrayGetValueAtIndex(validModes, n) == currentMode){
            containsCurrentMode = YES;
            break;
        }
    }

    if (!containsCurrentMode) {
        CFArrayAppendValue(validModes, currentMode);
    }
    CGDisplayModeRelease(currentMode);

    return validModes;
}

/*
 * Find the best possible match in the list of display modes that we can switch to based on
 * the provided parameters.
 */
static CGDisplayModeRef getBestModeForParameters(CFArrayRef allModes, int w, int h, int bpp, int refrate) {
    CGDisplayModeRef bestGuess = NULL;
    CFIndex numModes = CFArrayGetCount(allModes), n;
    int thisBpp = 0;
    for(n = 0; n < numModes; n++ ) {
        CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n);
        if(cRef == NULL) {
            continue;
        }
        CFStringRef modeString = CGDisplayModeCopyPixelEncoding(cRef);
        thisBpp = getBPPFromModeString(modeString);
        CFRelease(modeString);
        if (thisBpp != bpp || (int)CGDisplayModeGetHeight(cRef) != h || (int)CGDisplayModeGetWidth(cRef) != w) {
            // One of the key parameters does not match
            continue;
        }

        if (refrate == 0) { // REFRESH_RATE_UNKNOWN
            return cRef;
        }

        // Refresh rate might be 0 in display mode and we ask for specific display rate
        // but if we do not find exact match then 0 refresh rate might be just Ok
        if (CGDisplayModeGetRefreshRate(cRef) == refrate) {
            // Exact match
            return cRef;
        }
        if (CGDisplayModeGetRefreshRate(cRef) == 0) {
            // Not exactly what was asked for, but may fit our needs if we don't find an exact match
            bestGuess = cRef;
        }
    }
    return bestGuess;
}

/*
 * Create a new java.awt.DisplayMode instance based on provided CGDisplayModeRef
 */
static jobject createJavaDisplayMode(CGDisplayModeRef mode, JNIEnv *env, jint displayID) {
    jobject ret = NULL;
    jint h, w, bpp, refrate;
    JNF_COCOA_ENTER(env);
    CFStringRef currentBPP = CGDisplayModeCopyPixelEncoding(mode);
    bpp = getBPPFromModeString(currentBPP);
    refrate = CGDisplayModeGetRefreshRate(mode);
    h = CGDisplayModeGetHeight(mode);
    w = CGDisplayModeGetWidth(mode);
    CFRelease(currentBPP);
    static JNF_CLASS_CACHE(jc_DisplayMode, "java/awt/DisplayMode");
    static JNF_CTOR_CACHE(jc_DisplayMode_ctor, jc_DisplayMode, "(IIII)V");
    ret = JNFNewObject(env, jc_DisplayMode_ctor, w, h, bpp, refrate);
    JNF_COCOA_EXIT(env);
    return ret;
}


/*
 * Class:     sun_awt_CGraphicsDevice
 * Method:    nativeGetXResolution
 * Signature: (I)D
 */
JNIEXPORT jdouble JNICALL
Java_sun_awt_CGraphicsDevice_nativeGetXResolution
  (JNIEnv *env, jclass class, jint displayID)
{
    // TODO: this is the physically correct answer, but we probably want
    // to use NSScreen API instead...
    CGSize size = CGDisplayScreenSize(displayID);
    CGRect rect = CGDisplayBounds(displayID);
    // 1 inch == 25.4 mm
    jfloat inches = size.width / 25.4f;
    jfloat dpi = rect.size.width / inches;
    return dpi;
}

/*
 * Class:     sun_awt_CGraphicsDevice
 * Method:    nativeGetYResolution
 * Signature: (I)D
 */
JNIEXPORT jdouble JNICALL
Java_sun_awt_CGraphicsDevice_nativeGetYResolution
  (JNIEnv *env, jclass class, jint displayID)
{
    // TODO: this is the physically correct answer, but we probably want
    // to use NSScreen API instead...
    CGSize size = CGDisplayScreenSize(displayID);
    CGRect rect = CGDisplayBounds(displayID);
    // 1 inch == 25.4 mm
    jfloat inches = size.height / 25.4f;
    jfloat dpi = rect.size.height / inches;
    return dpi;
}

/*
 * Class:     sun_awt_CGraphicsDevice
 * Method:    nativeGetScreenInsets
 * Signature: (I)D
 */
JNIEXPORT jobject JNICALL
Java_sun_awt_CGraphicsDevice_nativeGetScreenInsets
  (JNIEnv *env, jclass class, jint displayID)
{
    jobject ret = NULL;
    __block NSRect frame = NSZeroRect;
    __block NSRect visibleFrame = NSZeroRect;
JNF_COCOA_ENTER(env);
    
    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
        NSArray *screens = [NSScreen screens];
        for (NSScreen *screen in screens) {
            NSDictionary *screenInfo = [screen deviceDescription];
            NSNumber *screenID = [screenInfo objectForKey:@"NSScreenNumber"];
            if ([screenID pointerValue] == displayID){
                frame = [screen frame];
                visibleFrame = [screen visibleFrame];
                break;
            }
        }
    }];
    // Convert between Cocoa's coordinate system and Java.
    jint bottom = visibleFrame.origin.y - frame.origin.y;
    jint top = frame.size.height - visibleFrame.size.height - bottom;
    jint left = visibleFrame.origin.x - frame.origin.x;
    jint right = frame.size.width - visibleFrame.size.width - left;
    
    static JNF_CLASS_CACHE(jc_Insets, "java/awt/Insets");
    static JNF_CTOR_CACHE(jc_Insets_ctor, jc_Insets, "(IIII)V");
    ret = JNFNewObject(env, jc_Insets_ctor, top, left, bottom, right);

JNF_COCOA_EXIT(env);

    return ret;
}

/*
 * Class:     sun_awt_CGraphicsDevice
 * Method:    nativeSetDisplayMode
 * Signature: (IIIII)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_CGraphicsDevice_nativeSetDisplayMode
(JNIEnv *env, jclass class, jint displayID, jint w, jint h, jint bpp, jint refrate)
{
    JNF_COCOA_ENTER(env);
    CFArrayRef allModes = getAllValidDisplayModes(displayID);
    CGDisplayModeRef closestMatch = getBestModeForParameters(allModes, (int)w, (int)h, (int)bpp, (int)refrate);
    
    __block CGError retCode = kCGErrorSuccess;
    if (closestMatch != NULL) {
        CGDisplayModeRetain(closestMatch);
        [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
            CGDisplayConfigRef config;
            retCode = CGBeginDisplayConfiguration(&config);
            if (retCode == kCGErrorSuccess) {
                CGConfigureDisplayWithDisplayMode(config, displayID, closestMatch, NULL);
                retCode = CGCompleteDisplayConfiguration(config, kCGConfigureForAppOnly);
            }
            CGDisplayModeRelease(closestMatch);
        }];
    } else {
        [JNFException raise:env as:kIllegalArgumentException reason:"Invalid display mode"];
    }

    if (retCode != kCGErrorSuccess){
        [JNFException raise:env as:kIllegalArgumentException reason:"Unable to set display mode!"];
    }
    CFRelease(allModes);
    JNF_COCOA_EXIT(env);
}
/*
 * Class:     sun_awt_CGraphicsDevice
 * Method:    nativeGetDisplayMode
 * Signature: (I)Ljava/awt/DisplayMode
 */
JNIEXPORT jobject JNICALL
Java_sun_awt_CGraphicsDevice_nativeGetDisplayMode
(JNIEnv *env, jclass class, jint displayID)
{
    jobject ret = NULL;
    CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(displayID);
    ret = createJavaDisplayMode(currentMode, env, displayID);
    CGDisplayModeRelease(currentMode);
    return ret;
}

/*
 * Class:     sun_awt_CGraphicsDevice
 * Method:    nativeGetDisplayMode
 * Signature: (I)[Ljava/awt/DisplayModes
 */
JNIEXPORT jobjectArray JNICALL
Java_sun_awt_CGraphicsDevice_nativeGetDisplayModes
(JNIEnv *env, jclass class, jint displayID)
{
    jobjectArray jreturnArray = NULL;
    JNF_COCOA_ENTER(env);
    CFArrayRef allModes = getAllValidDisplayModes(displayID);

    CFIndex numModes = CFArrayGetCount(allModes);
    static JNF_CLASS_CACHE(jc_DisplayMode, "java/awt/DisplayMode");

    jreturnArray = JNFNewObjectArray(env, &jc_DisplayMode, (jsize) numModes);
    if (!jreturnArray) {
        NSLog(@"CGraphicsDevice can't create java array of DisplayMode objects");
        return nil;
    }

    CFIndex n;
    for (n=0; n < numModes; n++) {
        CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n);
        if (cRef != NULL) {
            jobject oneMode = createJavaDisplayMode(cRef, env, displayID);
            (*env)->SetObjectArrayElement(env, jreturnArray, n, oneMode);
            if ((*env)->ExceptionOccurred(env)) {
                (*env)->ExceptionDescribe(env);
                (*env)->ExceptionClear(env);
                continue;
            }
            (*env)->DeleteLocalRef(env, oneMode);
        }
    }
    CFRelease(allModes);
    JNF_COCOA_EXIT(env);

    return jreturnArray;
}

/*
 * Class:     sun_awt_CGraphicsDevice
 * Method:    nativeGetScaleFactor
 * Signature: (I)D
 */
JNIEXPORT jdouble JNICALL
Java_sun_awt_CGraphicsDevice_nativeGetScaleFactor
(JNIEnv *env, jclass class, jint displayID)
{
    __block jdouble ret = 1.0f;

JNF_COCOA_ENTER(env);

    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
        NSArray *screens = [NSScreen screens];
        for (NSScreen *screen in screens) {
            NSDictionary *screenInfo = [screen deviceDescription];
            NSNumber *screenID = [screenInfo objectForKey:@"NSScreenNumber"];
            if ([screenID pointerValue] == displayID){
                if ([screen respondsToSelector:@selector(backingScaleFactor)]) {
                    ret = [screen backingScaleFactor];
                }
                break;
            }
        }
    }];

JNF_COCOA_EXIT(env);
    return ret;
}
