/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#import <UIKit/UIGestureRecognizerSubclass.h>
#import <UIKit/UITextView.h>

#include <QtGui/QGuiApplication>
#include <QtGui/QInputMethod>
#include <QtGui/QStyleHints>

#include <QtGui/private/qinputmethod_p.h>
#include <QtCore/private/qobject_p.h>
#include <QtCore/private/qcore_mac_p.h>

#include "qiosglobal.h"
#include "qiostextinputoverlay.h"

typedef QPair<int, int> SelectionPair;
typedef void (^Block)(void);

static const CGFloat kKnobWidth = 10;

static QPlatformInputContext *platformInputContext()
{
    return static_cast<QInputMethodPrivate *>(QObjectPrivate::get(QGuiApplication::inputMethod()))->platformInputContext();
}

static SelectionPair querySelection()
{
    QInputMethodQueryEvent query(Qt::ImAnchorPosition | Qt::ImCursorPosition);
    QGuiApplication::sendEvent(QGuiApplication::focusObject(), &query);
    int anchorPos = query.value(Qt::ImAnchorPosition).toInt();
    int cursorPos = query.value(Qt::ImCursorPosition).toInt();
    return qMakePair<int, int>(anchorPos, cursorPos);
}

static bool hasSelection()
{
    SelectionPair selection = querySelection();
    return selection.first != selection.second;
}

static void executeBlockWithoutAnimation(Block block)
{
    [CATransaction begin];
    [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
    block();
    [CATransaction commit];
}

// -------------------------------------------------------------------------
/**
  QIOSEditMenu is just a wrapper class around UIMenuController to
  ease showing and hiding it correcly.
  */
@interface QIOSEditMenu : NSObject
@property (nonatomic, assign) BOOL visible;
@property (nonatomic, readonly) BOOL isHiding;
@property (nonatomic, assign) BOOL reshowAfterHidden;
@end

@implementation QIOSEditMenu

- (instancetype)init
{
    if (self = [super init]) {
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

        [center addObserverForName:UIMenuControllerWillHideMenuNotification
            object:nil queue:nil usingBlock:^(NSNotification *) {
            _isHiding = YES;
        }];

        [center addObserverForName:UIMenuControllerDidHideMenuNotification
            object:nil queue:nil usingBlock:^(NSNotification *) {
            _isHiding = NO;
            if (self.reshowAfterHidden) {
                // To not abort an ongoing hide transition when showing the menu, you can set
                // reshowAfterHidden to wait until the transition finishes before reshowing it.
                self.reshowAfterHidden = NO;
                dispatch_async(dispatch_get_main_queue (), ^{ self.visible = YES; });
            }
        }];
        [center addObserverForName:UIKeyboardDidHideNotification object:nil queue:nil
            usingBlock:^(NSNotification *) {
                self.visible = NO;
        }];

    }

    return self;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:nil];
    [super dealloc];
}

- (BOOL)visible
{
    return [UIMenuController sharedMenuController].menuVisible;
}

- (void)setVisible:(BOOL)visible
{
    if (visible == self.visible)
        return;

    if (visible) {
        // Note that the contents of the edit menu is decided by
        // first responder, which is normally QIOSTextResponder.
        QRectF cr = qApp->inputMethod()->cursorRectangle();
        QRectF ar = qApp->inputMethod()->anchorRectangle();
        CGRect targetRect = cr.united(ar).toCGRect();
        UIView *focusView = reinterpret_cast<UIView *>(qApp->focusWindow()->winId());
        [[UIMenuController sharedMenuController] setTargetRect:targetRect inView:focusView];
        [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
    } else {
        [[UIMenuController sharedMenuController] setMenuVisible:NO animated:YES];
    }
}

@end

// -------------------------------------------------------------------------

@interface QIOSLoupeLayer : CALayer
@property (nonatomic, retain) UIView *targetView;
@property (nonatomic, assign) CGPoint focalPoint;
@property (nonatomic, assign) BOOL visible;
@end

@implementation QIOSLoupeLayer {
    UIView *_snapshotView;
    BOOL _pendingSnapshotUpdate;
    UIView *_loupeImageView;
    CALayer *_containerLayer;
    CGFloat _loupeOffset;
    QTimer _updateTimer;
}

- (instancetype)initWithSize:(CGSize)size cornerRadius:(CGFloat)cornerRadius bottomOffset:(CGFloat)bottomOffset
{
    if (self = [super init]) {
        _loupeOffset = bottomOffset + (size.height / 2);
        _snapshotView = nil;
        _pendingSnapshotUpdate = YES;
        _updateTimer.setInterval(100);
        _updateTimer.setSingleShot(true);
        QObject::connect(&_updateTimer, &QTimer::timeout, [self](){ [self updateSnapshot]; });

        // Create own geometry and outer shadow
        self.frame = CGRectMake(0, 0, size.width, size.height);
        self.cornerRadius = cornerRadius;
        self.shadowColor = [[UIColor grayColor] CGColor];
        self.shadowOffset = CGSizeMake(0, 1);
        self.shadowRadius = 2.0;
        self.shadowOpacity = 0.75;
        self.transform = CATransform3DMakeScale(0, 0, 0);

        // Create container view for the snapshots
        _containerLayer = [[CALayer new] autorelease];
        _containerLayer.frame = self.bounds;
        _containerLayer.cornerRadius = cornerRadius;
        _containerLayer.masksToBounds = YES;
        [self addSublayer:_containerLayer];

        // Create inner loupe shadow
        const CGFloat inset = 30;
        CALayer *topShadeLayer = [[CALayer new] autorelease];
        topShadeLayer.frame = CGRectOffset(CGRectInset(self.bounds, -inset, -inset), 0, inset / 2);
        topShadeLayer.borderWidth = inset / 2;
        topShadeLayer.cornerRadius = cornerRadius;
        topShadeLayer.borderColor = [[UIColor blackColor] CGColor];
        topShadeLayer.shadowColor = [[UIColor blackColor] CGColor];
        topShadeLayer.shadowOffset = CGSizeMake(0, 0);
        topShadeLayer.shadowRadius = 15.0;
        topShadeLayer.shadowOpacity = 0.6;
        // Keep the shadow inside the loupe
        CALayer *mask = [[CALayer new] autorelease];
        mask.frame = CGRectOffset(self.bounds, inset, inset / 2);
        mask.backgroundColor = [[UIColor blackColor] CGColor];
        mask.cornerRadius = cornerRadius;
        topShadeLayer.mask = mask;
        [self addSublayer:topShadeLayer];

        // Create border around the loupe. We need to do this in a separate
        // layer (as opposed to on self) to not draw the border on top of
        // overlapping external children (arrow).
        CALayer *borderLayer = [[CALayer new] autorelease];
        borderLayer.frame = self.bounds;
        borderLayer.borderWidth = 0.75;
        borderLayer.cornerRadius = cornerRadius;
        borderLayer.borderColor = [[UIColor lightGrayColor] CGColor];
        [self addSublayer:borderLayer];
    }

    return self;
}

- (void)dealloc
{
    _targetView = nil;
    [super dealloc];
}

- (void)setVisible:(BOOL)visible
{
    if (_visible == visible)
        return;

    _visible = visible;

    dispatch_async(dispatch_get_main_queue (), ^{
        // Setting transform later, since CA will not perform an animation if
        // changing values directly after init, and if the scale ends up empty.
        self.transform = _visible ? CATransform3DMakeScale(1, 1, 1) : CATransform3DMakeScale(0.0, 0.0, 1);
    });
}

- (void)updateSnapshot
{
    _pendingSnapshotUpdate = YES;
    [self setNeedsDisplay];
}

- (void)setFocalPoint:(CGPoint)point
{
    _focalPoint = point;
    [self updateSnapshot];

    // Schedule a delayed update as well to ensure that we end up with a correct
    // snapshot of the cursor, since QQuickRenderThread lags a bit behind
    _updateTimer.start();
}

- (void)display
{
     // Take a snapshow of the target view, magnify the area around the focal
     // point, and add the snapshow layer as a child of the container layer
     // to make it look like a loupe. Then place this layer at the position of
     // the focal point with the requested offset.
     executeBlockWithoutAnimation(^{
         if (_pendingSnapshotUpdate) {
             UIView *newSnapshot = [_targetView snapshotViewAfterScreenUpdates:NO];
             [_snapshotView.layer removeFromSuperlayer];
             [_snapshotView release];
             _snapshotView = [newSnapshot retain];
             [_containerLayer addSublayer:_snapshotView.layer];
             _pendingSnapshotUpdate = NO;
         }

         self.position = CGPointMake(_focalPoint.x, _focalPoint.y - _loupeOffset);

         const CGFloat loupeScale = 1.5;
         CGFloat x = -(_focalPoint.x * loupeScale) + self.frame.size.width / 2;
         CGFloat y = -(_focalPoint.y * loupeScale) + self.frame.size.height / 2;
         CGFloat w = _targetView.frame.size.width * loupeScale;
         CGFloat h = _targetView.frame.size.height * loupeScale;
         _snapshotView.layer.frame = CGRectMake(x, y, w, h);
     });
}

@end

// -------------------------------------------------------------------------

@interface QIOSHandleLayer : CALayer <CAAnimationDelegate>
@property (nonatomic, assign) CGRect cursorRectangle;
@property (nonatomic, assign) CGFloat handleScale;
@property (nonatomic, assign) BOOL visible;
@property (nonatomic, copy) Block onAnimationDidStop;
@end

@implementation QIOSHandleLayer {
    CALayer *_handleCursorLayer;
    CALayer *_handleKnobLayer;
    Qt::Edge _selectionEdge;
}

@dynamic handleScale;

- (instancetype)initWithKnobAtEdge:(Qt::Edge)selectionEdge
{
    if (self = [super init]) {
        CGColorRef bgColor = [UIColor colorWithRed:0.1 green:0.4 blue:0.9 alpha:1].CGColor;
        _selectionEdge = selectionEdge;
        self.handleScale = 0;

        _handleCursorLayer = [[CALayer new] autorelease];
        _handleCursorLayer.masksToBounds = YES;
        _handleCursorLayer.backgroundColor = bgColor;
        [self addSublayer:_handleCursorLayer];

        _handleKnobLayer = [[CALayer new] autorelease];
        _handleKnobLayer.masksToBounds = YES;
        _handleKnobLayer.backgroundColor = bgColor;
        _handleKnobLayer.cornerRadius = kKnobWidth / 2;
        [self addSublayer:_handleKnobLayer];
    }
    return self;
}

+ (BOOL)needsDisplayForKey:(NSString *)key
{
    if ([key isEqualToString:@"handleScale"])
        return YES;
    return [super needsDisplayForKey:key];
}

- (id<CAAction>)actionForKey:(NSString *)key
{
    if ([key isEqualToString:@"handleScale"]) {
        if (_visible) {
            // The handle should "bounce" in when becoming visible
            CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:key];
            [animation setDuration:0.5];
            animation.values = @[@(0.0f), @(1.3f), @(1.3f), @(1.0f)];
            animation.keyTimes = @[@(0.0f), @(0.3f), @(0.9f), @(1.0f)];
            return animation;
        } else {
            CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:key];
            [animation setDelegate:self];
            animation.fromValue = [self valueForKey:key];
            [animation setDuration:0.2];
            return animation;
        }
    }
    return [super actionForKey:key];
}

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag
{
    Q_UNUSED(animation);
    Q_UNUSED(flag);
    if (self.onAnimationDidStop)
        self.onAnimationDidStop();
}

- (void)setVisible:(BOOL)visible
{
    if (visible == _visible)
        return;

    _visible = visible;

    self.handleScale = visible ? 1 : 0;
}

- (void)setCursorRectangle:(CGRect)cursorRect
{
    if (CGRectEqualToRect(_cursorRectangle, cursorRect))
        return;

    _cursorRectangle = cursorRect;

    executeBlockWithoutAnimation(^{
        [self setNeedsDisplay];
        [self displayIfNeeded];
    });
}

- (void)display
{
    CGFloat cursorWidth = 2;
    CGPoint origin = _cursorRectangle.origin;
    CGSize size = _cursorRectangle.size;
    CGFloat scale = ((QIOSHandleLayer *)[self presentationLayer]).handleScale;
    CGFloat edgeAdjustment = (_selectionEdge == Qt::LeftEdge) ? 0.5 - cursorWidth : -0.5;

    CGFloat cursorX = origin.x + (size.width / 2) + edgeAdjustment;
    CGFloat cursorY = origin.y;
    CGFloat knobX = cursorX - (kKnobWidth - cursorWidth) / 2;
    CGFloat knobY = origin.y + ((_selectionEdge == Qt::LeftEdge) ? -kKnobWidth : size.height);

    _handleCursorLayer.frame = CGRectMake(cursorX, cursorY, cursorWidth, size.height);
    _handleKnobLayer.frame = CGRectMake(knobX, knobY, kKnobWidth, kKnobWidth);
    _handleCursorLayer.transform = CATransform3DMakeScale(1, scale, scale);
    _handleKnobLayer.transform = CATransform3DMakeScale(scale, scale, scale);
}

@end

// -------------------------------------------------------------------------

/**
  QIOSLoupeRecognizer is only a base class from which other recognisers
  below will inherit. It takes care of creating and showing a magnifier
  glass depending on the current gesture state.
  */
@interface QIOSLoupeRecognizer : UIGestureRecognizer <UIGestureRecognizerDelegate>
@property (nonatomic, assign) QPointF focalPoint;
@property (nonatomic, assign) BOOL dragTriggersGesture;
@property (nonatomic, readonly) UIView *focusView;
@end

@implementation QIOSLoupeRecognizer {
    QIOSLoupeLayer *_loupeLayer;
    UIView *_desktopView;
    CGPoint _firstTouchPoint;
    CGPoint _lastTouchPoint;
    QTimer _triggerStateBeganTimer;
    int _originalCursorFlashTime;
}

- (instancetype)init
{
    if (self = [super initWithTarget:self action:@selector(gestureStateChanged)]) {
        self.enabled = NO;
        _triggerStateBeganTimer.setInterval(QGuiApplication::styleHints()->startDragTime());
        _triggerStateBeganTimer.setSingleShot(true);
        QObject::connect(&_triggerStateBeganTimer, &QTimer::timeout, [=](){
            self.state = UIGestureRecognizerStateBegan;
        });
    }

    return self;
}

- (void)setEnabled:(BOOL)enabled
{
    if (enabled == self.enabled)
        return;

    [super setEnabled:enabled];

    if (enabled) {
        _focusView = [reinterpret_cast<UIView *>(qApp->focusWindow()->winId()) retain];
        _desktopView = [qt_apple_sharedApplication().keyWindow.rootViewController.view retain];
        Q_ASSERT(_focusView && _desktopView && _desktopView.superview);
        [_desktopView addGestureRecognizer:self];
    } else {
        [_desktopView removeGestureRecognizer:self];
        [_desktopView release];
        _desktopView = nil;
        [_focusView release];
        _focusView = nil;
        _triggerStateBeganTimer.stop();
        if (_loupeLayer) {
            [_loupeLayer removeFromSuperlayer];
            [_loupeLayer release];
            _loupeLayer = nil;
        }
    }
}

- (void)gestureStateChanged
{
    switch (self.state) {
    case UIGestureRecognizerStateBegan:
        // Stop cursor blinking, and show the loupe
        _originalCursorFlashTime = QGuiApplication::styleHints()->cursorFlashTime();
        QGuiApplication::styleHints()->setCursorFlashTime(0);
        if (!_loupeLayer)
            [self createLoupe];
        [self updateFocalPoint:QPointF::fromCGPoint(_lastTouchPoint)];
        _loupeLayer.visible = YES;
        break;
    case UIGestureRecognizerStateChanged:
        // Tell the sub class to move the loupe to the correct position
        [self updateFocalPoint:QPointF::fromCGPoint(_lastTouchPoint)];
        break;
    case UIGestureRecognizerStateEnded:
        // Restore cursor blinking, and hide the loupe
        QGuiApplication::styleHints()->setCursorFlashTime(_originalCursorFlashTime);
        QIOSTextInputOverlay::s_editMenu.visible = YES;
        _loupeLayer.visible = NO;
        break;
    default:
        _loupeLayer.visible = NO;
        break;
    }
}

- (void)createLoupe
{
    // We magnify the the desktop view. But the loupe itself will be added as a child
    // of the desktop view's parent, so it doesn't become a part of what we magnify.
    _loupeLayer = [[self createLoupeLayer] retain];
    _loupeLayer.targetView = _desktopView;
    [_desktopView.superview.layer addSublayer:_loupeLayer];
}

- (QPointF)focalPoint
{
    return QPointF::fromCGPoint([_loupeLayer.targetView convertPoint:_loupeLayer.focalPoint toView:_focusView]);
}

- (void)setFocalPoint:(QPointF)point
{
    _loupeLayer.focalPoint = [_loupeLayer.targetView convertPoint:point.toCGPoint() fromView:_focusView];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    if ([event allTouches].count > 1) {
        // We only support text selection with one finger
        self.state = UIGestureRecognizerStateFailed;
        return;
    }

    _firstTouchPoint = [static_cast<UITouch *>([touches anyObject]) locationInView:_focusView];
    _lastTouchPoint = _firstTouchPoint;

    // If the touch point is accepted by the sub class (e.g touch on cursor), we start a
    // press'n'hold timer that eventually will move the state to UIGestureRecognizerStateBegan.
    if ([self acceptTouchesBegan:QPointF::fromCGPoint(_firstTouchPoint)])
        _triggerStateBeganTimer.start();
    else
        self.state = UIGestureRecognizerStateFailed;
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];
    _lastTouchPoint = [static_cast<UITouch *>([touches anyObject]) locationInView:_focusView];

    if (self.state == UIGestureRecognizerStatePossible) {
        // If the touch was moved too far before the timer triggered (meaning that this
        // is a drag, not a press'n'hold), we should either fail, or trigger the gesture
        // immediately, depending on self.dragTriggersGesture.
        int startDragDistance = QGuiApplication::styleHints()->startDragDistance();
        int dragDistance = hypot(_firstTouchPoint.x - _lastTouchPoint.x, _firstTouchPoint.y - _lastTouchPoint.y);
        if (dragDistance > startDragDistance) {
            _triggerStateBeganTimer.stop();
            self.state = self.dragTriggersGesture ? UIGestureRecognizerStateBegan : UIGestureRecognizerStateFailed;
        }
    } else {
        self.state = UIGestureRecognizerStateChanged;
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];
    _triggerStateBeganTimer.stop();
    _lastTouchPoint = [static_cast<UITouch *>([touches anyObject]) locationInView:_focusView];
    self.state = self.state == UIGestureRecognizerStatePossible ? UIGestureRecognizerStateFailed : UIGestureRecognizerStateEnded;
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesCancelled:touches withEvent:event];
    _triggerStateBeganTimer.stop();
    _lastTouchPoint = [static_cast<UITouch *>([touches anyObject]) locationInView:_focusView];
    self.state = UIGestureRecognizerStateCancelled;
}

// Methods implemented by subclasses:

- (BOOL)acceptTouchesBegan:(QPointF)touchPoint
{
    Q_UNUSED(touchPoint)
    Q_UNREACHABLE();
    return NO;
}

- (QIOSLoupeLayer *)createLoupeLayer
{
    Q_UNREACHABLE();
    return nullptr;
}

- (void)updateFocalPoint:(QPointF)touchPoint
{
    Q_UNUSED(touchPoint)
    Q_UNREACHABLE();
}

@end

// -------------------------------------------------------------------------

/**
  This recognizer will be active when there's no selection. It will trigger if
  the user does a press and hold, which will start a session where the user can move
  the cursor around with his finger together with a magnifier glass.
  */
@interface QIOSCursorRecognizer : QIOSLoupeRecognizer
@end

@implementation QIOSCursorRecognizer

- (QIOSLoupeLayer *)createLoupeLayer
{
    return [[[QIOSLoupeLayer alloc] initWithSize:CGSizeMake(120, 120) cornerRadius:60 bottomOffset:4] autorelease];
}

- (BOOL)acceptTouchesBegan:(QPointF)touchPoint
{
    QRectF inputRect = QGuiApplication::inputMethod()->inputItemClipRectangle();
    return !hasSelection() && inputRect.contains(touchPoint);
}

- (void)updateFocalPoint:(QPointF)touchPoint
{
    platformInputContext()->setSelectionOnFocusObject(touchPoint, touchPoint);
    self.focalPoint = touchPoint;
}

@end

// -------------------------------------------------------------------------

/**
  This recognizer will watch for selections, and draw handles as overlay
  on the sides. If the user starts dragging on a handle (or do a press and
  hold), it will show a magnifier glass that follows the handle as it moves.
  */
@interface QIOSSelectionRecognizer : QIOSLoupeRecognizer
@end

@implementation QIOSSelectionRecognizer {
    CALayer *_clipRectLayer;
    QIOSHandleLayer *_cursorLayer;
    QIOSHandleLayer *_anchorLayer;
    QPointF _touchOffset;
    bool _dragOnCursor;
    bool _multiLine;
    QTimer _updateSelectionTimer;
    QMetaObject::Connection _cursorConnection;
    QMetaObject::Connection _anchorConnection;
    QMetaObject::Connection _clipRectConnection;
}

- (instancetype)init
{
    if (self = [super init]) {
        self.delaysTouchesBegan = YES;
        self.dragTriggersGesture = YES;
        _multiLine = QInputMethod::queryFocusObject(Qt::ImHints, QVariant()).toUInt() & Qt::ImhMultiLine;
        _updateSelectionTimer.setInterval(1);
        _updateSelectionTimer.setSingleShot(true);
        QObject::connect(&_updateSelectionTimer, &QTimer::timeout, [self](){ [self updateSelection]; });
    }

    return self;
}

- (void)setEnabled:(BOOL)enabled
{
    if (enabled == self.enabled)
        return;

    [super setEnabled:enabled];

    if (enabled) {
        // Create a layer that clips the handles inside the input field
        _clipRectLayer = [CALayer new];
        _clipRectLayer.masksToBounds = YES;
        [self.focusView.layer addSublayer:_clipRectLayer];

        // Create the handle layers, and add them to the clipped input rect layer
        _cursorLayer = [[[QIOSHandleLayer alloc] initWithKnobAtEdge:Qt::RightEdge] autorelease];
        _anchorLayer = [[[QIOSHandleLayer alloc] initWithKnobAtEdge:Qt::LeftEdge] autorelease];
        bool selection = hasSelection();
        _cursorLayer.visible = selection;
        _anchorLayer.visible = selection;
        [_clipRectLayer addSublayer:_cursorLayer];
        [_clipRectLayer addSublayer:_anchorLayer];

        // iOS text input will sometimes set a temporary text selection to perform operations
        // such as backspace (select last character + cut selection). To avoid briefly showing
        // the selection handles for such cases, and to avoid calling updateSelection when
        // both handles and clip rectangle change, we use a timer to wait a cycle before we update.
        // (Note that since QTimer::start is overloaded, we need some extra syntax for the connections).
        QInputMethod *im = QGuiApplication::inputMethod();
        void(QTimer::*start)(void) = &QTimer::start;
        _cursorConnection = QObject::connect(im, &QInputMethod::cursorRectangleChanged, &_updateSelectionTimer, start);
        _anchorConnection = QObject::connect(im, &QInputMethod::anchorRectangleChanged, &_updateSelectionTimer, start);
        _clipRectConnection = QObject::connect(im, &QInputMethod::inputItemClipRectangleChanged, &_updateSelectionTimer, start);

        [self updateSelection];
    } else {
        // Fade out the handles by setting visible to NO, and wait for the animations
        // to finish before removing the clip rect layer, including the handles.
        // Create a local variable to hold the clipRectLayer while the animation is
        // ongoing to ensure that any subsequent calls to setEnabled does not interfere.
        // Also, declare it as __block to stop it from being automatically retained, which
        // would cause a cyclic dependency between clipRectLayer and the block.
        __block CALayer *clipRectLayer = _clipRectLayer;
        __block int handleCount = 2;
        Block block = ^{
            if (--handleCount == 0) {
                [clipRectLayer removeFromSuperlayer];
                [clipRectLayer release];
            }
        };

        _cursorLayer.onAnimationDidStop = block;
        _anchorLayer.onAnimationDidStop = block;
        _cursorLayer.visible = NO;
        _anchorLayer.visible = NO;

        _clipRectLayer = 0;
        _cursorLayer = 0;
        _anchorLayer = 0;
        _updateSelectionTimer.stop();

        QObject::disconnect(_cursorConnection);
        QObject::disconnect(_anchorConnection);
        QObject::disconnect(_clipRectConnection);
    }
}

- (QIOSLoupeLayer *)createLoupeLayer
{
    CGSize loupeSize = CGSizeMake(123, 33);
    CGSize arrowSize = CGSizeMake(25, 12);
    CGFloat loupeOffset = arrowSize.height + 20;

    // Create loupe and arrow layers
    QIOSLoupeLayer *loupeLayer = [[[QIOSLoupeLayer alloc] initWithSize:loupeSize cornerRadius:5 bottomOffset:loupeOffset] autorelease];
    CAShapeLayer *arrowLayer = [[[CAShapeLayer alloc] init] autorelease];

    // Build a triangular path to both draw and mask the arrow layer as a triangle
    UIBezierPath *path = [[UIBezierPath new] autorelease];
    [path moveToPoint:CGPointMake(0, 0)];
    [path addLineToPoint:CGPointMake(arrowSize.width / 2, arrowSize.height)];
    [path addLineToPoint:CGPointMake(arrowSize.width, 0)];

    arrowLayer.frame = CGRectMake((loupeSize.width - arrowSize.width) / 2, loupeSize.height - 1, arrowSize.width, arrowSize.height);
    arrowLayer.path = path.CGPath;
    arrowLayer.backgroundColor = [[UIColor whiteColor] CGColor];
    arrowLayer.strokeColor = [[UIColor lightGrayColor] CGColor];
    arrowLayer.lineWidth = 0.75 * 2;
    arrowLayer.fillColor = nil;

    CAShapeLayer *mask = [[CAShapeLayer new] autorelease];
    mask.frame = arrowLayer.bounds;
    mask.path = path.CGPath;
    arrowLayer.mask = mask;

    [loupeLayer addSublayer:arrowLayer];

    return loupeLayer;
}

- (BOOL)acceptTouchesBegan:(QPointF)touchPoint
{
    if (!hasSelection())
        return NO;

    // Accept the touch if it "overlaps" with any of the handles
    const int handleRadius = 50;
    QPointF cursorCenter = qApp->inputMethod()->cursorRectangle().center();
    QPointF anchorCenter = qApp->inputMethod()->anchorRectangle().center();
    QPointF cursorOffset = QPointF(cursorCenter.x() - touchPoint.x(), cursorCenter.y() - touchPoint.y());
    QPointF anchorOffset = QPointF(anchorCenter.x() - touchPoint.x(), anchorCenter.y() - touchPoint.y());
    double cursorDist = hypot(cursorOffset.x(), cursorOffset.y());
    double anchorDist = hypot(anchorOffset.x(), anchorOffset.y());

    if (cursorDist > handleRadius && anchorDist > handleRadius)
        return NO;

    if (cursorDist < anchorDist) {
        _touchOffset = cursorOffset;
        _dragOnCursor = YES;
    } else {
        _touchOffset = anchorOffset;
        _dragOnCursor = NO;
    }

    return YES;
}

- (void)updateFocalPoint:(QPointF)touchPoint
{
    touchPoint += _touchOffset;

    // Get the text position under the touch
    SelectionPair selection = querySelection();
    const QTransform mapToLocal = QGuiApplication::inputMethod()->inputItemTransform().inverted();
    int touchTextPos = QInputMethod::queryFocusObject(Qt::ImCursorPosition, touchPoint * mapToLocal).toInt();

    // Ensure that the handels cannot be dragged past each other
    if (_dragOnCursor)
        selection.second = (touchTextPos > selection.first) ? touchTextPos : selection.first + 1;
    else
        selection.first = (touchTextPos < selection.second) ? touchTextPos : selection.second - 1;

    // Set new selection
    QList<QInputMethodEvent::Attribute> imAttributes;
    imAttributes.append(QInputMethodEvent::Attribute(
        QInputMethodEvent::Selection, selection.first, selection.second - selection.first, QVariant()));
    QInputMethodEvent event(QString(), imAttributes);
    QGuiApplication::sendEvent(qApp->focusObject(), &event);

    // Move loupe to new position
    QRectF handleRect = _dragOnCursor ?
        qApp->inputMethod()->cursorRectangle() :
        qApp->inputMethod()->anchorRectangle();
    self.focalPoint = QPointF(touchPoint.x(), handleRect.center().y());
}

- (void)updateSelection
{
    if (!hasSelection()) {
        if (_cursorLayer.visible) {
            _cursorLayer.visible = NO;
            _anchorLayer.visible = NO;
            // Only hide the edit menu if we had a selection from before, since
            // the edit menu can also be used for other purposes by others (in
            // which case we try our best not to interfere).
            QIOSTextInputOverlay::s_editMenu.visible = NO;
        }
        return;
    }

    if (!_cursorLayer.visible && QIOSTextInputOverlay::s_editMenu.isHiding) {
        // Since the edit menu is hiding and this is the first selection thereafter, we
        // assume that the selection came from the user tapping on a menu item. In that
        // case, we reshow the menu after it has closed (but then with selection based
        // menu items, as specified by first responder).
        QIOSTextInputOverlay::s_editMenu.reshowAfterHidden = YES;
    }

    // Adjust handles and input rect to match the new selection
    QRectF inputRect = QGuiApplication::inputMethod()->inputItemClipRectangle();
    CGRect cursorRect = QGuiApplication::inputMethod()->cursorRectangle().toCGRect();
    CGRect anchorRect = QGuiApplication::inputMethod()->anchorRectangle().toCGRect();

    if (!_multiLine) {
        // Resize the layer a bit bigger to ensure that the handles are
        // not cut if if they are otherwise visible inside the clip rect.
        int margin = kKnobWidth + 5;
        inputRect.adjust(-margin / 2, -margin, margin / 2, margin);
    }

    executeBlockWithoutAnimation(^{ _clipRectLayer.frame = inputRect.toCGRect(); });
    _cursorLayer.cursorRectangle = [self.focusView.layer convertRect:cursorRect toLayer:_clipRectLayer];
    _anchorLayer.cursorRectangle = [self.focusView.layer convertRect:anchorRect toLayer:_clipRectLayer];
    _cursorLayer.visible = YES;
    _anchorLayer.visible = YES;
}

@end

// -------------------------------------------------------------------------

/**
  This recognizer will trigger if the user taps inside the edit rectangle.
  If there's no selection, and the tap doesn't change the cursor position, the
  visibility of the edit menu will be toggled. Otherwise, if there's a selection, a
  first tap will close the edit menu (if any), and a second tap will remove the selection.
  */
@interface QIOSTapRecognizer : UITapGestureRecognizer
@end

@implementation QIOSTapRecognizer {
    int _cursorPosOnPress;
    UIView *_focusView;
}

- (instancetype)init
{
    if (self = [super initWithTarget:self action:@selector(gestureStateChanged)]) {
        self.enabled = NO;
    }

    return self;
}

- (void)setEnabled:(BOOL)enabled
{
    if (enabled == self.enabled)
        return;

    [super setEnabled:enabled];

    if (enabled) {
        _focusView = [reinterpret_cast<UIView *>(qApp->focusWindow()->winId()) retain];
        [_focusView addGestureRecognizer:self];
    } else {
        [_focusView removeGestureRecognizer:self];
        [_focusView release];
        _focusView = nil;
    }
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];

    if (hasSelection() && !QIOSTextInputOverlay::s_editMenu.isHiding) {
        // If there's a selection and the menu is visible, UIKit will hide the menu on the
        // first tap. But if we get a second tap while the menu is hidden, we choose to diverge
        // a bit from native behavior and instead fail the tap and forward the touch
        // to Qt. This will effectively move the cursor (and remove the selection).
        // This is needed to ensure that the user can remove the selection at any time, but
        // at the same time, also be able to tap on other items in the UI while keeping the
        // selection (e.g make the selection bold by tapping on a bold button in the UI).
        self.state = UIGestureRecognizerStateFailed;
        return;
    }

    QRectF inputRect = QGuiApplication::inputMethod()->inputItemClipRectangle();
    QPointF touchPos = QPointF::fromCGPoint([static_cast<UITouch *>([touches anyObject]) locationInView:_focusView]);
    if (!inputRect.contains(touchPos))
        self.state = UIGestureRecognizerStateFailed;

    _cursorPosOnPress = QInputMethod::queryFocusObject(Qt::ImCursorPosition, QVariant()).toInt();
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    QPointF touchPos = QPointF::fromCGPoint([static_cast<UITouch *>([touches anyObject]) locationInView:_focusView]);
    const QTransform mapToLocal = QGuiApplication::inputMethod()->inputItemTransform().inverted();
    int cursorPosOnRelease = QInputMethod::queryFocusObject(Qt::ImCursorPosition, touchPos * mapToLocal).toInt();

    if (!QIOSTextInputOverlay::s_editMenu.isHiding && cursorPosOnRelease != _cursorPosOnPress) {
        // We also want to track if the user taps on the screen to close the edit menu. And
        // the way we detect that is to check if the edit menu is hiding when we receive this
        // call. If that's the case, we leave the state as-is to allow a tap to be recognized.
        // Otherwise, if we also see that the cursor will change position, we fail, so that
        // touch events for Qt are not cancelled.
        self.state = UIGestureRecognizerStateFailed;
    }

    [super touchesEnded:touches withEvent:event];
}

- (void)gestureStateChanged
{
    if (self.state != UIGestureRecognizerStateEnded)
        return;

    if (QIOSTextInputOverlay::s_editMenu.isHiding) {
        // Closing the menu is what we want for the first tap, so just return
        return;
    }

    QIOSTextInputOverlay::s_editMenu.visible = !QIOSTextInputOverlay::s_editMenu.visible;
}

@end

// -------------------------------------------------------------------------

QT_BEGIN_NAMESPACE

QIOSEditMenu *QIOSTextInputOverlay::s_editMenu = nullptr;

QIOSTextInputOverlay::QIOSTextInputOverlay()
    : m_cursorRecognizer(nullptr)
    , m_selectionRecognizer(nullptr)
    , m_openMenuOnTapRecognizer(nullptr)
{
    if (qt_apple_isApplicationExtension()) {
        qWarning() << "text input overlays disabled in application extensions";
        return;
    }

    connect(qApp, &QGuiApplication::focusObjectChanged, this, &QIOSTextInputOverlay::updateFocusObject);
}

QIOSTextInputOverlay::~QIOSTextInputOverlay()
{
    if (qApp)
        disconnect(qApp, 0, this, 0);
}

void QIOSTextInputOverlay::updateFocusObject()
{
    if (m_cursorRecognizer) {
        // Destroy old recognizers since they were created with
        // dependencies to the old focus object (focus view).
        m_cursorRecognizer.enabled = NO;
        m_selectionRecognizer.enabled = NO;
        m_openMenuOnTapRecognizer.enabled = NO;
        [m_cursorRecognizer release];
        [m_selectionRecognizer release];
        [m_openMenuOnTapRecognizer release];
        [s_editMenu release];
        m_cursorRecognizer = nullptr;
        m_selectionRecognizer = nullptr;
        m_openMenuOnTapRecognizer = nullptr;
        s_editMenu = nullptr;
    }

    if (platformInputContext()->inputMethodAccepted()) {
        s_editMenu = [QIOSEditMenu new];
        m_cursorRecognizer = [QIOSCursorRecognizer new];
        m_selectionRecognizer = [QIOSSelectionRecognizer new];
        m_openMenuOnTapRecognizer = [QIOSTapRecognizer new];
        m_cursorRecognizer.enabled = YES;
        m_selectionRecognizer.enabled = YES;
        m_openMenuOnTapRecognizer.enabled = YES;
    }
}

QT_END_NAMESPACE
