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

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

#import "LWCToolkit.h"
#import "sun_lwawt_macosx_CRobot.h"
#import "java_awt_event_InputEvent.h"
#import "sizecalc.h"


// Starting number for event numbers generated by Robot.
// Apple docs don't mention at all what are the requirements
// for these numbers. It seems that they must be higher
// than event numbers from real events, which start at some
// value close to zero. There is no API for obtaining current
// event number, so we have to start from some random number.
// 32000 as starting value works for me, let's hope that it will
// work for others as well.
#define ROBOT_EVENT_NUMBER_START 32000

#define k_JAVA_ROBOT_WHEEL_COUNT 1

#if !defined(kCGBitmapByteOrder32Host)
#define kCGBitmapByteOrder32Host 0
#endif

// In OS X, left and right mouse button share the same click count.
// That is, if one starts clicking the left button rapidly and then
// switches to the right button, then the click count will continue
// increasing, without dropping to 1 in between. The middle button,
// however, has its own click count.
// For robot, we aren't going to emulate all that complexity. All our
// synhtetic clicks share the same click count.
static int gsClickCount;
static NSTimeInterval gsLastClickTime;

// Apparently, for mouse up/down events we have to set an event number
// that is incremented on each button press. Otherwise, strange things
// happen with z-order.
static int gsEventNumber;
static int* gsButtonEventNumber;

static inline CGKeyCode GetCGKeyCode(jint javaKeyCode);

static void PostMouseEvent(const CGPoint point, CGMouseButton button,
                           CGEventType type, int clickCount, int eventNumber);

static int GetClickCount(BOOL isDown);

static void
CreateJavaException(JNIEnv* env, CGError err)
{
    // Throw a java exception indicating what is wrong.
    NSString* s = [NSString stringWithFormat:@"Robot: CGError: %d", err];
    (*env)->ThrowNew(env, (*env)->FindClass(env, "java/awt/AWTException"),
                     [s UTF8String]);
}

/*
 * Class:     sun_lwawt_macosx_CRobot
 * Method:    initRobot
 * Signature: (V)V
 */
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CRobot_initRobot
(JNIEnv *env, jobject peer)
{
    // Set things up to let our app act like a synthetic keyboard and mouse.
    // Always set all states, in case Apple ever changes default behaviors.
    static int setupDone = 0;
    if (!setupDone) {
        int i;
        jint* tmp;
        jboolean copy = JNI_FALSE;

        setupDone = 1;
        // Don't block local events after posting ours
        CGSetLocalEventsSuppressionInterval(0.0);

        // Let our event's modifier key state blend with local hardware events
        CGEnableEventStateCombining(TRUE);

        // Don't let our events block local hardware events
        CGSetLocalEventsFilterDuringSupressionState(
                                    kCGEventFilterMaskPermitAllEvents,
                                    kCGEventSupressionStateSupressionInterval);
        CGSetLocalEventsFilterDuringSupressionState(
                                    kCGEventFilterMaskPermitAllEvents,
                                    kCGEventSupressionStateRemoteMouseDrag);

        gsClickCount = 0;
        gsLastClickTime = 0;
        gsEventNumber = ROBOT_EVENT_NUMBER_START;

        gsButtonEventNumber = (int*)SAFE_SIZE_ARRAY_ALLOC(malloc, sizeof(int), gNumberOfButtons);
        if (gsButtonEventNumber == NULL) {
            JNU_ThrowOutOfMemoryError(env, NULL);
            return;
        }

        for (i = 0; i < gNumberOfButtons; ++i) {
            gsButtonEventNumber[i] = ROBOT_EVENT_NUMBER_START;
        }
    }
}

/*
 * Class:     sun_lwawt_macosx_CRobot
 * Method:    mouseEvent
 * Signature: (IIIIZZ)V
 */
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CRobot_mouseEvent
(JNIEnv *env, jobject peer,
 jint displayID, jint mouseLastX, jint mouseLastY, jint buttonsState,
 jboolean isButtonsDownState, jboolean isMouseMove)
{
    JNF_COCOA_ENTER(env);

    // This is the native method called when Robot mouse events occur.
    // The CRobot tracks the mouse position, and which button was
    // pressed. If the mouse position is unknown it is obtained from
    // CGEvents. The peer also tracks the mouse button desired state,
    // the appropriate key modifier state, and whether the mouse action
    // is simply a mouse move with no mouse button state changes.

    CGError err = kCGErrorSuccess;

    CGRect globalDeviceBounds = CGDisplayBounds(displayID);

    // Set unknown mouse location, if needed.
    if ((mouseLastX == sun_lwawt_macosx_CRobot_MOUSE_LOCATION_UNKNOWN) ||
        (mouseLastY == sun_lwawt_macosx_CRobot_MOUSE_LOCATION_UNKNOWN))
    {
        CGEventRef event = CGEventCreate(NULL);
        if (event == NULL) {
            return;
        }

        CGPoint globalPos = CGEventGetLocation(event);
        CFRelease(event);

        // Normalize the coords within this display device, as
        // per Robot rules.
        if (globalPos.x < CGRectGetMinX(globalDeviceBounds)) {
            globalPos.x = CGRectGetMinX(globalDeviceBounds);
        }
        else if (globalPos.x > CGRectGetMaxX(globalDeviceBounds)) {
            globalPos.x = CGRectGetMaxX(globalDeviceBounds);
        }

        if (globalPos.y < CGRectGetMinY(globalDeviceBounds)) {
            globalPos.y = CGRectGetMinY(globalDeviceBounds);
        }
        else if (globalPos.y > CGRectGetMaxY(globalDeviceBounds)) {
            globalPos.y = CGRectGetMaxY(globalDeviceBounds);
        }

        mouseLastX = (jint)globalPos.x;
        mouseLastY = (jint)globalPos.y;
    }

    // volatile, otherwise it warns that it might be clobbered by 'longjmp'
    volatile CGPoint point;

    point.x = mouseLastX;
    point.y = mouseLastY;

    __block CGMouseButton button = kCGMouseButtonLeft;
    __block CGEventType type = kCGEventMouseMoved;

    void (^HandleRobotButton)(CGMouseButton, CGEventType, CGEventType, CGEventType) =
        ^(CGMouseButton cgButton, CGEventType cgButtonUp, CGEventType cgButtonDown,
          CGEventType cgButtonDragged) {

            button = cgButton;
            type = cgButtonUp;

            if (isButtonsDownState) {
                if (isMouseMove) {
                    type = cgButtonDragged;
                } else {
                    type = cgButtonDown;
                }
            }
        };

    // Left
    if (buttonsState & java_awt_event_InputEvent_BUTTON1_MASK ||
        buttonsState & java_awt_event_InputEvent_BUTTON1_DOWN_MASK ) {

        HandleRobotButton(kCGMouseButtonLeft, kCGEventLeftMouseUp,
                          kCGEventLeftMouseDown, kCGEventLeftMouseDragged);
    }

    // Other
    if (buttonsState & java_awt_event_InputEvent_BUTTON2_MASK ||
        buttonsState & java_awt_event_InputEvent_BUTTON2_DOWN_MASK ) {

        HandleRobotButton(kCGMouseButtonCenter, kCGEventOtherMouseUp,
                          kCGEventOtherMouseDown, kCGEventOtherMouseDragged);
    }

    // Right
    if (buttonsState & java_awt_event_InputEvent_BUTTON3_MASK ||
        buttonsState & java_awt_event_InputEvent_BUTTON3_DOWN_MASK ) {

        HandleRobotButton(kCGMouseButtonRight, kCGEventRightMouseUp,
                          kCGEventRightMouseDown, kCGEventRightMouseDragged);
    }

    // Extra
    if (gNumberOfButtons > 3) {
        int extraButton;
        for (extraButton = 3; extraButton < gNumberOfButtons; ++extraButton) {
            if ((buttonsState & gButtonDownMasks[extraButton])) {
                HandleRobotButton(extraButton, kCGEventOtherMouseUp,
                            kCGEventOtherMouseDown, kCGEventOtherMouseDragged);
            }
        }
    }

    int clickCount = 0;
    int eventNumber = gsEventNumber;

    if (isMouseMove) {
        // any mouse movement resets click count
        gsLastClickTime = 0;
    } else {
        clickCount = GetClickCount(isButtonsDownState);

        if (isButtonsDownState) {
            gsButtonEventNumber[button] = gsEventNumber++;
        }
        eventNumber = gsButtonEventNumber[button];
    }

    PostMouseEvent(point, button, type, clickCount, eventNumber);

    JNF_COCOA_EXIT(env);
}

/*
 * Class:     sun_lwawt_macosx_CRobot
 * Method:    mouseWheel
 * Signature: (I)V
 */
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CRobot_mouseWheel
(JNIEnv *env, jobject peer, jint wheelAmt)
{
    CGEventRef event = CGEventCreateScrollWheelEvent(NULL,
                                            kCGScrollEventUnitLine,
                                            k_JAVA_ROBOT_WHEEL_COUNT, wheelAmt);

    if (event != NULL) {
        CGEventPost(kCGSessionEventTap, event);
        CFRelease(event);
    }
}

/*
 * Class:     sun_lwawt_macosx_CRobot
 * Method:    keyEvent
 * Signature: (IZ)V
 */
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CRobot_keyEvent
(JNIEnv *env, jobject peer, jint javaKeyCode, jboolean keyPressed)
{
    /*
     * Well, using CGEventCreateKeyboardEvent/CGEventPost would have been
     * a better solution, however, it gives me all kinds of trouble and I have
     * no idea how to solve them without inserting delays between simulated
     * events. So, I've ended up disabling it and opted for another approach
     * that uses Accessibility API instead.
     */
    CGKeyCode keyCode = GetCGKeyCode(javaKeyCode);
    AXUIElementRef elem = AXUIElementCreateSystemWide();
    AXUIElementPostKeyboardEvent(elem, (CGCharCode)0, keyCode, keyPressed);
    CFRelease(elem);


#if 0
    CGEventRef event = CGEventCreateKeyboardEvent(NULL, keyCode, keyPressed);
    if (event != NULL) {
        CGEventPost(kCGSessionEventTap, event);
        CFRelease(event);
    }
#endif
}

/*
 * Class:     sun_lwawt_macosx_CRobot
 * Method:    nativeGetScreenPixels
 * Signature: (IIIII[I)V
 */
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CRobot_nativeGetScreenPixels
(JNIEnv *env, jobject peer,
 jint x, jint y, jint width, jint height, jintArray pixels)
{
    JNF_COCOA_ENTER(env);

    jint picX = x;
    jint picY = y;
    jint picWidth = width;
    jint picHeight = height;

    CGRect screenRect = CGRectMake(picX, picY, picWidth, picHeight);
    CGImageRef screenPixelsImage = CGWindowListCreateImage(screenRect,
                                        kCGWindowListOptionOnScreenOnly,
                                        kCGNullWindowID, kCGWindowImageDefault);

    if (screenPixelsImage == NULL) {
        return;
    }

    // get a pointer to the Java int array
    void *jPixelData = (*env)->GetPrimitiveArrayCritical(env, pixels, 0);
    CHECK_NULL(jPixelData);

    // create a graphics context around the Java int array
    CGColorSpaceRef picColorSpace = CGColorSpaceCreateWithName(
                                            kCGColorSpaceGenericRGB);
    CGContextRef jPicContextRef = CGBitmapContextCreate(
                                            jPixelData,
                                            picWidth, picHeight,
                                            8, picWidth * sizeof(jint),
                                            picColorSpace,
                                            kCGBitmapByteOrder32Host |
                                            kCGImageAlphaPremultipliedFirst);

    CGColorSpaceRelease(picColorSpace);

    // flip, scale, and color correct the screen image into the Java pixels
    CGRect bounds = { { 0, 0 }, { picWidth, picHeight } };
    CGContextDrawImage(jPicContextRef, bounds, screenPixelsImage);
    CGContextFlush(jPicContextRef);

    // cleanup
    CGContextRelease(jPicContextRef);
    CGImageRelease(screenPixelsImage);

    // release the Java int array back up to the JVM
    (*env)->ReleasePrimitiveArrayCritical(env, pixels, jPixelData, 0);

    JNF_COCOA_EXIT(env);
}

/****************************************************
 * Helper methods
 ****************************************************/

static void PostMouseEvent(const CGPoint point, CGMouseButton button,
                           CGEventType type, int clickCount, int eventNumber)
{
    CGEventRef mouseEvent = CGEventCreateMouseEvent(NULL, type, point, button);
    if (mouseEvent != NULL) {
        CGEventSetIntegerValueField(mouseEvent, kCGMouseEventClickState, clickCount);
        CGEventSetIntegerValueField(mouseEvent, kCGMouseEventNumber, eventNumber);
        CGEventPost(kCGSessionEventTap, mouseEvent);
        CFRelease(mouseEvent);
    }
}

// NOTE: Don't modify this table directly. It is machine generated. See below.
static const unsigned char javaToMacKeyCode[] = {
    127,    //     0     0 VK_UNDEFINED                      No_Equivalent
    127,    //     1   0x1 Not_Used
    127,    //     2   0x2 Not_Used
    127,    //     3   0x3 VK_CANCEL                         No_Equivalent
    127,    //     4   0x4 Not_Used
    127,    //     5   0x5 Not_Used
    127,    //     6   0x6 Not_Used
    127,    //     7   0x7 Not_Used
     51,    //     8   0x8 VK_BACK_SPACE
     48,    //     9   0x9 VK_TAB
     36,    //    10   0xa VK_ENTER
    127,    //    11   0xb Not_Used
     71,    //    12   0xc VK_CLEAR
    127,    //    13   0xd Not_Used
    127,    //    14   0xe Not_Used
    127,    //    15   0xf Not_Used
     56,    //    16  0x10 VK_SHIFT
     59,    //    17  0x11 VK_CONTROL
     58,    //    18  0x12 VK_ALT
    113,    //    19  0x13 VK_PAUSE
     57,    //    20  0x14 VK_CAPS_LOCK
    127,    //    21  0x15 VK_KANA                           No_Equivalent
    127,    //    22  0x16 Not_Used
    127,    //    23  0x17 Not_Used
    127,    //    24  0x18 VK_FINAL                          No_Equivalent
    127,    //    25  0x19 VK_KANJI                          No_Equivalent
    127,    //    26  0x1a Not_Used
     53,    //    27  0x1b VK_ESCAPE
    127,    //    28  0x1c VK_CONVERT                        No_Equivalent
    127,    //    29  0x1d VK_NONCONVERT                     No_Equivalent
    127,    //    30  0x1e VK_ACCEPT                         No_Equivalent
    127,    //    31  0x1f VK_MODECHANGE                     No_Equivalent
     49,    //    32  0x20 VK_SPACE
    116,    //    33  0x21 VK_PAGE_UP
    121,    //    34  0x22 VK_PAGE_DOWN
    119,    //    35  0x23 VK_END
    115,    //    36  0x24 VK_HOME
    123,    //    37  0x25 VK_LEFT
    126,    //    38  0x26 VK_UP
    124,    //    39  0x27 VK_RIGHT
    125,    //    40  0x28 VK_DOWN
    127,    //    41  0x29 Not_Used
    127,    //    42  0x2a Not_Used
    127,    //    43  0x2b Not_Used
     43,    //    44  0x2c VK_COMMA
     27,    //    45  0x2d VK_MINUS
     47,    //    46  0x2e VK_PERIOD
     44,    //    47  0x2f VK_SLASH
     29,    //    48  0x30 VK_0
     18,    //    49  0x31 VK_1
     19,    //    50  0x32 VK_2
     20,    //    51  0x33 VK_3
     21,    //    52  0x34 VK_4
     23,    //    53  0x35 VK_5
     22,    //    54  0x36 VK_6
     26,    //    55  0x37 VK_7
     28,    //    56  0x38 VK_8
     25,    //    57  0x39 VK_9
    127,    //    58  0x3a Not_Used
     41,    //    59  0x3b VK_SEMICOLON
    127,    //    60  0x3c Not_Used
     24,    //    61  0x3d VK_EQUALS
    127,    //    62  0x3e Not_Used
    127,    //    63  0x3f Not_Used
    127,    //    64  0x40 Not_Used
      0,    //    65  0x41 VK_A
     11,    //    66  0x42 VK_B
      8,    //    67  0x43 VK_C
      2,    //    68  0x44 VK_D
     14,    //    69  0x45 VK_E
      3,    //    70  0x46 VK_F
      5,    //    71  0x47 VK_G
      4,    //    72  0x48 VK_H
     34,    //    73  0x49 VK_I
     38,    //    74  0x4a VK_J
     40,    //    75  0x4b VK_K
     37,    //    76  0x4c VK_L
     46,    //    77  0x4d VK_M
     45,    //    78  0x4e VK_N
     31,    //    79  0x4f VK_O
     35,    //    80  0x50 VK_P
     12,    //    81  0x51 VK_Q
     15,    //    82  0x52 VK_R
      1,    //    83  0x53 VK_S
     17,    //    84  0x54 VK_T
     32,    //    85  0x55 VK_U
      9,    //    86  0x56 VK_V
     13,    //    87  0x57 VK_W
      7,    //    88  0x58 VK_X
     16,    //    89  0x59 VK_Y
      6,    //    90  0x5a VK_Z
     33,    //    91  0x5b VK_OPEN_BRACKET
     42,    //    92  0x5c VK_BACK_SLASH
     30,    //    93  0x5d VK_CLOSE_BRACKET
    127,    //    94  0x5e Not_Used
    127,    //    95  0x5f Not_Used
     82,    //    96  0x60 VK_NUMPAD0
     83,    //    97  0x61 VK_NUMPAD1
     84,    //    98  0x62 VK_NUMPAD2
     85,    //    99  0x63 VK_NUMPAD3
     86,    //   100  0x64 VK_NUMPAD4
     87,    //   101  0x65 VK_NUMPAD5
     88,    //   102  0x66 VK_NUMPAD6
     89,    //   103  0x67 VK_NUMPAD7
     91,    //   104  0x68 VK_NUMPAD8
     92,    //   105  0x69 VK_NUMPAD9
     67,    //   106  0x6a VK_MULTIPLY
     69,    //   107  0x6b VK_ADD
    127,    //   108  0x6c VK_SEPARATER                      No_Equivalent
     78,    //   109  0x6d VK_SUBTRACT
     65,    //   110  0x6e VK_DECIMAL
     75,    //   111  0x6f VK_DIVIDE
    122,    //   112  0x70 VK_F1
    120,    //   113  0x71 VK_F2
     99,    //   114  0x72 VK_F3
    118,    //   115  0x73 VK_F4
     96,    //   116  0x74 VK_F5
     97,    //   117  0x75 VK_F6
     98,    //   118  0x76 VK_F7
    100,    //   119  0x77 VK_F8
    101,    //   120  0x78 VK_F9
    109,    //   121  0x79 VK_F10
    103,    //   122  0x7a VK_F11
    111,    //   123  0x7b VK_F12
    127,    //   124  0x7c Not_Used
    127,    //   125  0x7d Not_Used
    127,    //   126  0x7e Not_Used
    117,    //   127  0x7f VK_DELETE
    127,    //   128  0x80 VK_DEAD_GRAVE                     No_Equivalent
    127,    //   129  0x81 VK_DEAD_ACUTE                     No_Equivalent
    127,    //   130  0x82 VK_DEAD_CIRCUMFLEX                No_Equivalent
    127,    //   131  0x83 VK_DEAD_TILDE                     No_Equivalent
    127,    //   132  0x84 VK_DEAD_MACRON                    No_Equivalent
    127,    //   133  0x85 VK_DEAD_BREVE                     No_Equivalent
    127,    //   134  0x86 VK_DEAD_ABOVEDOT                  No_Equivalent
    127,    //   135  0x87 VK_DEAD_DIAERESIS                 No_Equivalent
    127,    //   136  0x88 VK_DEAD_ABOVERING                 No_Equivalent
    127,    //   137  0x89 VK_DEAD_DOUBLEACUTE               No_Equivalent
    127,    //   138  0x8a VK_DEAD_CARON                     No_Equivalent
    127,    //   139  0x8b VK_DEAD_CEDILLA                   No_Equivalent
    127,    //   140  0x8c VK_DEAD_OGONEK                    No_Equivalent
    127,    //   141  0x8d VK_DEAD_IOTA                      No_Equivalent
    127,    //   142  0x8e VK_DEAD_VOICED_SOUND              No_Equivalent
    127,    //   143  0x8f VK_DEAD_SEMIVOICED_SOUND          No_Equivalent
    127,    //   144  0x90 VK_NUM_LOCK                       No_Equivalent
    107,    //   145  0x91 VK_SCROLL_LOCK
    127,    //   146  0x92 Not_Used
    127,    //   147  0x93 Not_Used
    127,    //   148  0x94 Not_Used
    127,    //   149  0x95 Not_Used
    127,    //   150  0x96 VK_AMPERSAND                      No_Equivalent
    127,    //   151  0x97 VK_ASTERISK                       No_Equivalent
    127,    //   152  0x98 VK_QUOTEDBL                       No_Equivalent
    127,    //   153  0x99 VK_LESS                           No_Equivalent
    105,    //   154  0x9a VK_PRINTSCREEN
    127,    //   155  0x9b VK_INSERT                         No_Equivalent
    114,    //   156  0x9c VK_HELP
     55,    //   157  0x9d VK_META
    127,    //   158  0x9e Not_Used
    127,    //   159  0x9f Not_Used
    127,    //   160  0xa0 VK_GREATER                        No_Equivalent
    127,    //   161  0xa1 VK_BRACELEFT                      No_Equivalent
    127,    //   162  0xa2 VK_BRACERIGHT                     No_Equivalent
    127,    //   163  0xa3 Not_Used
    127,    //   164  0xa4 Not_Used
    127,    //   165  0xa5 Not_Used
    127,    //   166  0xa6 Not_Used
    127,    //   167  0xa7 Not_Used
    127,    //   168  0xa8 Not_Used
    127,    //   169  0xa9 Not_Used
    127,    //   170  0xaa Not_Used
    127,    //   171  0xab Not_Used
    127,    //   172  0xac Not_Used
    127,    //   173  0xad Not_Used
    127,    //   174  0xae Not_Used
    127,    //   175  0xaf Not_Used
    127,    //   176  0xb0 Not_Used
    127,    //   177  0xb1 Not_Used
    127,    //   178  0xb2 Not_Used
    127,    //   179  0xb3 Not_Used
    127,    //   180  0xb4 Not_Used
    127,    //   181  0xb5 Not_Used
    127,    //   182  0xb6 Not_Used
    127,    //   183  0xb7 Not_Used
    127,    //   184  0xb8 Not_Used
    127,    //   185  0xb9 Not_Used
    127,    //   186  0xba Not_Used
    127,    //   187  0xbb Not_Used
    127,    //   188  0xbc Not_Used
    127,    //   189  0xbd Not_Used
    127,    //   190  0xbe Not_Used
    127,    //   191  0xbf Not_Used
     50,    //   192  0xc0 VK_BACK_QUOTE
    127,    //   193  0xc1 Not_Used
    127,    //   194  0xc2 Not_Used
    127,    //   195  0xc3 Not_Used
    127,    //   196  0xc4 Not_Used
    127,    //   197  0xc5 Not_Used
    127,    //   198  0xc6 Not_Used
    127,    //   199  0xc7 Not_Used
    127,    //   200  0xc8 Not_Used
    127,    //   201  0xc9 Not_Used
    127,    //   202  0xca Not_Used
    127,    //   203  0xcb Not_Used
    127,    //   204  0xcc Not_Used
    127,    //   205  0xcd Not_Used
    127,    //   206  0xce Not_Used
    127,    //   207  0xcf Not_Used
    127,    //   208  0xd0 Not_Used
    127,    //   209  0xd1 Not_Used
    127,    //   210  0xd2 Not_Used
    127,    //   211  0xd3 Not_Used
    127,    //   212  0xd4 Not_Used
    127,    //   213  0xd5 Not_Used
    127,    //   214  0xd6 Not_Used
    127,    //   215  0xd7 Not_Used
    127,    //   216  0xd8 Not_Used
    127,    //   217  0xd9 Not_Used
    127,    //   218  0xda Not_Used
    127,    //   219  0xdb Not_Used
    127,    //   220  0xdc Not_Used
    127,    //   221  0xdd Not_Used
     39     //   222  0xde VK_QUOTE
};

// NOTE: All values above 222 don't have an equivalent on MacOSX.
static inline CGKeyCode GetCGKeyCode(jint javaKeyCode)
{
    if (javaKeyCode > 222) {
        return 127;
    } else {
        return javaToMacKeyCode[javaKeyCode];
    }
}

static int GetClickCount(BOOL isDown) {
    NSTimeInterval now = [[NSDate date] timeIntervalSinceReferenceDate];
    NSTimeInterval clickInterval = now - gsLastClickTime;
    BOOL isWithinTreshold = clickInterval < [NSEvent doubleClickInterval];

    if (isDown) {
        if (isWithinTreshold) {
            gsClickCount++;
        } else {
            gsClickCount = 1;
        }

        gsLastClickTime = now;
    } else {
        // In OS X, a mouse up has the click count of the last mouse down
        // if an interval between up and down is within the double click
        // threshold, and 0 otherwise.
        if (!isWithinTreshold) {
            gsClickCount = 0;
        }
    }

    return gsClickCount;
}
