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

#include "GlassApplication.h"
#include "Utils.h"
#include "Pixels.h"
#include "com_sun_glass_ui_Cursor.h"
#include "com_sun_glass_ui_win_WinCursor.h"

HCURSOR currentCursor;

static HCURSOR GetNativeCursor(int type)
{
    LPCTSTR winCursor;
    switch (type) {
        case com_sun_glass_ui_Cursor_CURSOR_DEFAULT:
            winCursor = IDC_ARROW;
            break;
        case com_sun_glass_ui_Cursor_CURSOR_TEXT:
            winCursor = IDC_IBEAM;
            break;
        case com_sun_glass_ui_Cursor_CURSOR_CROSSHAIR:
            winCursor = IDC_CROSS;
            break;
        case com_sun_glass_ui_Cursor_CURSOR_CLOSED_HAND:
        case com_sun_glass_ui_Cursor_CURSOR_OPEN_HAND:
        case com_sun_glass_ui_Cursor_CURSOR_POINTING_HAND:
            winCursor = IDC_HAND;
            break;
        case com_sun_glass_ui_Cursor_CURSOR_RESIZE_UP:
        case com_sun_glass_ui_Cursor_CURSOR_RESIZE_DOWN:
        case com_sun_glass_ui_Cursor_CURSOR_RESIZE_UPDOWN:
             winCursor = IDC_SIZENS;
             break;
        case com_sun_glass_ui_Cursor_CURSOR_RESIZE_LEFT:
        case com_sun_glass_ui_Cursor_CURSOR_RESIZE_RIGHT:
        case com_sun_glass_ui_Cursor_CURSOR_RESIZE_LEFTRIGHT:
            winCursor = IDC_SIZEWE;
            break;
        case com_sun_glass_ui_Cursor_CURSOR_RESIZE_SOUTHWEST:
        case com_sun_glass_ui_Cursor_CURSOR_RESIZE_NORTHEAST:
            winCursor = IDC_SIZENESW;
            break;
        case com_sun_glass_ui_Cursor_CURSOR_RESIZE_SOUTHEAST:
        case com_sun_glass_ui_Cursor_CURSOR_RESIZE_NORTHWEST:
            winCursor = IDC_SIZENWSE;
            break;
        case com_sun_glass_ui_Cursor_CURSOR_MOVE:
            winCursor = IDC_SIZEALL;
            break;
        case com_sun_glass_ui_Cursor_CURSOR_DISAPPEAR:
            // Not implemented, using CURSOR_DEFAULT instead
            winCursor = IDC_ARROW;
            break;
        case com_sun_glass_ui_Cursor_CURSOR_WAIT:
            winCursor = IDC_WAIT;
            break;
        case com_sun_glass_ui_Cursor_CURSOR_NONE:
            return NULL;
        default:
            winCursor = IDC_ARROW;
            break;
    }

    HCURSOR hCursor = ::LoadCursor(NULL, winCursor);
    if (!hCursor) {
        // Not a system cursor, check for resource
        hCursor = ::LoadCursor(GetModuleHandle(NULL), winCursor);
    }
    if (!hCursor) {
        hCursor = ::LoadCursor(NULL, IDC_ARROW);
    }
    ASSERT(hCursor);

    return hCursor;
}

extern "C" {

/*
 * Class:     com_sun_glass_ui_win_WinCursor
 * Method:    _initIDs
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinCursor__1initIDs
(JNIEnv *env, jclass cls)
{
    cls = env->FindClass("com/sun/glass/ui/Size");
    
    javaIDs.Size.init = env->GetMethodID(cls, "<init>", "(II)V");
    ASSERT(javaIDs.Size.init);
}
	
/*
 * Class:     com_sun_glass_ui_win_WinCursor
 * Method:    _createCursor
 * Signature: (IIIILjava/nio/ByteBuffer;)J
 */
JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_win_WinCursor__1createCursor
	(JNIEnv *env, jobject jThis, jint x, jint y, jobject pixels)
{
    return (jlong)Pixels::CreateCursor(env, pixels, x, y);
}

/*
 * Class:     com_sun_glass_ui_win_WinCursor
 * Method:    _set
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinCursor__1set
    (JNIEnv *env, jobject jThis, jint type)
{
    ASSERT(type != com_sun_glass_ui_Cursor_CURSOR_CUSTOM);
    HCURSOR hCursor = GetNativeCursor(type);
    currentCursor = hCursor;
    ::SetCursor(hCursor);
}

/*
 * Class:     com_sun_glass_ui_win_WinCursor
 * Method:    _setCustom
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinCursor__1setCustom
    (JNIEnv *env, jobject jThis, jlong cursorPtr)
{
    HCURSOR hCursor = (HCURSOR)cursorPtr;
    if (hCursor) {
        currentCursor = hCursor;
        ::SetCursor(hCursor);
    }
}

/*
 * Class:     com_sun_glass_ui_win_WinCursor
 * Method:    _setVisible
 * Signature: (Z)V
 */
JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinCursor__1setVisible
    (JNIEnv *env, jclass jCursorClass, jboolean jshow)
{
    static BOOL visible = TRUE;
    BOOL show = jbool_to_bool(jshow);

    //XXX: not thread safe
    if (show != visible) {
        ::ShowCursor(show);
        visible = show;
    }
}

/*
 * Class:     com_sun_glass_ui_win_WinCursor
 * Method:    _getBestSize
 * Signature: (II)Lcom.sun.glass.ui.Size;
 */
JNIEXPORT jobject JNICALL Java_com_sun_glass_ui_win_WinCursor__1getBestSize
	(JNIEnv *env, jclass jCursorClass, jint width, jint height)
{
    return env->NewObject(env->FindClass("com/sun/glass/ui/Size"),
            javaIDs.Size.init,
            (jint)::GetSystemMetrics(SM_CXCURSOR),
            (jint)::GetSystemMetrics(SM_CYCURSOR));
}
} // extern "C"
