/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

/* NSOpenGL implementation of SDL OpenGL support */

#if SDL_VIDEO_OPENGL_CGL
#include "SDL_cocoavideo.h"
#include "SDL_cocoaopengl.h"
#include "SDL_cocoaopengles.h"

#include <OpenGL/CGLTypes.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/CGLRenderers.h>

#include "SDL_loadso.h"
#include "SDL_opengl.h"

#define DEFAULT_OPENGL  "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"

/* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif

@implementation SDLOpenGLContext : NSOpenGLContext

- (id)initWithFormat:(NSOpenGLPixelFormat *)format
        shareContext:(NSOpenGLContext *)share
{
    self = [super initWithFormat:format shareContext:share];
    if (self) {
        SDL_AtomicSet(&self->dirty, 0);
        self->window = NULL;
    }
    return self;
}

- (void)scheduleUpdate
{
    SDL_AtomicAdd(&self->dirty, 1);
}

/* This should only be called on the thread on which a user is using the context. */
- (void)updateIfNeeded
{
    const int value = SDL_AtomicSet(&self->dirty, 0);
    if (value > 0) {
        /* We call the real underlying update here, since -[SDLOpenGLContext update] just calls us. */
        [self explicitUpdate];
    }
}

/* This should only be called on the thread on which a user is using the context. */
- (void)update
{
    /* This ensures that regular 'update' calls clear the atomic dirty flag. */
    [self scheduleUpdate];
    [self updateIfNeeded];
}

/* Updates the drawable for the contexts and manages related state. */
- (void)setWindow:(SDL_Window *)newWindow
{
    if (self->window) {
        SDL_WindowData *oldwindowdata = (SDL_WindowData *)self->window->driverdata;

        /* Make sure to remove us from the old window's context list, or we'll get scheduled updates from it too. */
        NSMutableArray *contexts = oldwindowdata->nscontexts;
        @synchronized (contexts) {
            [contexts removeObject:self];
        }
    }

    self->window = newWindow;

    if (newWindow) {
        SDL_WindowData *windowdata = (SDL_WindowData *)newWindow->driverdata;
        NSView *contentview = windowdata->sdlContentView;

        /* Now sign up for scheduled updates for the new window. */
        NSMutableArray *contexts = windowdata->nscontexts;
        @synchronized (contexts) {
            [contexts addObject:self];
        }

        if ([self view] != contentview) {
            if ([NSThread isMainThread]) {
                [self setView:contentview];
            } else {
                dispatch_sync(dispatch_get_main_queue(), ^{ [self setView:contentview]; });
            }
            if (self == [NSOpenGLContext currentContext]) {
                [self explicitUpdate];
            } else {
                [self scheduleUpdate];
            }
        }
    } else {
        [self clearDrawable];
        if (self == [NSOpenGLContext currentContext]) {
            [self explicitUpdate];
        } else {
            [self scheduleUpdate];
        }
    }
}

- (SDL_Window*)window
{
    return self->window;
}

- (void)explicitUpdate
{
    if ([NSThread isMainThread]) {
        [super update];
    } else {
        dispatch_async(dispatch_get_main_queue(), ^{ [super update]; });
    }
}

@end


int
Cocoa_GL_LoadLibrary(_THIS, const char *path)
{
    /* Load the OpenGL library */
    if (path == NULL) {
        path = SDL_getenv("SDL_OPENGL_LIBRARY");
    }
    if (path == NULL) {
        path = DEFAULT_OPENGL;
    }
    _this->gl_config.dll_handle = SDL_LoadObject(path);
    if (!_this->gl_config.dll_handle) {
        return -1;
    }
    SDL_strlcpy(_this->gl_config.driver_path, path,
                SDL_arraysize(_this->gl_config.driver_path));
    return 0;
}

void *
Cocoa_GL_GetProcAddress(_THIS, const char *proc)
{
    return SDL_LoadFunction(_this->gl_config.dll_handle, proc);
}

void
Cocoa_GL_UnloadLibrary(_THIS)
{
    SDL_UnloadObject(_this->gl_config.dll_handle);
    _this->gl_config.dll_handle = NULL;
}

SDL_GLContext
Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
{ @autoreleasepool
{
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
    SDL_bool lion_or_later = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
    NSOpenGLPixelFormatAttribute attr[32];
    NSOpenGLPixelFormat *fmt;
    SDLOpenGLContext *context;
    NSOpenGLContext *share_context = nil;
    int i = 0;
    const char *glversion;
    int glversion_major;
    int glversion_minor;

    if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
#if SDL_VIDEO_OPENGL_EGL
        /* Switch to EGL based functions */
        Cocoa_GL_UnloadLibrary(_this);
        _this->GL_LoadLibrary = Cocoa_GLES_LoadLibrary;
        _this->GL_GetProcAddress = Cocoa_GLES_GetProcAddress;
        _this->GL_UnloadLibrary = Cocoa_GLES_UnloadLibrary;
        _this->GL_CreateContext = Cocoa_GLES_CreateContext;
        _this->GL_MakeCurrent = Cocoa_GLES_MakeCurrent;
        _this->GL_SetSwapInterval = Cocoa_GLES_SetSwapInterval;
        _this->GL_GetSwapInterval = Cocoa_GLES_GetSwapInterval;
        _this->GL_SwapWindow = Cocoa_GLES_SwapWindow;
        _this->GL_DeleteContext = Cocoa_GLES_DeleteContext;
        
        if (Cocoa_GLES_LoadLibrary(_this, NULL) != 0) {
            return NULL;
        }
        return Cocoa_GLES_CreateContext(_this, window);
#else
        SDL_SetError("SDL not configured with EGL support");
        return NULL;
#endif
    }
    if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) && !lion_or_later) {
        SDL_SetError ("OpenGL Core Profile is not supported on this platform version");
        return NULL;
    }

    attr[i++] = NSOpenGLPFAAllowOfflineRenderers;

    /* specify a profile if we're on Lion (10.7) or later. */
    if (lion_or_later) {
        NSOpenGLPixelFormatAttribute profile = NSOpenGLProfileVersionLegacy;
        if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) {
            profile = NSOpenGLProfileVersion3_2Core;
        }
        attr[i++] = NSOpenGLPFAOpenGLProfile;
        attr[i++] = profile;
    }

    attr[i++] = NSOpenGLPFAColorSize;
    attr[i++] = SDL_BYTESPERPIXEL(display->current_mode.format)*8;

    attr[i++] = NSOpenGLPFADepthSize;
    attr[i++] = _this->gl_config.depth_size;

    if (_this->gl_config.double_buffer) {
        attr[i++] = NSOpenGLPFADoubleBuffer;
    }

    if (_this->gl_config.stereo) {
        attr[i++] = NSOpenGLPFAStereo;
    }

    if (_this->gl_config.stencil_size) {
        attr[i++] = NSOpenGLPFAStencilSize;
        attr[i++] = _this->gl_config.stencil_size;
    }

    if ((_this->gl_config.accum_red_size +
         _this->gl_config.accum_green_size +
         _this->gl_config.accum_blue_size +
         _this->gl_config.accum_alpha_size) > 0) {
        attr[i++] = NSOpenGLPFAAccumSize;
        attr[i++] = _this->gl_config.accum_red_size + _this->gl_config.accum_green_size + _this->gl_config.accum_blue_size + _this->gl_config.accum_alpha_size;
    }

    if (_this->gl_config.multisamplebuffers) {
        attr[i++] = NSOpenGLPFASampleBuffers;
        attr[i++] = _this->gl_config.multisamplebuffers;
    }

    if (_this->gl_config.multisamplesamples) {
        attr[i++] = NSOpenGLPFASamples;
        attr[i++] = _this->gl_config.multisamplesamples;
        attr[i++] = NSOpenGLPFANoRecovery;
    }

    if (_this->gl_config.accelerated >= 0) {
        if (_this->gl_config.accelerated) {
            attr[i++] = NSOpenGLPFAAccelerated;
        } else {
            attr[i++] = NSOpenGLPFARendererID;
            attr[i++] = kCGLRendererGenericFloatID;
        }
    }

    attr[i++] = NSOpenGLPFAScreenMask;
    attr[i++] = CGDisplayIDToOpenGLDisplayMask(displaydata->display);
    attr[i] = 0;

    fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
    if (fmt == nil) {
        SDL_SetError("Failed creating OpenGL pixel format");
        return NULL;
    }

    if (_this->gl_config.share_with_current_context) {
        share_context = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
    }

    context = [[SDLOpenGLContext alloc] initWithFormat:fmt shareContext:share_context];

    [fmt release];

    if (context == nil) {
        SDL_SetError("Failed creating OpenGL context");
        return NULL;
    }

    if ( Cocoa_GL_MakeCurrent(_this, window, context) < 0 ) {
        Cocoa_GL_DeleteContext(_this, context);
        SDL_SetError("Failed making OpenGL context current");
        return NULL;
    }

    if (_this->gl_config.major_version < 3 &&
        _this->gl_config.profile_mask == 0 &&
        _this->gl_config.flags == 0) {
        /* This is a legacy profile, so to match other backends, we're done. */
    } else {
        const GLubyte *(APIENTRY * glGetStringFunc)(GLenum);

        glGetStringFunc = (const GLubyte *(APIENTRY *)(GLenum)) SDL_GL_GetProcAddress("glGetString");
        if (!glGetStringFunc) {
            Cocoa_GL_DeleteContext(_this, context);
            SDL_SetError ("Failed getting OpenGL glGetString entry point");
            return NULL;
        }

        glversion = (const char *)glGetStringFunc(GL_VERSION);
        if (glversion == NULL) {
            Cocoa_GL_DeleteContext(_this, context);
            SDL_SetError ("Failed getting OpenGL context version");
            return NULL;
        }

        if (SDL_sscanf(glversion, "%d.%d", &glversion_major, &glversion_minor) != 2) {
            Cocoa_GL_DeleteContext(_this, context);
            SDL_SetError ("Failed parsing OpenGL context version");
            return NULL;
        }

        if ((glversion_major < _this->gl_config.major_version) ||
           ((glversion_major == _this->gl_config.major_version) && (glversion_minor < _this->gl_config.minor_version))) {
            Cocoa_GL_DeleteContext(_this, context);
            SDL_SetError ("Failed creating OpenGL context at version requested");
            return NULL;
        }

        /* In the future we'll want to do this, but to match other platforms
           we'll leave the OpenGL version the way it is for now
         */
        /*_this->gl_config.major_version = glversion_major;*/
        /*_this->gl_config.minor_version = glversion_minor;*/
    }
    return context;
}}

int
Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
{ @autoreleasepool
{
    if (context) {
        SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context;
        if ([nscontext window] != window) {
            [nscontext setWindow:window];
            [nscontext updateIfNeeded];
        }
        [nscontext makeCurrentContext];
    } else {
        [NSOpenGLContext clearCurrentContext];
    }

    return 0;
}}

void
Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
{
    SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
    NSView *contentView = windata->sdlContentView;
    NSRect viewport = [contentView bounds];

    if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
        /* This gives us the correct viewport for a Retina-enabled view, only
         * supported on 10.7+. */
        if ([contentView respondsToSelector:@selector(convertRectToBacking:)]) {
            viewport = [contentView convertRectToBacking:viewport];
        }
    }

    if (w) {
        *w = viewport.size.width;
    }

    if (h) {
        *h = viewport.size.height;
    }
}

int
Cocoa_GL_SetSwapInterval(_THIS, int interval)
{ @autoreleasepool
{
    NSOpenGLContext *nscontext;
    GLint value;
    int status;

    if (interval < 0) {  /* no extension for this on Mac OS X at the moment. */
        return SDL_SetError("Late swap tearing currently unsupported");
    }

    nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
    if (nscontext != nil) {
        value = interval;
        [nscontext setValues:&value forParameter:NSOpenGLCPSwapInterval];
        status = 0;
    } else {
        status = SDL_SetError("No current OpenGL context");
    }

    return status;
}}

int
Cocoa_GL_GetSwapInterval(_THIS)
{ @autoreleasepool
{
    NSOpenGLContext *nscontext;
    GLint value;
    int status = 0;

    nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
    if (nscontext != nil) {
        [nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
        status = (int)value;
    }

    return status;
}}

int
Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
{ @autoreleasepool
{
    SDLOpenGLContext* nscontext = (SDLOpenGLContext*)SDL_GL_GetCurrentContext();
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;

    /* on 10.14 ("Mojave") and later, this deadlocks if two contexts in two
       threads try to swap at the same time, so put a mutex around it. */
    SDL_LockMutex(videodata->swaplock);
    [nscontext flushBuffer];
    [nscontext updateIfNeeded];
    SDL_UnlockMutex(videodata->swaplock);
    return 0;
}}

void
Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context)
{ @autoreleasepool
{
    SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context;

    [nscontext setWindow:NULL];
    [nscontext release];
}}

/* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */
#ifdef __clang__
#pragma clang diagnostic pop
#endif

#endif /* SDL_VIDEO_OPENGL_CGL */

/* vi: set ts=4 sw=4 expandtab: */
