//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// OSXWindow.mm: Implementation of OSWindow for OSX

#include "util/osx/OSXWindow.h"

#include <set>
// Include Carbon to use the keycode names in Carbon's Event.h
#include <Carbon/Carbon.h>

#include "anglebase/no_destructor.h"
#include "common/debug.h"

// On OSX 10.12 a number of AppKit interfaces have been renamed for consistency, and the previous
// symbols tagged as deprecated. However we can't simply use the new symbols as it would break
// compilation on our automated testing that doesn't use OSX 10.12 yet. So we just ignore the
// warnings.
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

// Some events such as "ShouldTerminate" are sent to the whole application so we keep a list of
// all the windows in order to forward the event to each of them. However this and calling pushEvent
// in ApplicationDelegate is inherently unsafe in a multithreaded environment.
static std::set<OSXWindow *> &AllWindows()
{
    static angle::base::NoDestructor<std::set<OSXWindow *>> allWindows;
    return *allWindows;
}

@interface Application : NSApplication
@end

@implementation Application
- (void)sendEvent:(NSEvent *)nsEvent
{
    if ([nsEvent type] == NSApplicationDefined)
    {
        for (auto window : AllWindows())
        {
            if ([window->getNSWindow() windowNumber] == [nsEvent windowNumber])
            {
                Event event;
                event.Type = Event::EVENT_TEST;
                window->pushEvent(event);
            }
        }
    }
    [super sendEvent:nsEvent];
}
@end

// The Delegate receiving application-wide events.
@interface ApplicationDelegate : NSObject
@end

@implementation ApplicationDelegate
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
    Event event;
    event.Type = Event::EVENT_CLOSED;
    for (auto window : AllWindows())
    {
        window->pushEvent(event);
    }
    return NSTerminateCancel;
}
@end
static ApplicationDelegate *gApplicationDelegate = nil;

static bool InitializeAppKit()
{
    if (NSApp != nil)
    {
        return true;
    }

    // Initialize the global variable "NSApp"
    [Application sharedApplication];

    // Make us appear in the dock
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];

    // Register our global event handler
    gApplicationDelegate = [[ApplicationDelegate alloc] init];
    if (gApplicationDelegate == nil)
    {
        return false;
    }
    [NSApp setDelegate:static_cast<id>(gApplicationDelegate)];

    // Set our status to "started" so we are not bouncing in the doc and can activate
    [NSApp finishLaunching];
    return true;
}

// NS's and CG's coordinate systems start at the bottom left, while OSWindow's coordinate
// system starts at the top left. This function converts the Y coordinate accordingly.
static float YCoordToFromCG(float y)
{
    float screenHeight = CGDisplayBounds(CGMainDisplayID()).size.height;
    return screenHeight - y;
}

// Delegate for window-wide events, note that the protocol doesn't contain anything input related.
@implementation WindowDelegate
- (id)initWithWindow:(OSXWindow *)window
{
    self = [super init];
    if (self != nil)
    {
        mWindow = window;
    }
    return self;
}

- (void)onOSXWindowDeleted
{
    mWindow = nil;
}

- (BOOL)windowShouldClose:(id)sender
{
    Event event;
    event.Type = Event::EVENT_CLOSED;
    mWindow->pushEvent(event);
    return NO;
}

- (void)windowDidResize:(NSNotification *)notification
{
    NSSize windowSize = [[mWindow->getNSWindow() contentView] frame].size;
    Event event;
    event.Type        = Event::EVENT_RESIZED;
    event.Size.Width  = (int)windowSize.width;
    event.Size.Height = (int)windowSize.height;
    mWindow->pushEvent(event);
}

- (void)windowDidMove:(NSNotification *)notification
{
    NSRect screenspace = [mWindow->getNSWindow() frame];
    Event event;
    event.Type   = Event::EVENT_MOVED;
    event.Move.X = (int)screenspace.origin.x;
    event.Move.Y = (int)YCoordToFromCG(screenspace.origin.y + screenspace.size.height);
    mWindow->pushEvent(event);
}

- (void)windowDidBecomeKey:(NSNotification *)notification
{
    Event event;
    event.Type = Event::EVENT_GAINED_FOCUS;
    mWindow->pushEvent(event);
    [self retain];
}

- (void)windowDidResignKey:(NSNotification *)notification
{
    if (mWindow != nil)
    {
        Event event;
        event.Type = Event::EVENT_LOST_FOCUS;
        mWindow->pushEvent(event);
    }
    [self release];
}
@end

static Key NSCodeToKey(int keyCode)
{
    // Missing KEY_PAUSE
    switch (keyCode)
    {
        case kVK_Shift:
            return KEY_LSHIFT;
        case kVK_RightShift:
            return KEY_RSHIFT;
        case kVK_Option:
            return KEY_LALT;
        case kVK_RightOption:
            return KEY_RALT;
        case kVK_Control:
            return KEY_LCONTROL;
        case kVK_RightControl:
            return KEY_RCONTROL;
        case kVK_Command:
            return KEY_LSYSTEM;
        // Right System doesn't have a name, but shows up as 0x36.
        case 0x36:
            return KEY_RSYSTEM;
        case kVK_Function:
            return KEY_MENU;

        case kVK_ANSI_Semicolon:
            return KEY_SEMICOLON;
        case kVK_ANSI_Slash:
            return KEY_SLASH;
        case kVK_ANSI_Equal:
            return KEY_EQUAL;
        case kVK_ANSI_Minus:
            return KEY_DASH;
        case kVK_ANSI_LeftBracket:
            return KEY_LBRACKET;
        case kVK_ANSI_RightBracket:
            return KEY_RBRACKET;
        case kVK_ANSI_Comma:
            return KEY_COMMA;
        case kVK_ANSI_Period:
            return KEY_PERIOD;
        case kVK_ANSI_Backslash:
            return KEY_BACKSLASH;
        case kVK_ANSI_Grave:
            return KEY_TILDE;
        case kVK_Escape:
            return KEY_ESCAPE;
        case kVK_Space:
            return KEY_SPACE;
        case kVK_Return:
            return KEY_RETURN;
        case kVK_Delete:
            return KEY_BACK;
        case kVK_Tab:
            return KEY_TAB;
        case kVK_PageUp:
            return KEY_PAGEUP;
        case kVK_PageDown:
            return KEY_PAGEDOWN;
        case kVK_End:
            return KEY_END;
        case kVK_Home:
            return KEY_HOME;
        case kVK_Help:
            return KEY_INSERT;
        case kVK_ForwardDelete:
            return KEY_DELETE;
        case kVK_ANSI_KeypadPlus:
            return KEY_ADD;
        case kVK_ANSI_KeypadMinus:
            return KEY_SUBTRACT;
        case kVK_ANSI_KeypadMultiply:
            return KEY_MULTIPLY;
        case kVK_ANSI_KeypadDivide:
            return KEY_DIVIDE;

        case kVK_F1:
            return KEY_F1;
        case kVK_F2:
            return KEY_F2;
        case kVK_F3:
            return KEY_F3;
        case kVK_F4:
            return KEY_F4;
        case kVK_F5:
            return KEY_F5;
        case kVK_F6:
            return KEY_F6;
        case kVK_F7:
            return KEY_F7;
        case kVK_F8:
            return KEY_F8;
        case kVK_F9:
            return KEY_F9;
        case kVK_F10:
            return KEY_F10;
        case kVK_F11:
            return KEY_F11;
        case kVK_F12:
            return KEY_F12;
        case kVK_F13:
            return KEY_F13;
        case kVK_F14:
            return KEY_F14;
        case kVK_F15:
            return KEY_F15;

        case kVK_LeftArrow:
            return KEY_LEFT;
        case kVK_RightArrow:
            return KEY_RIGHT;
        case kVK_DownArrow:
            return KEY_DOWN;
        case kVK_UpArrow:
            return KEY_UP;

        case kVK_ANSI_Keypad0:
            return KEY_NUMPAD0;
        case kVK_ANSI_Keypad1:
            return KEY_NUMPAD1;
        case kVK_ANSI_Keypad2:
            return KEY_NUMPAD2;
        case kVK_ANSI_Keypad3:
            return KEY_NUMPAD3;
        case kVK_ANSI_Keypad4:
            return KEY_NUMPAD4;
        case kVK_ANSI_Keypad5:
            return KEY_NUMPAD5;
        case kVK_ANSI_Keypad6:
            return KEY_NUMPAD6;
        case kVK_ANSI_Keypad7:
            return KEY_NUMPAD7;
        case kVK_ANSI_Keypad8:
            return KEY_NUMPAD8;
        case kVK_ANSI_Keypad9:
            return KEY_NUMPAD9;

        case kVK_ANSI_A:
            return KEY_A;
        case kVK_ANSI_B:
            return KEY_B;
        case kVK_ANSI_C:
            return KEY_C;
        case kVK_ANSI_D:
            return KEY_D;
        case kVK_ANSI_E:
            return KEY_E;
        case kVK_ANSI_F:
            return KEY_F;
        case kVK_ANSI_G:
            return KEY_G;
        case kVK_ANSI_H:
            return KEY_H;
        case kVK_ANSI_I:
            return KEY_I;
        case kVK_ANSI_J:
            return KEY_J;
        case kVK_ANSI_K:
            return KEY_K;
        case kVK_ANSI_L:
            return KEY_L;
        case kVK_ANSI_M:
            return KEY_M;
        case kVK_ANSI_N:
            return KEY_N;
        case kVK_ANSI_O:
            return KEY_O;
        case kVK_ANSI_P:
            return KEY_P;
        case kVK_ANSI_Q:
            return KEY_Q;
        case kVK_ANSI_R:
            return KEY_R;
        case kVK_ANSI_S:
            return KEY_S;
        case kVK_ANSI_T:
            return KEY_T;
        case kVK_ANSI_U:
            return KEY_U;
        case kVK_ANSI_V:
            return KEY_V;
        case kVK_ANSI_W:
            return KEY_W;
        case kVK_ANSI_X:
            return KEY_X;
        case kVK_ANSI_Y:
            return KEY_Y;
        case kVK_ANSI_Z:
            return KEY_Z;

        case kVK_ANSI_1:
            return KEY_NUM1;
        case kVK_ANSI_2:
            return KEY_NUM2;
        case kVK_ANSI_3:
            return KEY_NUM3;
        case kVK_ANSI_4:
            return KEY_NUM4;
        case kVK_ANSI_5:
            return KEY_NUM5;
        case kVK_ANSI_6:
            return KEY_NUM6;
        case kVK_ANSI_7:
            return KEY_NUM7;
        case kVK_ANSI_8:
            return KEY_NUM8;
        case kVK_ANSI_9:
            return KEY_NUM9;
        case kVK_ANSI_0:
            return KEY_NUM0;
    }

    return Key(0);
}

static void AddNSKeyStateToEvent(Event *event, NSEventModifierFlags state)
{
    event->Key.Shift   = state & NSShiftKeyMask;
    event->Key.Control = state & NSControlKeyMask;
    event->Key.Alt     = state & NSAlternateKeyMask;
    event->Key.System  = state & NSCommandKeyMask;
}

static MouseButton TranslateMouseButton(NSInteger button)
{
    switch (button)
    {
        case 2:
            return MOUSEBUTTON_MIDDLE;
        case 3:
            return MOUSEBUTTON_BUTTON4;
        case 4:
            return MOUSEBUTTON_BUTTON5;
        default:
            return MOUSEBUTTON_UNKNOWN;
    }
}

// Delegate for NSView events, mostly the input events
@implementation ContentView
- (id)initWithWindow:(OSXWindow *)window
{
    self = [super init];
    if (self != nil)
    {
        mWindow          = window;
        mTrackingArea    = nil;
        mCurrentModifier = 0;
        [self updateTrackingAreas];
    }
    return self;
}

- (void)dealloc
{
    [mTrackingArea release];
    [super dealloc];
}

- (void)updateTrackingAreas
{
    if (mTrackingArea != nil)
    {
        [self removeTrackingArea:mTrackingArea];
        [mTrackingArea release];
        mTrackingArea = nil;
    }

    NSRect bounds               = [self bounds];
    NSTrackingAreaOptions flags = NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow |
                                  NSTrackingCursorUpdate | NSTrackingInVisibleRect |
                                  NSTrackingAssumeInside;
    mTrackingArea = [[NSTrackingArea alloc] initWithRect:bounds
                                                 options:flags
                                                   owner:self
                                                userInfo:nil];

    [self addTrackingArea:mTrackingArea];
    [super updateTrackingAreas];
}

// Helps with performance
- (BOOL)isOpaque
{
    return YES;
}

- (BOOL)canBecomeKeyView
{
    return YES;
}

- (BOOL)acceptsFirstResponder
{
    return YES;
}

// Handle mouse events from the NSResponder protocol
- (float)translateMouseY:(float)y
{
    return [self frame].size.height - y;
}

- (void)addButtonEvent:(NSEvent *)nsEvent
                  type:(Event::EventType)eventType
                button:(MouseButton)button
{
    Event event;
    event.Type               = eventType;
    event.MouseButton.Button = button;
    event.MouseButton.X      = (int)[nsEvent locationInWindow].x;
    event.MouseButton.Y      = (int)[self translateMouseY:[nsEvent locationInWindow].y];
    mWindow->pushEvent(event);
}

- (void)mouseDown:(NSEvent *)event
{
    [self addButtonEvent:event type:Event::EVENT_MOUSE_BUTTON_PRESSED button:MOUSEBUTTON_LEFT];
}

- (void)mouseDragged:(NSEvent *)event
{
    [self mouseMoved:event];
}

- (void)mouseUp:(NSEvent *)event
{
    [self addButtonEvent:event type:Event::EVENT_MOUSE_BUTTON_RELEASED button:MOUSEBUTTON_LEFT];
}

- (void)mouseMoved:(NSEvent *)nsEvent
{
    Event event;
    event.Type        = Event::EVENT_MOUSE_MOVED;
    event.MouseMove.X = (int)[nsEvent locationInWindow].x;
    event.MouseMove.Y = (int)[self translateMouseY:[nsEvent locationInWindow].y];
    mWindow->pushEvent(event);
}

- (void)mouseEntered:(NSEvent *)nsEvent
{
    Event event;
    event.Type = Event::EVENT_MOUSE_ENTERED;
    mWindow->pushEvent(event);
}

- (void)mouseExited:(NSEvent *)nsEvent
{
    Event event;
    event.Type = Event::EVENT_MOUSE_LEFT;
    mWindow->pushEvent(event);
}

- (void)rightMouseDown:(NSEvent *)event
{
    [self addButtonEvent:event type:Event::EVENT_MOUSE_BUTTON_PRESSED button:MOUSEBUTTON_RIGHT];
}

- (void)rightMouseDragged:(NSEvent *)event
{
    [self mouseMoved:event];
}

- (void)rightMouseUp:(NSEvent *)event
{
    [self addButtonEvent:event type:Event::EVENT_MOUSE_BUTTON_RELEASED button:MOUSEBUTTON_RIGHT];
}

- (void)otherMouseDown:(NSEvent *)event
{
    [self addButtonEvent:event
                    type:Event::EVENT_MOUSE_BUTTON_PRESSED
                  button:TranslateMouseButton([event buttonNumber])];
}

- (void)otherMouseDragged:(NSEvent *)event
{
    [self mouseMoved:event];
}

- (void)otherMouseUp:(NSEvent *)event
{
    [self addButtonEvent:event
                    type:Event::EVENT_MOUSE_BUTTON_RELEASED
                  button:TranslateMouseButton([event buttonNumber])];
}

- (void)scrollWheel:(NSEvent *)nsEvent
{
    if (static_cast<int>([nsEvent deltaY]) == 0)
    {
        return;
    }

    Event event;
    event.Type             = Event::EVENT_MOUSE_WHEEL_MOVED;
    event.MouseWheel.Delta = (int)[nsEvent deltaY];
    mWindow->pushEvent(event);
}

// Handle key events from the NSResponder protocol
- (void)keyDown:(NSEvent *)nsEvent
{
    // TODO(cwallez) also send text events
    Event event;
    event.Type     = Event::EVENT_KEY_PRESSED;
    event.Key.Code = NSCodeToKey([nsEvent keyCode]);
    AddNSKeyStateToEvent(&event, [nsEvent modifierFlags]);
    mWindow->pushEvent(event);
}

- (void)keyUp:(NSEvent *)nsEvent
{
    Event event;
    event.Type     = Event::EVENT_KEY_RELEASED;
    event.Key.Code = NSCodeToKey([nsEvent keyCode]);
    AddNSKeyStateToEvent(&event, [nsEvent modifierFlags]);
    mWindow->pushEvent(event);
}

// Modifier keys do not trigger keyUp/Down events but only flagsChanged events.
- (void)flagsChanged:(NSEvent *)nsEvent
{
    Event event;

    // Guess if the key has been pressed or released with the change of modifiers
    // It currently doesn't work when modifiers are unchanged, such as when pressing
    // both shift keys. GLFW has a solution for this but it requires tracking the
    // state of the keys. Implementing this is still TODO(cwallez)
    int modifier = [nsEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask;
    if (modifier < mCurrentModifier)
    {
        event.Type = Event::EVENT_KEY_RELEASED;
    }
    else
    {
        event.Type = Event::EVENT_KEY_PRESSED;
    }
    mCurrentModifier = modifier;

    event.Key.Code = NSCodeToKey([nsEvent keyCode]);
    AddNSKeyStateToEvent(&event, [nsEvent modifierFlags]);
    mWindow->pushEvent(event);
}
@end

OSXWindow::OSXWindow() : mWindow(nil), mDelegate(nil), mView(nil) {}

OSXWindow::~OSXWindow()
{
    destroy();
}

bool OSXWindow::initialize(const std::string &name, int width, int height)
{
    if (!InitializeAppKit())
    {
        return false;
    }

    unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask |
                             NSMiniaturizableWindowMask;
    mWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, width, height)
                                          styleMask:styleMask
                                            backing:NSBackingStoreBuffered
                                              defer:NO];

    if (mWindow == nil)
    {
        return false;
    }

    mDelegate = [[WindowDelegate alloc] initWithWindow:this];
    if (mDelegate == nil)
    {
        return false;
    }
    [mWindow setDelegate:static_cast<id>(mDelegate)];

    mView = [[ContentView alloc] initWithWindow:this];
    if (mView == nil)
    {
        return false;
    }
    [mView setWantsLayer:YES];

    // Disable scaling for this view. If scaling is enabled, the metal backend's
    // frame buffer's size will be this window's size multiplied by contentScale.
    // It will cause inconsistent testing & example apps' results.
    mView.layer.contentsScale = 1;

    [mWindow setContentView:mView];
    [mWindow setTitle:[NSString stringWithUTF8String:name.c_str()]];
    [mWindow setAcceptsMouseMovedEvents:YES];
    [mWindow center];

    [NSApp activateIgnoringOtherApps:YES];

    mX      = 0;
    mY      = 0;
    mWidth  = width;
    mHeight = height;

    AllWindows().insert(this);
    return true;
}

void OSXWindow::destroy()
{
    AllWindows().erase(this);

    [mView release];
    mView = nil;
    [mDelegate onOSXWindowDeleted];
    [mDelegate release];
    mDelegate = nil;
    [mWindow release];
    mWindow = nil;
}

void OSXWindow::resetNativeWindow() {}

EGLNativeWindowType OSXWindow::getNativeWindow() const
{
    return [mView layer];
}

EGLNativeDisplayType OSXWindow::getNativeDisplay() const
{
    // TODO(cwallez): implement it once we have defined what EGLNativeDisplayType is
    return static_cast<EGLNativeDisplayType>(0);
}

void OSXWindow::messageLoop()
{
    @autoreleasepool
    {
        while (true)
        {
            NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask
                                                untilDate:[NSDate distantPast]
                                                   inMode:NSDefaultRunLoopMode
                                                  dequeue:YES];
            if (event == nil)
            {
                break;
            }

            if ([event type] == NSAppKitDefined)
            {
                continue;
            }
            [NSApp sendEvent:event];
        }
    }
}

void OSXWindow::setMousePosition(int x, int y)
{
    y = (int)([mWindow frame].size.height) - y - 1;
    NSPoint screenspace;

#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
    screenspace = [mWindow convertBaseToScreen:NSMakePoint(x, y)];
#else
    screenspace = [mWindow convertRectToScreen:NSMakeRect(x, y, 0, 0)].origin;
#endif
    CGWarpMouseCursorPosition(CGPointMake(screenspace.x, YCoordToFromCG(screenspace.y)));
}

bool OSXWindow::setPosition(int x, int y)
{
    // Given CG and NS's coordinate system, the "Y" position of a window is the Y coordinate
    // of the bottom of the window.
    int newBottom    = (int)([mWindow frame].size.height) + y;
    NSRect emptyRect = NSMakeRect(x, YCoordToFromCG(newBottom), 0, 0);
    [mWindow setFrameOrigin:[mWindow frameRectForContentRect:emptyRect].origin];
    return true;
}

bool OSXWindow::resize(int width, int height)
{
    [mWindow setContentSize:NSMakeSize(width, height)];
    return true;
}

void OSXWindow::setVisible(bool isVisible)
{
    if (isVisible)
    {
        [mWindow makeKeyAndOrderFront:nil];
    }
    else
    {
        [mWindow orderOut:nil];
    }
}

void OSXWindow::signalTestEvent()
{
    @autoreleasepool
    {
        NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined
                                            location:NSMakePoint(0, 0)
                                       modifierFlags:0
                                           timestamp:0.0
                                        windowNumber:[mWindow windowNumber]
                                             context:nil
                                             subtype:0
                                               data1:0
                                               data2:0];
        [NSApp postEvent:event atStart:YES];
    }
}

NSWindow *OSXWindow::getNSWindow() const
{
    return mWindow;
}

// static
OSWindow *OSWindow::New()
{
    return new OSXWindow;
}
