//
// Copyright (c) 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 "osx/OSXWindow.h"

#include <set>
// Include Carbon to use the keycode names in Carbon's Event.h
#include <Carbon/Carbon.h>
#include <QuartzCore/CAMetalLayer.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*> gAllWindows;

@interface Application : NSApplication
@end

@implementation Application
    - (void) sendEvent: (NSEvent*) nsEvent
    {
        if ([nsEvent type] == NSApplicationDefined)
        {
            for (auto window : gAllWindows)
            {
                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 : gAllWindows)
        {
            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 = windowSize.width;
        event.size.height = windowSize.height;
        mWindow->pushEvent(event);
    }

    - (void) windowDidMove: (NSNotification*) notification
    {
        NSRect screenspace = [mWindow->getNSWindow() frame];
        Event event;
        event.type = Event::EVENT_MOVED;
        event.move.x = screenspace.origin.x;
        event.move.y = 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, int state)
{
    event->key.shift = state & NSShiftKeyMask;
    event->key.control = state & NSControlKeyMask;
    event->key.alt = state & NSAlternateKeyMask;
    event->key.system = state & NSCommandKeyMask;
}

static MouseButton TranslateMouseButton(int 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 = [nsEvent locationInWindow].x;
        event.mouseButton.y = [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 = [nsEvent locationInWindow].x;
        event.mouseMove.y = [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 = [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, size_t width, size_t 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;
    }

    mLayer = [CAMetalLayer layer];
    [mView setLayer:mLayer];
    [mView setWantsLayer:YES];

    [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;

    gAllWindows.insert(this);
    return true;
}

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

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

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::getFramebufferNativeWindow() const
{
    return static_cast<void*>(mWindow);
}

float OSXWindow::getDevicePixelRatio() const
{
    return [[NSScreen mainScreen] backingScaleFactor];
}

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 = [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 = [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;
}

OSWindow *CreateOSWindow()
{
    return new OSXWindow;
}
