
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#import "SkNSView.h"
#include "SkCanvas.h"
#include "SkCGUtils.h"
#include "SkEvent.h"
SK_COMPILE_ASSERT(SK_SUPPORT_GPU, not_implemented_for_non_gpu_build);
#include <OpenGL/gl.h>

//#define FORCE_REDRAW
// Can be dropped when we no longer support 10.6.
#define RETINA_API_AVAILABLE (defined(MAC_OS_X_VERSION_10_7) && \
                              MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
@implementation SkNSView
@synthesize fWind, fTitle, fOptionsDelegate, fGLContext;

- (id)initWithCoder:(NSCoder*)coder {
    if ((self = [super initWithCoder:coder])) {
        self = [self initWithDefaults];
        [self setUpWindow];
    }
    return self;
}

- (id)initWithFrame:(NSRect)frameRect {
    if ((self = [super initWithFrame:frameRect])) {
        self = [self initWithDefaults];
        [self setUpWindow];
    }
    return self;
}

- (id)initWithDefaults {
#if RETINA_API_AVAILABLE
    [self setWantsBestResolutionOpenGLSurface:YES];
#endif
    fRedrawRequestPending = false;
    fWind = NULL;
    return self;
}

- (void)setUpWindow {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(backingPropertiesChanged:)
                                          name:@"NSWindowDidChangeBackingPropertiesNotification"
                                          object:[self window]];
    if (NULL != fWind) {
        fWind->setVisibleP(true);
        NSSize size = self.frame.size;
#if RETINA_API_AVAILABLE
        size = [self convertSizeToBacking:self.frame.size];
#endif
        fWind->resize((int) size.width, (int) size.height,
                      kN32_SkColorType);
    }
}

-(BOOL) isFlipped {
    return YES;
}

- (BOOL)acceptsFirstResponder {
    return YES;
}

- (float)scaleFactor {
    NSWindow *window = [self window];
#if RETINA_API_AVAILABLE
    if (window) {
        return [window backingScaleFactor];
    }
    return [[NSScreen mainScreen] backingScaleFactor];
#else
    if (window) {
        return [window userSpaceScaleFactor];
    }
    return [[NSScreen mainScreen] userSpaceScaleFactor];
#endif
}

- (void)backingPropertiesChanged:(NSNotification *)notification {
    CGFloat oldBackingScaleFactor = (CGFloat)[
        [notification.userInfo objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue
    ];
    CGFloat newBackingScaleFactor = [self scaleFactor];
    if (oldBackingScaleFactor == newBackingScaleFactor) {
        return;
    }
    
    // TODO: need a better way to force a refresh (that works).
    // [fGLContext update] does not appear to update if the point size has not changed,
    // even if the backing size has changed.
    [self setFrameSize:NSMakeSize(self.frame.size.width + 1, self.frame.size.height + 1)];
}

- (void)resizeSkView:(NSSize)newSize {
#if RETINA_API_AVAILABLE
    newSize = [self convertSizeToBacking:newSize];
#endif
    if (NULL != fWind &&
            (fWind->width()  != newSize.width ||
             fWind->height() != newSize.height))
    {
        fWind->resize((int) newSize.width, (int) newSize.height);
        if (NULL != fGLContext) {
            glClear(GL_STENCIL_BUFFER_BIT);
            [fGLContext update];
        }
    }
}

- (void) setFrameSize:(NSSize)newSize {
    [super setFrameSize:newSize];
    [self resizeSkView:newSize];
}

- (void)dealloc {
    delete fWind;
    self.fGLContext = nil;
    self.fTitle = nil;
    [super dealloc];
}

////////////////////////////////////////////////////////////////////////////////

- (void)drawSkia {
    fRedrawRequestPending = false;
    if (NULL != fWind) {
        SkAutoTUnref<SkCanvas> canvas(fWind->createCanvas());
        fWind->draw(canvas);
#ifdef FORCE_REDRAW
        fWind->inval(NULL);
#endif
    }
}

- (void)setSkTitle:(const char *)title {
    self.fTitle = [NSString stringWithUTF8String:title];
    [[self window] setTitle:self.fTitle];
}

- (BOOL)onHandleEvent:(const SkEvent&)evt {
    return false;
}

#include "SkOSMenu.h"
- (void)onAddMenu:(const SkOSMenu*)menu {
    [self.fOptionsDelegate view:self didAddMenu:menu];
}

- (void)onUpdateMenu:(const SkOSMenu*)menu {
    [self.fOptionsDelegate view:self didUpdateMenu:menu];
}

- (void)postInvalWithRect:(const SkIRect*)r {
    if (!fRedrawRequestPending) {
        fRedrawRequestPending = true;
        [self setNeedsDisplay:YES];
        [self performSelector:@selector(drawSkia) withObject:nil afterDelay:0];
    }
}
///////////////////////////////////////////////////////////////////////////////

#include "SkKey.h"
enum {
	SK_MacReturnKey		= 36,
	SK_MacDeleteKey		= 51,
	SK_MacEndKey		= 119,
	SK_MacLeftKey		= 123,
	SK_MacRightKey		= 124,
	SK_MacDownKey		= 125,
	SK_MacUpKey			= 126,
    SK_Mac0Key          = 0x52,
    SK_Mac1Key          = 0x53,
    SK_Mac2Key          = 0x54,
    SK_Mac3Key          = 0x55,
    SK_Mac4Key          = 0x56,
    SK_Mac5Key          = 0x57,
    SK_Mac6Key          = 0x58,
    SK_Mac7Key          = 0x59,
    SK_Mac8Key          = 0x5b,
    SK_Mac9Key          = 0x5c
};

static SkKey raw2key(UInt32 raw)
{
	static const struct {
		UInt32  fRaw;
		SkKey   fKey;
	} gKeys[] = {
		{ SK_MacUpKey,		kUp_SkKey		},
		{ SK_MacDownKey,	kDown_SkKey		},
		{ SK_MacLeftKey,	kLeft_SkKey		},
		{ SK_MacRightKey,   kRight_SkKey	},
		{ SK_MacReturnKey,  kOK_SkKey		},
		{ SK_MacDeleteKey,  kBack_SkKey		},
		{ SK_MacEndKey,		kEnd_SkKey		},
        { SK_Mac0Key,       k0_SkKey        },
        { SK_Mac1Key,       k1_SkKey        },
        { SK_Mac2Key,       k2_SkKey        },
        { SK_Mac3Key,       k3_SkKey        },
        { SK_Mac4Key,       k4_SkKey        },
        { SK_Mac5Key,       k5_SkKey        },
        { SK_Mac6Key,       k6_SkKey        },
        { SK_Mac7Key,       k7_SkKey        },
        { SK_Mac8Key,       k8_SkKey        },
        { SK_Mac9Key,       k9_SkKey        }
	};
    
	for (unsigned i = 0; i < SK_ARRAY_COUNT(gKeys); i++)
		if (gKeys[i].fRaw == raw)
			return gKeys[i].fKey;
	return kNONE_SkKey;
}

- (void)keyDown:(NSEvent *)event {
    if (NULL == fWind)
        return;
    
    SkKey key = raw2key([event keyCode]);
    if (kNONE_SkKey != key)
        fWind->handleKey(key);
    else{
        unichar c = [[event characters] characterAtIndex:0];
        fWind->handleChar((SkUnichar)c);
    }
}

- (void)keyUp:(NSEvent *)event {
    if (NULL == fWind)
        return;
    
    SkKey key = raw2key([event keyCode]);
    if (kNONE_SkKey != key)
        fWind->handleKeyUp(key);
 // else
 //     unichar c = [[event characters] characterAtIndex:0];
}

static const struct {
    unsigned    fNSModifierMask;
    unsigned    fSkModifierMask;
} gModifierMasks[] = {
    { NSAlphaShiftKeyMask,  kShift_SkModifierKey },
    { NSShiftKeyMask,       kShift_SkModifierKey },
    { NSControlKeyMask,     kControl_SkModifierKey },
    { NSAlternateKeyMask,   kOption_SkModifierKey },
    { NSCommandKeyMask,     kCommand_SkModifierKey },
};

static unsigned convertNSModifiersToSk(NSUInteger nsModi) {
    unsigned skModi = 0;
    for (size_t i = 0; i < SK_ARRAY_COUNT(gModifierMasks); ++i) {
        if (nsModi & gModifierMasks[i].fNSModifierMask) {
            skModi |= gModifierMasks[i].fSkModifierMask;
        }
    }
    return skModi;
}

- (void)mouseDown:(NSEvent *)event {
    NSPoint p = [event locationInWindow];
    unsigned modi = convertNSModifiersToSk([event modifierFlags]);

    if ([self mouse:p inRect:[self bounds]] && NULL != fWind) {
        NSPoint loc = [self convertPoint:p fromView:nil];
#if RETINA_API_AVAILABLE
        loc = [self convertPointToBacking:loc]; //y-up
        loc.y = -loc.y;
#endif
        fWind->handleClick((int) loc.x, (int) loc.y,
                           SkView::Click::kDown_State, self, modi);
    }
}

- (void)mouseDragged:(NSEvent *)event {
    NSPoint p = [event locationInWindow];
    unsigned modi = convertNSModifiersToSk([event modifierFlags]);

    if ([self mouse:p inRect:[self bounds]] && NULL != fWind) {
        NSPoint loc = [self convertPoint:p fromView:nil];
#if RETINA_API_AVAILABLE
        loc = [self convertPointToBacking:loc]; //y-up
        loc.y = -loc.y;
#endif
        fWind->handleClick((int) loc.x, (int) loc.y,
                           SkView::Click::kMoved_State, self, modi);
    }
}

- (void)mouseMoved:(NSEvent *)event {
    NSPoint p = [event locationInWindow];
    unsigned modi = convertNSModifiersToSk([event modifierFlags]);
    
    if ([self mouse:p inRect:[self bounds]] && NULL != fWind) {
        NSPoint loc = [self convertPoint:p fromView:nil];
#if RETINA_API_AVAILABLE
        loc = [self convertPointToBacking:loc]; //y-up
        loc.y = -loc.y;
#endif
        fWind->handleClick((int) loc.x, (int) loc.y,
                           SkView::Click::kMoved_State, self, modi);
    }
}

- (void)mouseUp:(NSEvent *)event {
    NSPoint p = [event locationInWindow];
    unsigned modi = convertNSModifiersToSk([event modifierFlags]);
    
    if ([self mouse:p inRect:[self bounds]] && NULL != fWind) {
        NSPoint loc = [self convertPoint:p fromView:nil];
#if RETINA_API_AVAILABLE
        loc = [self convertPointToBacking:loc]; //y-up
        loc.y = -loc.y;
#endif
        fWind->handleClick((int) loc.x, (int) loc.y,
                           SkView::Click::kUp_State, self, modi);
    }
}

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

namespace { 
CGLContextObj createGLContext(int msaaSampleCount) {
    GLint major, minor;
    CGLGetVersion(&major, &minor);
    
    static const CGLPixelFormatAttribute attributes[] = {
        kCGLPFAStencilSize, (CGLPixelFormatAttribute) 8,
        kCGLPFAAccelerated,
        kCGLPFADoubleBuffer,
        (CGLPixelFormatAttribute)0
    };
    
    CGLPixelFormatObj format;
    GLint npix = 0;
    if (msaaSampleCount > 0) {
        static int kAttributeCount = SK_ARRAY_COUNT(attributes);
        CGLPixelFormatAttribute msaaAttributes[kAttributeCount + 5];
        memcpy(msaaAttributes, attributes, sizeof(attributes));
        SkASSERT(0 == msaaAttributes[kAttributeCount - 1]);
        msaaAttributes[kAttributeCount - 1] = kCGLPFASampleBuffers;
        msaaAttributes[kAttributeCount + 0] = (CGLPixelFormatAttribute)1;
        msaaAttributes[kAttributeCount + 1] = kCGLPFAMultisample;
        msaaAttributes[kAttributeCount + 2] = kCGLPFASamples;
        msaaAttributes[kAttributeCount + 3] =
                                    (CGLPixelFormatAttribute)msaaSampleCount;
        msaaAttributes[kAttributeCount + 4] = (CGLPixelFormatAttribute)0;
        CGLChoosePixelFormat(msaaAttributes, &format, &npix);
    }
    if (!npix) {
        CGLChoosePixelFormat(attributes, &format, &npix);
    }
    CGLContextObj ctx;
    CGLCreateContext(format, NULL, &ctx);
    CGLDestroyPixelFormat(format);
    
    static const GLint interval = 1;
    CGLSetParameter(ctx, kCGLCPSwapInterval, &interval);
    CGLSetCurrentContext(ctx);
    return ctx;
}
}

- (void)viewDidMoveToWindow {
    [super viewDidMoveToWindow];
    
    //Attaching view to fGLContext requires that the view to be part of a window,
    //and that the NSWindow instance must have a CoreGraphics counterpart (or 
    //it must NOT be deferred or should have been on screen at least once)
    if ([fGLContext view] != self && nil != self.window) {
        [fGLContext setView:self];
    }
}
- (bool)attach:(SkOSWindow::SkBackEndTypes)attachType
        withMSAASampleCount:(int) sampleCount
        andGetInfo:(SkOSWindow::AttachmentInfo*) info {
    if (nil == fGLContext) {
        CGLContextObj ctx = createGLContext(sampleCount);
        fGLContext = [[NSOpenGLContext alloc] initWithCGLContextObj:ctx];
        CGLReleaseContext(ctx);
        if (NULL == fGLContext) {
            return false;
        }
        [fGLContext setView:self];
    }

    [fGLContext makeCurrentContext];
    CGLPixelFormatObj format = CGLGetPixelFormat((CGLContextObj)[fGLContext CGLContextObj]);
    CGLDescribePixelFormat(format, 0, kCGLPFASamples, &info->fSampleCount);
    CGLDescribePixelFormat(format, 0, kCGLPFAStencilSize, &info->fStencilBits);
    NSSize size = self.bounds.size;
#if RETINA_API_AVAILABLE
    size = [self convertSizeToBacking:size];
#endif
    glViewport(0, 0, (int) size.width, (int) size.height);
    glClearColor(0, 0, 0, 0);
    glClearStencil(0);
    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    return true;
}

- (void)detach {
    [fGLContext release];
    fGLContext = nil;
}

- (void)present {
    if (nil != fGLContext) {
        [fGLContext flushBuffer];
    }
}
@end
