/*
 * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "PlatformEventFactoryMac.h"

#if PLATFORM(MAC)

#import "KeyEventCocoa.h"
#import "Logging.h"
#import "PlatformScreen.h"
#import "Scrollbar.h"
#import "WindowsKeyboardCodes.h"
#import <Carbon/Carbon.h>
#import <mach/mach_time.h>
#import <pal/spi/mac/HIToolboxSPI.h>
#import <pal/spi/mac/NSEventSPI.h>
#import <pal/spi/mac/NSMenuSPI.h>
#import <wtf/ASCIICType.h>
#import <wtf/WallTime.h>

namespace WebCore {

NSPoint globalPoint(const NSPoint& windowPoint, NSWindow *window)
{
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    return flipScreenPoint([window convertBaseToScreen:windowPoint], screen(window));
    ALLOW_DEPRECATED_DECLARATIONS_END
}

static NSPoint globalPointForEvent(NSEvent *event)
{
    switch ([event type]) {
    case NSEventTypePressure:
    case NSEventTypeLeftMouseDown:
    case NSEventTypeLeftMouseDragged:
    case NSEventTypeLeftMouseUp:
    case NSEventTypeMouseEntered:
    case NSEventTypeMouseExited:
    case NSEventTypeMouseMoved:
    case NSEventTypeOtherMouseDown:
    case NSEventTypeOtherMouseDragged:
    case NSEventTypeOtherMouseUp:
    case NSEventTypeRightMouseDown:
    case NSEventTypeRightMouseDragged:
    case NSEventTypeRightMouseUp:
    case NSEventTypeScrollWheel:
        return globalPoint([event locationInWindow], [event window]);
    default:
        return { 0, 0 };
    }
}

static IntPoint pointForEvent(NSEvent *event, NSView *windowView)
{
    switch ([event type]) {
    case NSEventTypePressure:
    case NSEventTypeLeftMouseDown:
    case NSEventTypeLeftMouseDragged:
    case NSEventTypeLeftMouseUp:
    case NSEventTypeMouseEntered:
    case NSEventTypeMouseExited:
    case NSEventTypeMouseMoved:
    case NSEventTypeOtherMouseDown:
    case NSEventTypeOtherMouseDragged:
    case NSEventTypeOtherMouseUp:
    case NSEventTypeRightMouseDown:
    case NSEventTypeRightMouseDragged:
    case NSEventTypeRightMouseUp:
    case NSEventTypeScrollWheel: {
        // Note: This will have its origin at the bottom left of the window unless windowView is flipped.
        // In those cases, the Y coordinate gets flipped by Widget::convertFromContainingWindow.
        NSPoint location = [event locationInWindow];
        if (windowView)
            location = [windowView convertPoint:location fromView:nil];
        return IntPoint(location);
    }
    default:
        return IntPoint();
    }
}

static MouseButton mouseButtonForEvent(NSEvent *event)
{
    switch ([event type]) {
    case NSEventTypePressure:
    case NSEventTypeLeftMouseDown:
    case NSEventTypeLeftMouseUp:
    case NSEventTypeLeftMouseDragged:
        return LeftButton;
    case NSEventTypeRightMouseDown:
    case NSEventTypeRightMouseUp:
    case NSEventTypeRightMouseDragged:
        return RightButton;
    case NSEventTypeOtherMouseDown:
    case NSEventTypeOtherMouseUp:
    case NSEventTypeOtherMouseDragged:
        return MiddleButton;
    default:
        return NoButton;
    }
}

static unsigned short currentlyPressedMouseButtons()
{
    return static_cast<unsigned short>([NSEvent pressedMouseButtons]);
}

static PlatformEvent::Type mouseEventTypeForEvent(NSEvent* event)
{
    switch ([event type]) {
    case NSEventTypeLeftMouseDragged:
    case NSEventTypeMouseEntered:
    case NSEventTypeMouseExited:
    case NSEventTypeMouseMoved:
    case NSEventTypeOtherMouseDragged:
    case NSEventTypeRightMouseDragged:
        return PlatformEvent::MouseMoved;
    case NSEventTypeLeftMouseDown:
    case NSEventTypeRightMouseDown:
    case NSEventTypeOtherMouseDown:
        return PlatformEvent::MousePressed;
    case NSEventTypeLeftMouseUp:
    case NSEventTypeRightMouseUp:
    case NSEventTypeOtherMouseUp:
        return PlatformEvent::MouseReleased;
    default:
        return PlatformEvent::MouseMoved;
    }
}

static int clickCountForEvent(NSEvent *event)
{
    switch ([event type]) {
    case NSEventTypeLeftMouseDown:
    case NSEventTypeLeftMouseUp:
    case NSEventTypeLeftMouseDragged:
    case NSEventTypeRightMouseDown:
    case NSEventTypeRightMouseUp:
    case NSEventTypeRightMouseDragged:
    case NSEventTypeOtherMouseDown:
    case NSEventTypeOtherMouseUp:
    case NSEventTypeOtherMouseDragged:
        return [event clickCount];
    default:
        return 0;
    }
}

static PlatformWheelEventPhase momentumPhaseForEvent(NSEvent *event)
{
    uint32_t phase = PlatformWheelEventPhaseNone;

    if ([event momentumPhase] & NSEventPhaseBegan)
        phase |= PlatformWheelEventPhaseBegan;
    if ([event momentumPhase] & NSEventPhaseStationary)
        phase |= PlatformWheelEventPhaseStationary;
    if ([event momentumPhase] & NSEventPhaseChanged)
        phase |= PlatformWheelEventPhaseChanged;
    if ([event momentumPhase] & NSEventPhaseEnded)
        phase |= PlatformWheelEventPhaseEnded;
    if ([event momentumPhase] & NSEventPhaseCancelled)
        phase |= PlatformWheelEventPhaseCancelled;

    return static_cast<PlatformWheelEventPhase>(phase);
}

static PlatformWheelEventPhase phaseForEvent(NSEvent *event)
{
    uint32_t phase = PlatformWheelEventPhaseNone; 
    if ([event phase] & NSEventPhaseBegan)
        phase |= PlatformWheelEventPhaseBegan;
    if ([event phase] & NSEventPhaseStationary)
        phase |= PlatformWheelEventPhaseStationary;
    if ([event phase] & NSEventPhaseChanged)
        phase |= PlatformWheelEventPhaseChanged;
    if ([event phase] & NSEventPhaseEnded)
        phase |= PlatformWheelEventPhaseEnded;
    if ([event phase] & NSEventPhaseCancelled)
        phase |= PlatformWheelEventPhaseCancelled;
    if ([event momentumPhase] & NSEventPhaseMayBegin)
        phase |= PlatformWheelEventPhaseMayBegin;

    return static_cast<PlatformWheelEventPhase>(phase);
}

static inline String textFromEvent(NSEvent* event)
{
    if ([event type] == NSEventTypeFlagsChanged)
        return emptyString();
    return String([event characters]);
}

static inline String unmodifiedTextFromEvent(NSEvent* event)
{
    if ([event type] == NSEventTypeFlagsChanged)
        return emptyString();
    return String([event charactersIgnoringModifiers]);
}

String keyForKeyEvent(NSEvent *event)
{
    switch ([event keyCode]) {
    case kVK_RightCommand:
    case kVK_Command:
        return "Meta"_s;
    case kVK_Shift:
    case kVK_RightShift:
        return "Shift"_s;
    case kVK_CapsLock:
        return "CapsLock"_s;
    case kVK_Option: // Left Alt.
    case kVK_RightOption: // Right Alt.
        return "Alt"_s;
    case kVK_Control:
    case kVK_RightControl:
        return "Control"_s;
    }

    // If the event is an NSEventTypeFlagsChanged events and we have not returned yet then this means we could not
    // identify the modifier key. We return now and report the key as "Unidentified".
    // Note that [event characters] below raises an exception if called on an NSEventTypeFlagsChanged event.
    if ([event type] == NSEventTypeFlagsChanged)
        return "Unidentified"_s;

    // If more than one key is being pressed and the key combination includes one or more modifier keys
    // that result in the key no longer producing a printable character (e.g., Control + a), then the
    // key value should be the printable key value that would have been produced if the key had been
    // typed with the default keyboard layout with no modifier keys except for Shift and AltGr applied.
    // See <https://www.w3.org/TR/2015/WD-uievents-20151215/#keys-guidelines>.
    bool isControlDown = ([event modifierFlags] & NSEventModifierFlagControl);
    NSString *s = isControlDown ? [event charactersIgnoringModifiers] : [event characters];
    auto length = [s length];
    // characters / charactersIgnoringModifiers return an empty string for dead keys.
    // https://developer.apple.com/reference/appkit/nsevent/1534183-characters
    if (!length)
        return "Dead"_s;
    // High unicode codepoints are coded with a character sequence in Mac OS X.
    if (length > 1)
        return s;
    return keyForCharCode([s characterAtIndex:0]);
}

// https://w3c.github.io/uievents-code/
String codeForKeyEvent(NSEvent *event)
{
    switch ([event keyCode]) {
    // Keys in the alphanumeric section.
    case kVK_ANSI_Grave: return "Backquote"_s;
    case kVK_ANSI_Backslash: return "Backslash"_s;
    case kVK_Delete: return "Backspace"_s;
    case kVK_ANSI_LeftBracket: return "BracketLeft"_s;
    case kVK_ANSI_RightBracket: return "BracketRight"_s;
    case kVK_ANSI_Comma: return "Comma"_s;
    case kVK_ANSI_0: return "Digit0"_s;
    case kVK_ANSI_1: return "Digit1"_s;
    case kVK_ANSI_2: return "Digit2"_s;
    case kVK_ANSI_3: return "Digit3"_s;
    case kVK_ANSI_4: return "Digit4"_s;
    case kVK_ANSI_5: return "Digit5"_s;
    case kVK_ANSI_6: return "Digit6"_s;
    case kVK_ANSI_7: return "Digit7"_s;
    case kVK_ANSI_8: return "Digit8"_s;
    case kVK_ANSI_9: return "Digit9"_s;
    case kVK_ANSI_Equal: return "Equal"_s;
    case kVK_ISO_Section: return "IntlBackslash"_s;
    case kVK_JIS_Underscore: return "IntlRo"_s;
    case kVK_JIS_Yen: return "IntlYen"_s;
    case kVK_ANSI_A: return "KeyA"_s;
    case kVK_ANSI_B: return "KeyB"_s;
    case kVK_ANSI_C: return "KeyC"_s;
    case kVK_ANSI_D: return "KeyD"_s;
    case kVK_ANSI_E: return "KeyE"_s;
    case kVK_ANSI_F: return "KeyF"_s;
    case kVK_ANSI_G: return "KeyG"_s;
    case kVK_ANSI_H: return "KeyH"_s;
    case kVK_ANSI_I: return "KeyI"_s;
    case kVK_ANSI_J: return "KeyJ"_s;
    case kVK_ANSI_K: return "KeyK"_s;
    case kVK_ANSI_L: return "KeyL"_s;
    case kVK_ANSI_M: return "KeyM"_s;
    case kVK_ANSI_N: return "KeyN"_s;
    case kVK_ANSI_O: return "KeyO"_s;
    case kVK_ANSI_P: return "KeyP"_s;
    case kVK_ANSI_Q: return "KeyQ"_s;
    case kVK_ANSI_R: return "KeyR"_s;
    case kVK_ANSI_S: return "KeyS"_s;
    case kVK_ANSI_T: return "KeyT"_s;
    case kVK_ANSI_U: return "KeyU"_s;
    case kVK_ANSI_V: return "KeyV"_s;
    case kVK_ANSI_W: return "KeyW"_s;
    case kVK_ANSI_X: return "KeyX"_s;
    case kVK_ANSI_Y: return "KeyY"_s;
    case kVK_ANSI_Z: return "KeyZ"_s;
    case kVK_ANSI_Minus: return "Minus"_s;
    case kVK_ANSI_Period: return "Period"_s;
    case kVK_ANSI_Quote: return "Quote"_s;
    case kVK_ANSI_Semicolon: return "Semicolon"_s;
    case kVK_ANSI_Slash: return "Slash"_s;

    // Functional keys in alphanumeric section.
    case kVK_Option: return "AltLeft"_s;
    case kVK_RightOption: return "AltRight"_s;
    case kVK_CapsLock: return "CapsLock"_s;
    // ContextMenu.
    case kVK_Control: return "ControlLeft"_s;
    case kVK_RightControl: return "ControlRight"_s;
    case kVK_Return: return "Enter"_s; //  Labeled Return on Apple keyboards.
    case kVK_Command: return "MetaLeft"_s;
    case kVK_RightCommand: return "MetaRight"_s;
    case kVK_Shift: return "ShiftLeft"_s;
    case kVK_RightShift: return "ShiftRight"_s;
    case kVK_Space: return "Space"_s;
    case kVK_Tab: return "Tab"_s;

    // Functional keys found on Japanese and Korean keyboards.
    // Convert.
    case kVK_JIS_Kana: return "KanaMode"_s;
    // Lang1.
    case kVK_JIS_Eisu: return "Lang2"_s; // Japanese (Mac keyboard): eisu.
    // Lang3.
    // Lang4.
    // Lang5.
    // NonConvert.

    // Keys in the ControlPad section.
    case kVK_ForwardDelete: return "Delete"_s;
    case kVK_End: return "End"_s;
    case kVK_Help: return "Help"_s;
    case kVK_Home: return "Home"_s;
    // Insert: Not present on Apple keyboards.
    case kVK_PageDown: return "PageDown"_s;
    case kVK_PageUp: return "PageUp"_s;

    // Keys in the ArrowPad section.
    case kVK_DownArrow: return "ArrowDown"_s;
    case kVK_LeftArrow: return "ArrowLeft"_s;
    case kVK_RightArrow: return "ArrowRight"_s;
    case kVK_UpArrow: return "ArrowUp"_s;

    // Keys in the Numpad section.
    case kVK_ANSI_KeypadClear: return "NumLock"_s; // The specification says to use "NumLock" on Mac for the numpad Clear key.
    case kVK_ANSI_Keypad0: return "Numpad0"_s;
    case kVK_ANSI_Keypad1: return "Numpad1"_s;
    case kVK_ANSI_Keypad2: return "Numpad2"_s;
    case kVK_ANSI_Keypad3: return "Numpad3"_s;
    case kVK_ANSI_Keypad4: return "Numpad4"_s;
    case kVK_ANSI_Keypad5: return "Numpad5"_s;
    case kVK_ANSI_Keypad6: return "Numpad6"_s;
    case kVK_ANSI_Keypad7: return "Numpad7"_s;
    case kVK_ANSI_Keypad8: return "Numpad8"_s;
    case kVK_ANSI_Keypad9: return "Numpad9"_s;
    case kVK_ANSI_KeypadPlus: return "NumpadAdd"_s;
    // NumpadBackspace.
    // NumpadClear: The specification says that the numpad Clear key should always be encoded as "NumLock" on Mac.
    // NumpadClearEntry.
    case kVK_JIS_KeypadComma: return "NumpadComma"_s;
    case kVK_ANSI_KeypadDecimal: return "NumpadDecimal"_s;
    case kVK_ANSI_KeypadDivide: return "NumpadDivide"_s;
    case kVK_ANSI_KeypadEnter: return "NumpadEnter"_s;
    case kVK_ANSI_KeypadEquals: return "NumpadEqual"_s;
    // NumpadHash.
    // NumpadMemoryAdd.
    // NumpadMemoryClear.
    // NumpadMemoryRecall.
    // NumpadMemoryStore.
    // NumpadMemorySubtract.
    case kVK_ANSI_KeypadMultiply: return "NumpadMultiply"_s;
    // NumpadParenLeft.
    // NumpadParenRight.
    // NumpadStar: The specification says to use "NumpadMultiply" for the * key on numeric keypads.
    case kVK_ANSI_KeypadMinus: return "NumpadSubtract"_s;

    // Keys in the Function section.
    case kVK_Escape: return "Escape"_s;
    case kVK_F1: return "F1"_s;
    case kVK_F2: return "F2"_s;
    case kVK_F3: return "F3"_s;
    case kVK_F4: return "F4"_s;
    case kVK_F5: return "F5"_s;
    case kVK_F6: return "F6"_s;
    case kVK_F7: return "F7"_s;
    case kVK_F8: return "F8"_s;
    case kVK_F9: return "F9"_s;
    case kVK_F10: return "F10"_s;
    case kVK_F11: return "F11"_s;
    case kVK_F12: return "F12"_s;
    case kVK_F13: return "F13"_s;
    case kVK_F14: return "F14"_s;
    case kVK_F15: return "F15"_s;
    case kVK_F16: return "F16"_s;
    case kVK_F17: return "F17"_s;
    case kVK_F18: return "F18"_s;
    case kVK_F19: return "F19"_s;
    case kVK_F20: return "F20"_s;
    // Fn: This is typically a hardware key that does not generate a separate code.
    // FnLock.
    // PrintScreen.
    // ScrollLock.
    // Pause.

    // Media keys.
    // BrowserBack.
    // BrowserFavorites.
    // BrowserForward.
    // BrowserHome.
    // BrowserRefresh.
    // BrowserSearch.
    // BrowserStop.
    // Eject.
    // LaunchApp1.
    // LaunchApp2.
    // LaunchMail.
    // MediaPlayPause.
    // MediaSelect.
    // MediaStop.
    // MediaTrackNext.
    // MediaTrackPrevious.
    // Power.
    // Sleep.
    case kVK_VolumeDown: return "AudioVolumeDown"_s;
    case kVK_Mute: return "AudioVolumeMute"_s;
    case kVK_VolumeUp: return "AudioVolumeUp"_s;
    // WakeUp.

    // Legacy modifier keys.
    // Hyper.
    // Super.
    // Turbo.

    // Legacy process control keys.
    // Abort.
    // Resume.
    // Suspend.

    // Legacy editing keys.
    // Again.
    // Copy.
    // Cut.
    // Find.
    // Open.
    // Paste.
    // Props.
    // Select.
    // Undo.

    // Keys found on international keyboards.
    // Hiragana.
    // Katakana.

    default:
        return "Unidentified"_s;
    }
}

String keyIdentifierForKeyEvent(NSEvent* event)
{
    if ([event type] == NSEventTypeFlagsChanged) {
        switch ([event keyCode]) {
        case 54: // Right Command
        case 55: // Left Command
            return "Meta"_str;

        case 57: // Capslock
            return "CapsLock"_str;

        case 56: // Left Shift
        case 60: // Right Shift
            return "Shift"_str;

        case 58: // Left Alt
        case 61: // Right Alt
            return "Alt"_str;

        case 59: // Left Ctrl
        case 62: // Right Ctrl
            return "Control"_str;

        default:
            ASSERT_NOT_REACHED();
            return emptyString();
        }
    }
    
    NSString *s = [event charactersIgnoringModifiers];
    if ([s length] != 1) {
        LOG(Events, "received an unexpected number of characters in key event: %u", [s length]);
        return "Unidentified";
    }
    return keyIdentifierForCharCode([s characterAtIndex:0]);
}

static bool isKeypadEvent(NSEvent* event)
{
    // Check that this is the type of event that has a keyCode.
    switch ([event type]) {
    case NSEventTypeKeyDown:
    case NSEventTypeKeyUp:
    case NSEventTypeFlagsChanged:
        break;
    default:
        return false;
    }

    if ([event modifierFlags] & NSEventModifierFlagNumericPad)
        return true;

    switch ([event keyCode]) {
    case 71: // Clear
    case 81: // =
    case 75: // /
    case 67: // *
    case 78: // -
    case 69: // +
    case 76: // Enter
    case 65: // .
    case 82: // 0
    case 83: // 1
    case 84: // 2
    case 85: // 3
    case 86: // 4
    case 87: // 5
    case 88: // 6
    case 89: // 7
    case 91: // 8
    case 92: // 9
        return true;
    }
     
     return false;
}

int windowsKeyCodeForKeyEvent(NSEvent* event)
{
    int code = 0;
    // There are several kinds of characters for which we produce key code from char code:
    // 1. Roman letters. Windows keyboard layouts affect both virtual key codes and character codes for these,
    //    so e.g. 'A' gets the same keyCode on QWERTY, AZERTY or Dvorak layouts.
    // 2. Keys for which there is no known Mac virtual key codes, like PrintScreen.
    // 3. Certain punctuation keys. On Windows, these are also remapped depending on current keyboard layout,
    //    but see comment in windowsKeyCodeForCharCode().
    if (!isKeypadEvent(event) && ([event type] == NSEventTypeKeyDown || [event type] == NSEventTypeKeyUp)) {
        // Cmd switches Roman letters for Dvorak-QWERTY layout, so try modified characters first.
        NSString* s = [event characters];
        code = [s length] > 0 ? windowsKeyCodeForCharCode([s characterAtIndex:0]) : 0;
        if (code)
            return code;

        // Ctrl+A on an AZERTY keyboard would get VK_Q keyCode if we relied on -[NSEvent keyCode] below.
        s = [event charactersIgnoringModifiers];
        code = [s length] > 0 ? windowsKeyCodeForCharCode([s characterAtIndex:0]) : 0;
        if (code)
            return code;
    }

    // Map Mac virtual key code directly to Windows one for any keys not handled above.
    // E.g. the key next to Caps Lock has the same Event.keyCode on U.S. keyboard ('A') and on Russian keyboard (CYRILLIC LETTER EF).
    return windowsKeyCodeForKeyCode([event keyCode]);
}

static CFAbsoluteTime systemStartupTime;

static void updateSystemStartupTimeIntervalSince1970()
{
    // CFAbsoluteTimeGetCurrent() provides the absolute time in seconds since 2001.
    // mach_absolute_time() provides a relative system time since startup minus the time the computer was suspended.
    mach_timebase_info_data_t timebase_info;
    mach_timebase_info(&timebase_info);
    double elapsedTimeSinceStartup = static_cast<double>(mach_absolute_time()) * timebase_info.numer / timebase_info.denom / 1e9;
    systemStartupTime = kCFAbsoluteTimeIntervalSince1970 + CFAbsoluteTimeGetCurrent() - elapsedTimeSinceStartup;
}

static CFTimeInterval cachedStartupTimeIntervalSince1970()
{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        void (^updateBlock)(NSNotification *) = Block_copy(^(NSNotification *){ updateSystemStartupTimeIntervalSince1970(); });
        [[[NSWorkspace sharedWorkspace] notificationCenter] addObserverForName:NSWorkspaceDidWakeNotification
                                                                        object:nil
                                                                         queue:nil
                                                                    usingBlock:updateBlock];
        [[NSNotificationCenter defaultCenter] addObserverForName:NSSystemClockDidChangeNotification
                                                          object:nil
                                                           queue:nil
                                                      usingBlock:updateBlock];
        Block_release(updateBlock);

        updateSystemStartupTimeIntervalSince1970();
    });
    return systemStartupTime;
}

WallTime eventTimeStampSince1970(NSEvent* event)
{
    return WallTime::fromRawSeconds(static_cast<double>(cachedStartupTimeIntervalSince1970() + [event timestamp]));
}

static inline bool isKeyUpEvent(NSEvent *event)
{
    if ([event type] != NSEventTypeFlagsChanged)
        return [event type] == NSEventTypeKeyUp;
    // FIXME: This logic fails if the user presses both Shift keys at once, for example:
    // we treat releasing one of them as keyDown.
    switch ([event keyCode]) {
    case 54: // Right Command
    case 55: // Left Command
        return !([event modifierFlags] & NSEventModifierFlagCommand);

    case 57: // Capslock
        return !([event modifierFlags] & NSEventModifierFlagCapsLock);

    case 56: // Left Shift
    case 60: // Right Shift
        return !([event modifierFlags] & NSEventModifierFlagShift);

    case 58: // Left Alt
    case 61: // Right Alt
        return !([event modifierFlags] & NSEventModifierFlagOption);

    case 59: // Left Ctrl
    case 62: // Right Ctrl
        return !([event modifierFlags] & NSEventModifierFlagControl);

    case 63: // Function
        return !([event modifierFlags] & NSEventModifierFlagFunction);
    }
    return false;
}

OptionSet<PlatformEvent::Modifier> modifiersForEvent(NSEvent *event)
{
    OptionSet<PlatformEvent::Modifier> modifiers;

    if (event.modifierFlags & NSEventModifierFlagShift)
        modifiers.add(PlatformEvent::Modifier::ShiftKey);
    if (event.modifierFlags & NSEventModifierFlagControl)
        modifiers.add(PlatformEvent::Modifier::ControlKey);
    if (event.modifierFlags & NSEventModifierFlagOption)
        modifiers.add(PlatformEvent::Modifier::AltKey);
    if (event.modifierFlags & NSEventModifierFlagCommand)
        modifiers.add(PlatformEvent::Modifier::MetaKey);
    if (event.modifierFlags & NSEventModifierFlagCapsLock)
        modifiers.add(PlatformEvent::Modifier::CapsLockKey);

    return modifiers;
}

static int typeForEvent(NSEvent *event)
{
    return static_cast<int>([NSMenu menuTypeForEvent:event]);
}

void getWheelEventDeltas(NSEvent *event, float& deltaX, float& deltaY, BOOL& continuous)
{
    ASSERT(event);
    if (event.hasPreciseScrollingDeltas) {
        deltaX = event.scrollingDeltaX;
        deltaY = event.scrollingDeltaY;
        continuous = YES;
    } else {
        deltaX = event.deltaX;
        deltaY = event.deltaY;
        continuous = NO;
    }
}

UInt8 keyCharForEvent(NSEvent *event)
{
    EventRef eventRef = (EventRef)[event _eventRef];
    if (!eventRef)
        return 0;

    ByteCount keyCharCount = 0;
    if (GetEventParameter(eventRef, kEventParamKeyMacCharCodes, typeChar, 0, 0, &keyCharCount, 0) != noErr)
        return 0;
    if (keyCharCount != 1)
        return 0;

    UInt8 keyChar = 0;
    if (GetEventParameter(eventRef, kEventParamKeyMacCharCodes, typeChar, 0, sizeof(keyChar), &keyCharCount, &keyChar) != noErr)
        return 0;
    
    return keyChar;
}

class PlatformMouseEventBuilder : public PlatformMouseEvent {
public:
    PlatformMouseEventBuilder(NSEvent *event, NSEvent *correspondingPressureEvent, NSView *windowView)
    {
        // PlatformEvent
        m_type = mouseEventTypeForEvent(event);

        BOOL eventIsPressureEvent = [event type] == NSEventTypePressure;
        if (eventIsPressureEvent) {
            // Since AppKit doesn't send mouse events for force down or force up, we have to use the current pressure
            // event and correspondingPressureEvent to detect if this is MouseForceDown, MouseForceUp, or just MouseForceChanged.
            if (correspondingPressureEvent.stage == 1 && event.stage == 2)
                m_type = PlatformEvent::MouseForceDown;
            else if (correspondingPressureEvent.stage == 2 && event.stage == 1)
                m_type = PlatformEvent::MouseForceUp;
            else
                m_type = PlatformEvent::MouseForceChanged;
        }

        m_modifiers = modifiersForEvent(event);
        m_timestamp = eventTimeStampSince1970(event);

        // PlatformMouseEvent
        m_position = pointForEvent(event, windowView);
        m_globalPosition = IntPoint(globalPointForEvent(event));
        m_button = mouseButtonForEvent(event);
        m_buttons = currentlyPressedMouseButtons();
        m_clickCount = clickCountForEvent(event);
#if ENABLE(POINTER_LOCK)
        m_movementDelta = IntPoint(event.deltaX, event.deltaY);
#endif

        m_force = 0;
        int stage = eventIsPressureEvent ? event.stage : correspondingPressureEvent.stage;
        double pressure = eventIsPressureEvent ? event.pressure : correspondingPressureEvent.pressure;
        m_force = pressure + stage;

        // Mac specific
        m_modifierFlags = [event modifierFlags];
        m_eventNumber = [event eventNumber];
        m_menuTypeForEvent = typeForEvent(event);
    }
};

PlatformMouseEvent PlatformEventFactory::createPlatformMouseEvent(NSEvent *event, NSEvent *correspondingPressureEvent, NSView *windowView)
{
    return PlatformMouseEventBuilder(event, correspondingPressureEvent, windowView);
}


class PlatformWheelEventBuilder : public PlatformWheelEvent {
public:
    PlatformWheelEventBuilder(NSEvent *event, NSView *windowView)
    {
        // PlatformEvent
        m_type = PlatformEvent::Wheel;
        m_modifiers = modifiersForEvent(event);
        m_timestamp = eventTimeStampSince1970(event);

        // PlatformWheelEvent
        m_position = pointForEvent(event, windowView);
        m_globalPosition = IntPoint(globalPointForEvent(event));
        m_granularity = ScrollByPixelWheelEvent;

        BOOL continuous;
        getWheelEventDeltas(event, m_deltaX, m_deltaY, continuous);
        if (continuous) {
            m_wheelTicksX = m_deltaX / static_cast<float>(Scrollbar::pixelsPerLineStep());
            m_wheelTicksY = m_deltaY / static_cast<float>(Scrollbar::pixelsPerLineStep());
        } else {
            m_wheelTicksX = m_deltaX;
            m_wheelTicksY = m_deltaY;
            m_deltaX *= static_cast<float>(Scrollbar::pixelsPerLineStep());
            m_deltaY *= static_cast<float>(Scrollbar::pixelsPerLineStep());
        }

        m_phase = phaseForEvent(event);
        m_momentumPhase = momentumPhaseForEvent(event);
        m_hasPreciseScrollingDeltas = continuous;
        m_directionInvertedFromDevice = [event isDirectionInvertedFromDevice];
    }
};

PlatformWheelEvent PlatformEventFactory::createPlatformWheelEvent(NSEvent *event, NSView *windowView)
{
    return PlatformWheelEventBuilder(event, windowView);
}


class PlatformKeyboardEventBuilder : public PlatformKeyboardEvent {
public:
    PlatformKeyboardEventBuilder(NSEvent *event)
    {
        // PlatformEvent
        m_type = isKeyUpEvent(event) ? PlatformEvent::KeyUp : PlatformEvent::KeyDown;
        m_modifiers = modifiersForEvent(event);
        m_timestamp = eventTimeStampSince1970(event);

        // PlatformKeyboardEvent
        m_text = textFromEvent(event);
        m_unmodifiedText = unmodifiedTextFromEvent(event);
        m_keyIdentifier = keyIdentifierForKeyEvent(event);
        m_key = keyForKeyEvent(event);
        m_code = codeForKeyEvent(event);
        m_windowsVirtualKeyCode = windowsKeyCodeForKeyEvent(event);
        m_autoRepeat = [event type] != NSEventTypeFlagsChanged && [event isARepeat];
        m_isKeypad = isKeypadEvent(event);
        m_isSystemKey = false; // SystemKey is always false on the Mac.

        // Always use 13 for Enter/Return -- we don't want to use AppKit's different character for Enter.
        if (m_windowsVirtualKeyCode == VK_RETURN) {
            m_text = "\r";
            m_unmodifiedText = "\r";
        }

        // AppKit sets text to "\x7F" for backspace, but the correct KeyboardEvent character code is 8.
        if (m_windowsVirtualKeyCode == VK_BACK) {
            m_text = "\x8";
            m_unmodifiedText = "\x8";
        }

        // Always use 9 for Tab -- we don't want to use AppKit's different character for shift-tab.
        if (m_windowsVirtualKeyCode == VK_TAB) {
            m_text = "\x9";
            m_unmodifiedText = "\x9";
        }

        // Mac specific.
        m_macEvent = event;
    }
};

PlatformKeyboardEvent PlatformEventFactory::createPlatformKeyboardEvent(NSEvent *event)
{
    return PlatformKeyboardEventBuilder(event);
}

} // namespace WebCore

#endif // PLATFORM(MAC)
