/*
 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "config.h"
#import "WAKViewInternal.h"

#if PLATFORM(IOS_FAMILY)

#import "GraphicsContext.h"
#import "WAKClipView.h"
#import "WAKScrollView.h"
#import "WAKWindow.h"
#import "WKGraphics.h"
#import "WKUtilities.h"
#import "WKViewPrivate.h"
#import "WebCoreThreadMessage.h"
#import "WebEvent.h"
#import <wtf/Assertions.h>
#import <wtf/NeverDestroyed.h>

WEBCORE_EXPORT NSString *WAKViewFrameSizeDidChangeNotification =   @"WAKViewFrameSizeDidChangeNotification";
WEBCORE_EXPORT NSString *WAKViewDidScrollNotification =            @"WAKViewDidScrollNotification";

static RetainPtr<WAKView>& globalFocusView()
{
    static NeverDestroyed<RetainPtr<WAKView>> _globalFocusView;
    return _globalFocusView;
}

static CGInterpolationQuality sInterpolationQuality;

static void setGlobalFocusView(WAKView *view)
{
    globalFocusView() = view;
}

static WAKScrollView *enclosingScrollView(WAKView *view)
{
    view = [view superview];
    while (view && ![view isKindOfClass:[WAKScrollView class]])
        view = [view superview];
    return (WAKScrollView *)view;
}

@interface WAKScrollView()
- (void)_adjustScrollers;
@end

@interface WAKView (WAKInternal)
- (id)_initWithViewRef:(WKViewRef)viewRef;
@end

@implementation WAKView

static NSInvocation* invocationForPostNotification(NSString *name, id object, id userInfo)
{
    NSNotificationCenter *target = [NSNotificationCenter defaultCenter];
    NSInvocation *invocation = WebThreadMakeNSInvocation(target, @selector(postNotificationName:object:userInfo:));
    [invocation setArgument:&name atIndex:2];
    [invocation setArgument:&object atIndex:3];
    [invocation setArgument:&userInfo atIndex:4];
    return invocation;
}

static void notificationCallback (WKViewRef v, WKViewNotificationType type, void *userInfo)
{
    UNUSED_PARAM(v);
    WAKView *view = (WAKView *)userInfo;
    switch (type){
        case WKViewNotificationViewDidMoveToWindow: {
            [view viewDidMoveToWindow];
            break;
        }
        case WKViewNotificationViewFrameSizeChanged: {
            [view frameSizeChanged];
            if (WAKScrollView *scrollView = enclosingScrollView(view))
                [scrollView _adjustScrollers];

            // Posting a notification to the main thread can cause the WebThreadLock to be
            // relinquished, which gives the main thread a change to run (and possible try
            // to paint). We don't want this to happen if we've updating view sizes in the middle
            // of layout, so use an async notification. <rdar://problem/6745974>
            NSInvocation *invocation = invocationForPostNotification(WAKViewFrameSizeDidChangeNotification, view, nil);
            WebThreadCallDelegateAsync(invocation);
            break;
        }
        case WKViewNotificationViewDidScroll: {
            WebThreadRunOnMainThread(^ {
                 [[NSNotificationCenter defaultCenter] postNotificationName:WAKViewDidScrollNotification object:view userInfo:nil];
            });
            break;
        }            
        default: {
            break;
        }
    }
}

- (void)handleEvent:(WebEvent *)event
{
    ASSERT(event);
    WAKView *view = self;
    while (view) {
        if ([view _selfHandleEvent:event])
            break;
        view = [view superview];
    }
}

- (BOOL)_selfHandleEvent:(WebEvent *)event
{
    switch (event.type) {
    case WebEventMouseDown:
        [self mouseDown:event];
        return YES;
    case WebEventMouseUp:
        [self mouseUp:event];
        return YES;
    case WebEventMouseMoved:
        [self mouseMoved:event];
        return YES;
    case WebEventKeyDown:
        [self keyDown:event];
        return YES;
    case WebEventKeyUp:
        [self keyUp:event];
        return YES;
    case WebEventScrollWheel:
        [self scrollWheel:event];
        return YES;
    case WebEventTouchBegin:
    case WebEventTouchChange:
    case WebEventTouchEnd:
    case WebEventTouchCancel:
#if ENABLE(TOUCH_EVENTS)
        [self touch:event];
#endif
        return YES;
    }
}

- (NSResponder *)nextResponder
{
    return [self superview];
}

static bool responderCallback(WKViewRef, WKViewResponderCallbackType type, void *userInfo)
{
    return [(WAKView *)userInfo _handleResponderCall:type];
}

- (BOOL)_handleResponderCall:(WKViewResponderCallbackType)type
{
    switch (type) {
        case WKViewResponderAcceptsFirstResponder:
            return [self acceptsFirstResponder];
        case WKViewResponderBecomeFirstResponder:
            return [self becomeFirstResponder];
        case WKViewResponderResignFirstResponder:
            return [self resignFirstResponder];
    }
    return NO;
}

static void willRemoveSubviewCallback(WKViewRef view, WKViewRef subview)
{
    [WAKViewForWKViewRef(view) willRemoveSubview:WAKViewForWKViewRef(subview)];
}

static void invalidateGStateCallback(WKViewRef view)
{
    [WAKViewForWKViewRef(view) invalidateGState];
}

+ (WAKView *)_wrapperForViewRef:(WKViewRef)_viewRef
{
    ASSERT(_viewRef);
    if (_viewRef->isa.classInfo == &WKViewClassInfo)
        return adoptNS([[WAKView alloc] _initWithViewRef:_viewRef]).autorelease();
    WKError ("unable to create wrapper for %s\n", _viewRef->isa.classInfo->name);
    return nil;
}

- (id)_initWithViewRef:(WKViewRef)viewR
{
    self = [super init];
    if (!self)
        return nil;

    viewRef = static_cast<WKViewRef>(const_cast<void*>(WKRetain(viewR)));
    viewRef->wrapper = (void *)self;

    return self;
}

- (id)init
{
    return [self initWithFrame:CGRectZero];
}

- (id)initWithFrame:(CGRect)rect
{
    WKViewRef view = WKViewCreateWithFrame(rect, &viewContext);
    self = [self _initWithViewRef:view];
    if (self) {
        viewContext.notificationCallback = notificationCallback;
        viewContext.notificationUserInfo = self;
        viewContext.responderCallback = responderCallback;
        viewContext.responderUserInfo = self;
        viewContext.willRemoveSubviewCallback = willRemoveSubviewCallback;
        viewContext.invalidateGStateCallback = invalidateGStateCallback;
    }
    WKRelease(view);
    return self;
}

- (void)dealloc
{
    [adoptNS([subviewReferences copy]) makeObjectsPerformSelector:@selector(removeFromSuperview)];

    if (viewRef) {
        _WKViewSetViewContext (viewRef, 0);
        viewRef->wrapper = NULL;
        WKRelease (viewRef);
    }
    
    [subviewReferences release];

    [super dealloc];
}

- (WAKWindow *)window
{
    return WKViewGetWindow(viewRef);
}

- (WKViewRef)_viewRef
{
    return viewRef;
}

- (NSMutableSet *)_subviewReferences
{
    if (!subviewReferences)
        subviewReferences = [[NSMutableSet alloc] init];
    return subviewReferences;
}

static void _WAKCopyWrapper(const void *value, void *context)
{
    if (!value)
        return;
    if (!context)
        return;
    
    NSMutableArray *array = (NSMutableArray *)context;
    WAKView *view = WAKViewForWKViewRef(static_cast<WKViewRef>(const_cast<void*>(value)));
    if (view)
        [array addObject:view];
}

- (NSArray *)subviews
{
    CFArrayRef subviews = WKViewGetSubviews([self _viewRef]);
    if (!subviews)
        return @[ ];
    
    CFIndex count = CFArrayGetCount(subviews);
    if (count == 0)
        return @[ ];
    
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:count];
    if (!result)
        return @[ ];
    
    CFArrayApplyFunction(subviews, CFRangeMake(0, count), _WAKCopyWrapper, (void*)result);
    
    return result;
}

- (WAKView *)superview
{
    return WAKViewForWKViewRef(viewRef->superview);
}

- (WAKView *)lastScrollableAncestor
{
    WAKView *view = nil;
    WAKScrollView *scrollView = enclosingScrollView(self);
    
    while (scrollView) {
        
        CGSize scrollViewSize = WKViewGetFrame((WKViewRef)scrollView).size;

        WAKView *documentView = [scrollView documentView];
        scrollView = enclosingScrollView(scrollView);
                                         
        // If this document view can be scrolled, and this is NOT the last scroll view.
        // Our last scroll view is non-existent as far as we're concerned.

        if (scrollView && !CGSizeEqualToSize(scrollViewSize, [documentView frame].size))
            view = documentView;
    }
    
    return view;
}

- (void)addSubview:(WAKView *)subview
{
    auto protectedSubView = retainPtr(subview);
    [subview removeFromSuperview];
    WKViewAddSubview (viewRef, [subview _viewRef]);
    
    // Keep a reference to subview so it sticks around.
    [[self _subviewReferences] addObject:subview];
}

- (void)willRemoveSubview:(WAKView *)subview
{
    UNUSED_PARAM(subview);
}

- (void)removeFromSuperview
{
    RetainPtr<WAKView> oldSuperview = [self superview];
    WKViewRemoveFromSuperview (viewRef);
    [[oldSuperview _subviewReferences] removeObject:self];
}

- (void)viewDidMoveToWindow
{
}

- (void)frameSizeChanged
{
}

- (void)setNeedsDisplay:(BOOL)flag
{
    if (!flag)
        return;
    [self setNeedsDisplayInRect:WKViewGetBounds(viewRef)];
}

- (void)setNeedsDisplayInRect:(CGRect)invalidRect
{
    if (_isHidden)
        return;

    WAKWindow *window = [self window];
    if (!window || CGRectIsEmpty(invalidRect))
        return;

    CGRect rect = CGRectIntersection(invalidRect, [self bounds]);
    if (CGRectIsEmpty(rect))
        return;

    CGRect baseRect = WKViewConvertRectToBase(viewRef, rect);
    [window setNeedsDisplayInRect:baseRect];
}

- (BOOL)needsDisplay 
{
    return NO;
}

- (void)display
{
    [self displayRect:WKViewGetBounds(viewRef)];
}

- (void)displayIfNeeded
{
}

- (void)drawRect:(CGRect)rect
{
    // Do nothing.  Override in subclass.
    UNUSED_PARAM(rect);
}

- (void)viewWillDraw
{
    [[self subviews] makeObjectsPerformSelector:@selector(viewWillDraw)];
}

+ (WAKView *)focusView
{
    return globalFocusView().get();
}

- (NSRect)bounds
{ 
    return WKViewGetBounds (viewRef);
}

- (NSRect)frame 
{ 
    return WKViewGetFrame (viewRef);
}

- (void)setFrame:(NSRect)frameRect
{
    WKViewSetFrameOrigin (viewRef, frameRect.origin);
    WKViewSetFrameSize (viewRef, frameRect.size);
}

- (void)setFrameOrigin:(NSPoint)newOrigin
{
    WKViewSetFrameOrigin (viewRef, newOrigin);
}

- (void)setFrameSize:(NSSize)newSize
{
    WKViewSetFrameSize (viewRef, newSize);
}

- (void)setBoundsSize:(NSSize)size
{
    WKViewSetBoundsSize (viewRef, size);
}

- (void)setBoundsOrigin:(NSPoint)newOrigin
{
    WKViewSetBoundsOrigin(viewRef, newOrigin);
}

- (void)_lockFocusViewInContext:(CGContextRef)context
{
    ASSERT(context);
    setGlobalFocusView(self);
    CGContextSaveGState(context);

    WAKView *superview = [self superview];
    if (superview)
        CGContextClipToRect(context, [superview bounds]);

    CGContextConcatCTM(context, _WKViewGetTransform(viewRef));
}

- (void)_unlockFocusViewInContext:(CGContextRef)context
{
    ASSERT(context);
    CGContextRestoreGState(context);
    setGlobalFocusView(nil);
}

static CGInterpolationQuality toCGInterpolationQuality(WebCore::InterpolationQuality quality)
{
    switch (quality) {
    case WebCore::InterpolationQuality::Default:
        return kCGInterpolationDefault;
    case WebCore::InterpolationQuality::DoNotInterpolate:
        return kCGInterpolationNone;
    case WebCore::InterpolationQuality::Low:
        return kCGInterpolationLow;
    case WebCore::InterpolationQuality::Medium:
        return kCGInterpolationMedium;
    case WebCore::InterpolationQuality::High:
        return kCGInterpolationHigh;
    default:
        ASSERT_NOT_REACHED();
        return kCGInterpolationLow;
    }
}

+ (void)_setInterpolationQuality:(int)quality
{
    sInterpolationQuality = toCGInterpolationQuality((WebCore::InterpolationQuality)quality);
}

- (void)_drawRect:(NSRect)dirtyRect context:(CGContextRef)context lockFocus:(BOOL)lockFocus
{
    if (_isHidden)
        return;

    ASSERT(viewRef);
    ASSERT(context);
    CGRect localRect = WKViewGetBounds(viewRef);
    dirtyRect = CGRectIntersection(localRect, dirtyRect);
    if (CGRectIsEmpty(dirtyRect))
        return;

    if (lockFocus)
        [self _lockFocusViewInContext:context];

    if (viewRef->scale != 1)
        CGContextSetInterpolationQuality(context, sInterpolationQuality);

    CGContextClipToRect(context, dirtyRect);
    [self drawRect:dirtyRect];

    if (!_drawsOwnDescendants) {
        NSArray *subViews = [self subviews];
        for (WAKView *subView in subViews) {
            NSRect childDirtyRect = [self convertRect:dirtyRect toView:subView];
            [subView _drawRect:CGRectIntegral(childDirtyRect) context:context lockFocus:YES];
        }
    }

    if (lockFocus)
        [self _unlockFocusViewInContext:context];
}

- (void)displayRect:(NSRect)rect
{
    CGContextRef context = WKGetCurrentGraphicsContext();
    if (!context) {
        WKError ("unable to get context for view");
        return;
    }

    [self _drawRect:rect context:context lockFocus:YES];
}

- (void)displayRectIgnoringOpacity:(NSRect)rect
{
    [self displayRect:rect];
}

- (void)displayRectIgnoringOpacity:(NSRect)rect inContext:(CGContextRef)context
{
    if (!context) {
        WKError ("invalid parameter: context must not be NULL");
        return;
    }

    CGContextRef previousContext = WKGetCurrentGraphicsContext();
    if (context != previousContext)
        WKSetCurrentGraphicsContext(context);

    [self _drawRect:rect context:context lockFocus:NO];

    if (context != previousContext)
        WKSetCurrentGraphicsContext (previousContext);
}

- (NSRect)visibleRect
{
    return WKViewGetVisibleRect (viewRef);
}

- (NSPoint)convertPoint:(NSPoint)aPoint toView:(WAKView *)aView 
{
    CGPoint p = WKViewConvertPointToBase (viewRef, aPoint);
    if (aView)
        return WKViewConvertPointFromBase ([aView _viewRef], p);
    return p;
}

- (NSPoint)convertPoint:(NSPoint)aPoint fromView:(WAKView *)aView
{
    if (aView)
        aPoint = WKViewConvertPointToBase ([aView _viewRef], aPoint);
    return WKViewConvertPointFromBase (viewRef, aPoint);
}

- (NSSize)convertSize:(NSSize)size toView:(WAKView *)aView
{
    return [self convertRect:NSMakeRect(0.0f, 0.0f, size.width, size.height) toView:aView].size;
}

- (NSRect)convertRect:(NSRect)aRect fromView:(WAKView *)aView
{
    if (aView)
        aRect = WKViewConvertRectToBase ([aView _viewRef], aRect);
    return WKViewConvertRectFromBase (viewRef, aRect);
}

- (NSRect)convertRect:(NSRect)aRect toView:(WAKView *)aView
{
    CGRect r = WKViewConvertRectToBase (viewRef, aRect);
    if (aView)
        return WKViewConvertRectFromBase ([aView _viewRef], r);
    return r;
}

- (void)lockFocus
{
    [self _lockFocusViewInContext:WKGetCurrentGraphicsContext()];
}

- (void)unlockFocus
{
    [self _unlockFocusViewInContext:WKGetCurrentGraphicsContext()];
}

- (WAKView *)hitTest:(NSPoint)point
{
    if (!CGRectContainsPoint([self frame], point))
        return nil;

    CGPoint subviewPoint = WKViewConvertPointFromSuperview(viewRef, point);
    for (WAKView *subview in [self subviews]) {
        if (WAKView *hitView = [subview hitTest: subviewPoint])
            return hitView;
    }

    return self;
}

- (void)setHidden:(BOOL)flag 
{
    ASSERT(viewRef);
    if (_isHidden != flag) {
        // setNeedsDisplay does nothing if the view is hidden so call it at the right time.
        if (flag) {
            [self setNeedsDisplay:YES];
            _isHidden = flag;
        } else {
            _isHidden = flag;
            [self setNeedsDisplay:YES];
        }
    }
}

- (BOOL)isDescendantOf:(NSView *)aView
{
    if (aView == self)
        return YES;
    else if (![self superview])
        return NO;
    else
        return [[self superview] isDescendantOf:aView];
}

- (BOOL)isHiddenOrHasHiddenAncestor
{
    if (_isHidden)
        return YES;

    if (![self superview])
        return NO;

    return [[self superview] isHiddenOrHasHiddenAncestor];
}

- (BOOL)mouse:(NSPoint)aPoint inRect:(NSRect)aRect 
{ 
    return aPoint.x >= aRect.origin.x
        && aPoint.x < (aRect.origin.x + aRect.size.width)
        && aPoint.y >= aRect.origin.y && aPoint.y < (aRect.origin.y + aRect.size.height);
}

- (BOOL)needsPanelToBecomeKey
{
    return true;
}

- (void)setNextKeyView:(NSView *)aView
{
    UNUSED_PARAM(aView);
}

- (WAKView *)previousValidKeyView { return nil; }
- (WAKView *)nextKeyView { return nil; }
- (WAKView *)nextValidKeyView { return nil; }
- (WAKView *)previousKeyView { return nil; }

- (void)invalidateGState { }
- (void)releaseGState { }
- (BOOL)inLiveResize { return NO; }

- (void)setAutoresizingMask:(unsigned int)mask
{
    WKViewSetAutoresizingMask(viewRef, mask);
}

- (unsigned int)autoresizingMask
{
    return WKViewGetAutoresizingMask(viewRef);
}

- (void)scrollPoint:(NSPoint)point 
{
    if (WAKScrollView *scrollView = enclosingScrollView(self)) {
        CGPoint scrollViewPoint = [self convertPoint:point toView:scrollView];
        [scrollView scrollPoint:scrollViewPoint];
    }
}

- (BOOL)scrollRectToVisible:(NSRect)rect
{
    // Scroll if the rect is not already visible.
    CGRect visibleRect = [self visibleRect];
    if (!CGRectContainsRect(visibleRect, rect) && !CGRectContainsRect(rect, visibleRect))
        [self scrollPoint:rect.origin];

    // Return value ignored by WebCore.

    return NO;
}

// Overridden by subclasses (only WebHTMLView for now).
- (void)setNeedsLayout:(BOOL)flag
{
    UNUSED_PARAM(flag);
}

- (void)layout { }
- (void)layoutIfNeeded { }

- (void)setScale:(float)scale
{
    WKViewSetScale(viewRef, scale);
}

- (float)scale
{
    return WKViewGetScale(viewRef);
}

- (void)_setDrawsOwnDescendants:(BOOL)draw
{
    _drawsOwnDescendants = draw;
}

- (NSString *)description
{
    NSMutableString *description = [NSMutableString stringWithFormat:@"<%@: WAK: %p (WK: %p); ", [self class], self, viewRef];

    float scale = [self scale];
    if (scale != 1)
        [description appendFormat:@"scale = %g ", scale];

    CGPoint origin = WKViewGetOrigin(viewRef);
    if (origin.x || origin.y)
        [description appendFormat:@"origin = (%g %g) ", origin.x, origin.y];

    CGRect bounds = [self bounds];
    CGRect frame = [self frame];

    if (frame.origin.x != bounds.origin.x || frame.origin.y != bounds.origin.y || frame.size.width != bounds.size.width || frame.size.height != bounds.size.height)
        [description appendFormat:@"bounds = (%g %g; %g %g) ", bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height];

    [description appendFormat:@"frame = (%g %g; %g %g)>", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height];

    return description;
}

- (void)_appendDescriptionToString:(NSMutableString *)info atLevel:(int)level
{
    @autoreleasepool {
        if ([info length])
            [info appendString:@"\n"];

        for (int i = 1; i <= level; i++)
            [info appendString:@"   | "];

        [info appendString:[self description]];

        for (WAKView *subview in [self subviews])
            [subview _appendDescriptionToString:info atLevel:level + 1];
    }
}

@end

#endif // PLATFORM(IOS_FAMILY)
