
/*
 * 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,
                      kPMColor_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
