/*
 * MACDRV Cocoa OpenGL code
 *
 * Copyright 2012, 2013 Ken Thomases for CodeWeavers Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <OpenGL/gl.h>
#import "cocoa_opengl.h"

#include "macdrv_cocoa.h"
#include "cocoa_event.h"


@interface WineOpenGLContext ()
@property (retain, nonatomic) NSView* latentView;

    + (NSView*) dummyView;
    - (void) wine_updateBackingSize:(const CGSize*)size;

@end


@implementation WineOpenGLContext
@synthesize latentView, needsUpdate, needsReattach, shouldClearToBlack;

    - (void) dealloc
    {
        [[self view] release];
        [latentView release];
        [super dealloc];
    }

    + (NSView*) dummyView
    {
        static NSWindow* dummyWindow;
        static dispatch_once_t once;

        dispatch_once(&once, ^{
            OnMainThread(^{
                dummyWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
                                                          styleMask:NSBorderlessWindowMask
                                                            backing:NSBackingStoreBuffered
                                                              defer:NO];
            });
        });

        return dummyWindow.contentView;
    }

    // Normally, we take care that disconnecting a context from a view doesn't
    // destroy that view's GL surface (see -clearDrawableLeavingSurfaceOnScreen).
    // However, if we're using a surface backing size and that size changes, we
    // need to destroy and recreate the surface or we get weird behavior.
    - (void) resetSurfaceIfBackingSizeChanged
    {
        if (!retina_enabled)
            return;

        int view_backing[2];
        if (macdrv_get_view_backing_size((macdrv_view)self.view, view_backing) &&
            (view_backing[0] != backing_size[0] || view_backing[1] != backing_size[1]))
        {
            view_backing[0] = backing_size[0];
            view_backing[1] = backing_size[1];
            macdrv_set_view_backing_size((macdrv_view)self.view, view_backing);

            NSView* save = self.view;
            [super clearDrawable];
            [super setView:save];
            shouldClearToBlack = TRUE;
        }
    }

    - (void) wine_updateBackingSize:(const CGSize*)size
    {
        GLint enabled;

        if (!retina_enabled)
            return;

        if (size)
        {
            if (CGLIsEnabled(self.CGLContextObj, kCGLCESurfaceBackingSize, &enabled) != kCGLNoError)
                enabled = 0;

            if (!enabled || backing_size[0] != size->width || backing_size[1] != size->height)
            {
                backing_size[0] = size->width;
                backing_size[1] = size->height;
                CGLSetParameter(self.CGLContextObj, kCGLCPSurfaceBackingSize, backing_size);
            }

            if (!enabled)
                CGLEnable(self.CGLContextObj, kCGLCESurfaceBackingSize);

            [self resetSurfaceIfBackingSizeChanged];
        }
        else
        {
            backing_size[0] = 0;
            backing_size[1] = 0;

            if (CGLIsEnabled(self.CGLContextObj, kCGLCESurfaceBackingSize, &enabled) == kCGLNoError && enabled)
               CGLDisable(self.CGLContextObj, kCGLCESurfaceBackingSize);
        }
    }

    - (void) setView:(NSView*)newView
    {
        NSView* oldView = [self view];
        [super setView:newView];
        [newView retain];
        [oldView release];
    }

    - (void) clearDrawable
    {
        NSView* oldView = [self view];
        [super clearDrawable];
        [oldView release];

        [self wine_updateBackingSize:NULL];
    }

    /* On at least some versions of Mac OS X, -[NSOpenGLContext clearDrawable] has the
       undesirable side effect of ordering the view's GL surface off-screen.  This isn't
       done when just changing the context's view to a different view (which I would
       think would be analogous, since the old view and surface end up without a
       context attached).  So, we finesse things by first setting the context's view to
       a different view (the content view of an off-screen window) and then letting the
       original implementation proceed. */
    - (void) clearDrawableLeavingSurfaceOnScreen
    {
        [self setView:[[self class] dummyView]];
        [self clearDrawable];
    }

    - (void) clearToBlackIfNeeded
    {
        if (shouldClearToBlack)
        {
            NSOpenGLContext* origContext = [NSOpenGLContext currentContext];
            const char *gl_version;
            unsigned int major;
            GLint draw_framebuffer_binding, draw_buffer;
            GLboolean scissor_test, color_mask[4];
            GLfloat clear_color[4];

            [self makeCurrentContext];

            gl_version = (const char *)glGetString(GL_VERSION);
            major = gl_version[0] - '0';
            /* FIXME: Should check for GL_ARB_framebuffer_object and GL_EXT_framebuffer_object
             * for older GL versions. */
            if (major >= 3)
            {
                glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer_binding);
                glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
            }
            glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer);
            scissor_test = glIsEnabled(GL_SCISSOR_TEST);
            glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
            glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
            glDrawBuffer(GL_FRONT_AND_BACK);
            glDisable(GL_SCISSOR_TEST);
            glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
            glClearColor(0, 0, 0, gl_surface_mode == GL_SURFACE_IN_FRONT_TRANSPARENT ? 0 : 1);

            glClear(GL_COLOR_BUFFER_BIT);

            glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
            glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
            if (scissor_test)
                glEnable(GL_SCISSOR_TEST);
            glDrawBuffer(draw_buffer);
            if (major >= 3)
                glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw_framebuffer_binding);
            glFlush();

            if (origContext)
                [origContext makeCurrentContext];
            else
                [NSOpenGLContext clearCurrentContext];

            shouldClearToBlack = FALSE;
        }
    }

    - (void) removeFromViews:(BOOL)removeViews
    {
        if ([self view])
        {
            macdrv_remove_view_opengl_context((macdrv_view)[self view], (macdrv_opengl_context)self);
            if (removeViews)
                [self clearDrawableLeavingSurfaceOnScreen];
        }
        if ([self latentView])
        {
            macdrv_remove_view_opengl_context((macdrv_view)[self latentView], (macdrv_opengl_context)self);
            if (removeViews)
                [self setLatentView:nil];
        }
        needsUpdate = FALSE;
        needsReattach = FALSE;
    }

@end


/***********************************************************************
 *              macdrv_create_opengl_context
 *
 * Returns a Cocoa OpenGL context created from a CoreGL context.  The
 * caller is responsible for calling macdrv_dispose_opengl_context()
 * when done with the context object.
 */
macdrv_opengl_context macdrv_create_opengl_context(void* cglctx)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineOpenGLContext *context;

    context = [[WineOpenGLContext alloc] initWithCGLContextObj:cglctx];

    [pool release];
    return (macdrv_opengl_context)context;
}

/***********************************************************************
 *              macdrv_dispose_opengl_context
 *
 * Destroys a Cocoa OpenGL context previously created by
 * macdrv_create_opengl_context();
 */
void macdrv_dispose_opengl_context(macdrv_opengl_context c)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineOpenGLContext *context = (WineOpenGLContext*)c;

    [context removeFromViews:YES];
    [context release];

    [pool release];
}

/***********************************************************************
 *              macdrv_make_context_current
 */
void macdrv_make_context_current(macdrv_opengl_context c, macdrv_view v, CGRect r)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineOpenGLContext *context = (WineOpenGLContext*)c;
    NSView* view = (NSView*)v;

    if (context && view)
    {
        if (view == [context view] || view == [context latentView])
        {
            [context wine_updateBackingSize:&r.size];
            macdrv_update_opengl_context(c);
        }
        else
        {
            [context removeFromViews:NO];
            macdrv_add_view_opengl_context(v, c);

            if (context.needsUpdate)
            {
                context.needsUpdate = FALSE;
                context.needsReattach = FALSE;
                if (context.view)
                    [context setView:[[context class] dummyView]];
                [context wine_updateBackingSize:&r.size];
                [context setView:view];
                [context setLatentView:nil];
                [context resetSurfaceIfBackingSizeChanged];
            }
            else
            {
                if ([context view])
                    [context clearDrawableLeavingSurfaceOnScreen];
                [context wine_updateBackingSize:&r.size];
                [context setLatentView:view];
            }
        }

        [context makeCurrentContext];

        if ([context view])
            [context clearToBlackIfNeeded];
    }
    else
    {
        WineOpenGLContext* currentContext = (WineOpenGLContext*)[WineOpenGLContext currentContext];

        if ([currentContext isKindOfClass:[WineOpenGLContext class]])
        {
            [WineOpenGLContext clearCurrentContext];
            if (currentContext != context)
                [currentContext removeFromViews:YES];
        }

        if (context)
            [context removeFromViews:YES];
    }

    [pool release];
}

/***********************************************************************
 *              macdrv_update_opengl_context
 */
void macdrv_update_opengl_context(macdrv_opengl_context c)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineOpenGLContext *context = (WineOpenGLContext*)c;

    if (context.needsUpdate)
    {
        BOOL reattach = context.needsReattach;
        context.needsUpdate = FALSE;
        context.needsReattach = FALSE;
        if (context.latentView)
        {
            [context setView:context.latentView];
            context.latentView = nil;

            [context resetSurfaceIfBackingSizeChanged];
            [context clearToBlackIfNeeded];
        }
        else
        {
            if (reattach)
            {
                NSView* view = [[context.view retain] autorelease];
                [context clearDrawableLeavingSurfaceOnScreen];
                context.view = view;
            }
            else
                [context update];
            [context resetSurfaceIfBackingSizeChanged];
        }
    }

    [pool release];
}

/***********************************************************************
 *              macdrv_flush_opengl_context
 *
 * Performs an implicit glFlush() and then swaps the back buffer to the
 * front (if the context is double-buffered).
 */
void macdrv_flush_opengl_context(macdrv_opengl_context c)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    WineOpenGLContext *context = (WineOpenGLContext*)c;

    macdrv_update_opengl_context(c);
    [context flushBuffer];

    [pool release];
}
