/****************************************************************************
**
** Copyright (C) 2016 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$
**
****************************************************************************/

#include <qglobal.h>
#include <qguiapplication.h>
#include <qpa/qplatformtheme.h>

#include "qiosglobal.h"
#include "qiosmenu.h"
#include "qioswindow.h"
#include "qiosinputcontext.h"
#include "qiosintegration.h"
#include "qiostextresponder.h"

#include <algorithm>
#include <iterator>

// m_currentMenu points to the currently visible menu.
// Only one menu will be visible at a time, and if a second menu
// is shown on top of a first, the first one will be told to hide.
QIOSMenu *QIOSMenu::m_currentMenu = 0;

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

static NSString *const kSelectorPrefix = @"_qtMenuItem_";

@interface QUIMenuController : UIResponder
@end

@implementation QUIMenuController {
    QIOSMenuItemList m_visibleMenuItems;
}

- (instancetype)initWithVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems
{
    if (self = [super init]) {
        [self setVisibleMenuItems:visibleMenuItems];
        [[NSNotificationCenter defaultCenter]
            addObserver:self
            selector:@selector(menuClosed)
            name:UIMenuControllerDidHideMenuNotification object:nil];
    }

    return self;
}

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

- (void)setVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems
{
    m_visibleMenuItems = visibleMenuItems;
    NSMutableArray<UIMenuItem *> *menuItemArray = [NSMutableArray<UIMenuItem *> arrayWithCapacity:m_visibleMenuItems.size()];
    // Create an array of UIMenuItems, one for each visible QIOSMenuItem. Each
    // UIMenuItem needs a callback assigned, so we assign one of the placeholder methods
    // added to UIWindow (QIOSMenuActionTargets) below. Each method knows its own index, which
    // corresponds to the index of the corresponding QIOSMenuItem in m_visibleMenuItems. When
    // triggered, menuItemActionCallback will end up being called.
    for (int i = 0; i < m_visibleMenuItems.count(); ++i) {
        QIOSMenuItem *item = m_visibleMenuItems.at(i);
        SEL sel = NSSelectorFromString([NSString stringWithFormat:@"%@%i:", kSelectorPrefix, i]);
        [menuItemArray addObject:[[[UIMenuItem alloc] initWithTitle:item->m_text.toNSString() action:sel] autorelease]];
    }
    [UIMenuController sharedMenuController].menuItems = menuItemArray;
    if ([UIMenuController sharedMenuController].menuVisible)
        [[UIMenuController sharedMenuController] setMenuVisible:YES animated:NO];
}

- (void)menuClosed
{
    QIOSMenu::currentMenu()->dismiss();
}

- (id)targetForAction:(SEL)action withSender:(id)sender
{
    Q_UNUSED(sender);
    BOOL containsPrefix = ([NSStringFromSelector(action) rangeOfString:kSelectorPrefix].location != NSNotFound);
    return containsPrefix ? self : 0;
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
    Q_UNUSED(selector);
    // Just return a dummy signature that NSObject can create an NSInvocation from.
    // We end up only checking selector in forwardInvocation anyway.
    return [super methodSignatureForSelector:@selector(methodSignatureForSelector:)];
}

- (void)forwardInvocation:(NSInvocation *)invocation
{
    // Since none of the menu item selector methods actually exist, this function
    // will end up being called as a final resort. We can then handle the action.
    NSString *selector = NSStringFromSelector(invocation.selector);
    NSRange range = NSMakeRange(kSelectorPrefix.length, selector.length - kSelectorPrefix.length - 1);
    NSInteger selectedIndex = [[selector substringWithRange:range] integerValue];
    QIOSMenu::currentMenu()->handleItemSelected(m_visibleMenuItems.at(selectedIndex));
}

@end

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

@interface QUIPickerView : UIPickerView <UIPickerViewDelegate, UIPickerViewDataSource>

@property(retain) UIToolbar *toolbar;

@end

@implementation QUIPickerView {
    QIOSMenuItemList m_visibleMenuItems;
    QPointer<QObject> m_focusObjectWithPickerView;
    NSInteger m_selectedRow;
}

- (instancetype)initWithVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems selectItem:(const QIOSMenuItem *)selectItem
{
    if (self = [super init]) {
        [self setVisibleMenuItems:visibleMenuItems selectItem:selectItem];

        self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        self.toolbar = [[[UIToolbar alloc] init] autorelease];
        self.toolbar.frame.size = [self.toolbar sizeThatFits:self.bounds.size];
        self.toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

        UIBarButtonItem *spaceButton = [[[UIBarButtonItem alloc]
                initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                target:self action:@selector(closeMenu)] autorelease];
        UIBarButtonItem *cancelButton = [[[UIBarButtonItem alloc]
                initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
                target:self action:@selector(cancelMenu)] autorelease];
        UIBarButtonItem *doneButton = [[[UIBarButtonItem alloc]
                initWithBarButtonSystemItem:UIBarButtonSystemItemDone
                target:self action:@selector(closeMenu)] autorelease];
        [self.toolbar setItems:@[cancelButton, spaceButton, doneButton]];

        [self setDelegate:self];
        [self setDataSource:self];
        [self selectRow:m_selectedRow inComponent:0 animated:false];
        [self listenForKeyboardWillHideNotification:YES];
    }

    return self;
}

- (void)setVisibleMenuItems:(const QIOSMenuItemList &)visibleMenuItems selectItem:(const QIOSMenuItem *)selectItem
{
    m_visibleMenuItems = visibleMenuItems;
    m_selectedRow = visibleMenuItems.indexOf(const_cast<QIOSMenuItem *>(selectItem));
    if (m_selectedRow == -1)
        m_selectedRow = 0;
    [self reloadAllComponents];
}

- (void)listenForKeyboardWillHideNotification:(BOOL)listen
{
    if (listen) {
        [[NSNotificationCenter defaultCenter]
            addObserver:self
            selector:@selector(cancelMenu)
            name:@"UIKeyboardWillHideNotification" object:nil];
    } else {
        [[NSNotificationCenter defaultCenter]
            removeObserver:self
            name:@"UIKeyboardWillHideNotification" object:nil];
    }
}

- (void)dealloc
{
    [self listenForKeyboardWillHideNotification:NO];
    self.toolbar = 0;
    [super dealloc];
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    Q_UNUSED(pickerView);
    Q_UNUSED(component);
    return m_visibleMenuItems.at(row)->m_text.toNSString();
}

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    Q_UNUSED(pickerView);
    return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    Q_UNUSED(pickerView);
    Q_UNUSED(component);
    return m_visibleMenuItems.length();
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    Q_UNUSED(pickerView);
    Q_UNUSED(component);
    m_selectedRow = row;
}

- (void)closeMenu
{
    if (!m_visibleMenuItems.isEmpty())
        QIOSMenu::currentMenu()->handleItemSelected(m_visibleMenuItems.at(m_selectedRow));
    else
        QIOSMenu::currentMenu()->dismiss();
}

- (void)cancelMenu
{
    QIOSMenu::currentMenu()->dismiss();
}

@end

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

QIOSMenuItem::QIOSMenuItem()
    : QPlatformMenuItem()
    , m_visible(true)
    , m_text(QString())
    , m_role(MenuRole(0))
    , m_enabled(true)
    , m_separator(false)
    , m_menu(0)
{
}

void QIOSMenuItem::setText(const QString &text)
{
    m_text = QPlatformTheme::removeMnemonics(text);
}

void QIOSMenuItem::setMenu(QPlatformMenu *menu)
{
   m_menu = static_cast<QIOSMenu *>(menu);
}

void QIOSMenuItem::setVisible(bool isVisible)
{
    m_visible = isVisible;
}

void QIOSMenuItem::setIsSeparator(bool isSeparator)
{
   m_separator = isSeparator;
}

void QIOSMenuItem::setRole(QPlatformMenuItem::MenuRole role)
{
    m_role = role;
}

#ifndef QT_NO_SHORTCUT
void QIOSMenuItem::setShortcut(const QKeySequence &sequence)
{
    m_shortcut = sequence;
}
#endif

void QIOSMenuItem::setEnabled(bool enabled)
{
    m_enabled = enabled;
}


QIOSMenu::QIOSMenu()
    : QPlatformMenu()
    , m_enabled(true)
    , m_visible(false)
    , m_text(QString())
    , m_menuType(DefaultMenu)
    , m_effectiveMenuType(DefaultMenu)
    , m_parentWindow(0)
    , m_targetItem(0)
    , m_menuController(0)
    , m_pickerView(0)
{
}

QIOSMenu::~QIOSMenu()
{
    dismiss();
}

void QIOSMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before)
{
    if (!before) {
        m_menuItems.append(static_cast<QIOSMenuItem *>(menuItem));
    } else {
        int index = m_menuItems.indexOf(static_cast<QIOSMenuItem *>(before)) + 1;
        m_menuItems.insert(index, static_cast<QIOSMenuItem *>(menuItem));
    }
    if (m_currentMenu == this)
        syncMenuItem(menuItem);
}

void QIOSMenu::removeMenuItem(QPlatformMenuItem *menuItem)
{
    m_menuItems.removeOne(static_cast<QIOSMenuItem *>(menuItem));
    if (m_currentMenu == this)
        syncMenuItem(menuItem);
}

void QIOSMenu::syncMenuItem(QPlatformMenuItem *)
{
    if (m_currentMenu != this)
        return;

    switch (m_effectiveMenuType) {
    case EditMenu:
        [m_menuController setVisibleMenuItems:filterFirstResponderActions(visibleMenuItems())];
        break;
    default:
        [m_pickerView setVisibleMenuItems:visibleMenuItems() selectItem:m_targetItem];
        break;
    }
}

void QIOSMenu::setText(const QString &text)
{
   m_text = text;
}

void QIOSMenu::setEnabled(bool enabled)
{
    m_enabled = enabled;
}

void QIOSMenu::setVisible(bool visible)
{
    m_visible = visible;
}

void QIOSMenu::setMenuType(QPlatformMenu::MenuType type)
{
    m_menuType = type;
}

void QIOSMenu::handleItemSelected(QIOSMenuItem *menuItem)
{
    emit menuItem->activated();
    dismiss();

    if (QIOSMenu *menu = menuItem->m_menu) {
        menu->setMenuType(m_effectiveMenuType);
        menu->showPopup(m_parentWindow, m_targetRect, 0);
    }
}

void QIOSMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item)
{
    if (m_currentMenu == this || !parentWindow)
        return;

    emit aboutToShow();

    m_parentWindow = const_cast<QWindow *>(parentWindow);
    m_targetRect = targetRect;
    m_targetItem = static_cast<const QIOSMenuItem *>(item);

    if (!m_parentWindow->isActive())
        m_parentWindow->requestActivate();

    if (m_currentMenu && m_currentMenu != this)
        m_currentMenu->dismiss();

    m_currentMenu = this;
    m_effectiveMenuType = m_menuType;
    connect(qGuiApp, &QGuiApplication::focusObjectChanged, this, &QIOSMenu::dismiss);

    switch (m_effectiveMenuType) {
    case EditMenu:
        toggleShowUsingUIMenuController(true);
        break;
    default:
        toggleShowUsingUIPickerView(true);
        break;
    }

    m_visible = true;
}

void QIOSMenu::dismiss()
{
    if (m_currentMenu != this)
        return;

    emit aboutToHide();

    disconnect(qGuiApp, &QGuiApplication::focusObjectChanged, this, &QIOSMenu::dismiss);

    switch (m_effectiveMenuType) {
    case EditMenu:
        toggleShowUsingUIMenuController(false);
        break;
    default:
        toggleShowUsingUIPickerView(false);
        break;
    }

    m_currentMenu = 0;
    m_visible = false;
}

void QIOSMenu::toggleShowUsingUIMenuController(bool show)
{
    if (show) {
        Q_ASSERT(!m_menuController);
        m_menuController = [[QUIMenuController alloc] initWithVisibleMenuItems:filterFirstResponderActions(visibleMenuItems())];
        repositionMenu();
        connect(qGuiApp->inputMethod(), &QInputMethod::keyboardRectangleChanged, this, &QIOSMenu::repositionMenu);
    } else {
        disconnect(qGuiApp->inputMethod(), &QInputMethod::keyboardRectangleChanged, this, &QIOSMenu::repositionMenu);

        Q_ASSERT(m_menuController);
        [[UIMenuController sharedMenuController] setMenuVisible:NO animated:YES];
        [m_menuController release];
        m_menuController = 0;
    }
}

void QIOSMenu::toggleShowUsingUIPickerView(bool show)
{
    static QObject *focusObjectWithPickerView = 0;

    if (show) {
        Q_ASSERT(!m_pickerView);
        m_pickerView = [[QUIPickerView alloc] initWithVisibleMenuItems:visibleMenuItems() selectItem:m_targetItem];

        Q_ASSERT(!focusObjectWithPickerView);
        focusObjectWithPickerView = qApp->focusWindow()->focusObject();
        focusObjectWithPickerView->installEventFilter(this);
        qApp->inputMethod()->update(Qt::ImEnabled | Qt::ImPlatformData);
    } else {
        Q_ASSERT(focusObjectWithPickerView);
        focusObjectWithPickerView->removeEventFilter(this);
        focusObjectWithPickerView = 0;

        Q_ASSERT(m_pickerView);
        [m_pickerView listenForKeyboardWillHideNotification:NO];
        [m_pickerView release];
        m_pickerView = 0;

        qApp->inputMethod()->update(Qt::ImEnabled | Qt::ImPlatformData);
    }
}

bool QIOSMenu::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::InputMethodQuery) {
        QInputMethodQueryEvent *queryEvent = static_cast<QInputMethodQueryEvent *>(event);
        if (queryEvent->queries() & Qt::ImPlatformData) {
            // Let object fill inn default query results
            obj->event(queryEvent);

            QVariantMap imPlatformData = queryEvent->value(Qt::ImPlatformData).toMap();
            imPlatformData.insert(kImePlatformDataInputView, QVariant::fromValue(static_cast<void *>(m_pickerView)));
            imPlatformData.insert(kImePlatformDataInputAccessoryView, QVariant::fromValue(static_cast<void *>(m_pickerView.toolbar)));
            imPlatformData.insert(kImePlatformDataHideShortcutsBar, true);
            queryEvent->setValue(Qt::ImPlatformData, imPlatformData);
            queryEvent->setValue(Qt::ImEnabled, true);

            return true;
        }
    }

    return QObject::eventFilter(obj, event);
}

QIOSMenuItemList QIOSMenu::visibleMenuItems() const
{
    QIOSMenuItemList visibleMenuItems;
    visibleMenuItems.reserve(m_menuItems.size());
    std::copy_if(m_menuItems.begin(), m_menuItems.end(), std::back_inserter(visibleMenuItems),
                 [](QIOSMenuItem *item) { return item->m_enabled && item->m_visible && !item->m_separator; });
    return visibleMenuItems;
}

QIOSMenuItemList QIOSMenu::filterFirstResponderActions(const QIOSMenuItemList &menuItems)
{
    // UIResponderStandardEditActions found in first responder will be prepended to the edit
    // menu automatically (or e.g made available as buttons on the virtual keyboard). So we
    // filter them out to avoid duplicates, and let first responder handle the actions instead.
    // In case of QIOSTextResponder, edit actions will be converted to key events that ends up
    // triggering the shortcuts of the filtered menu items.
    QIOSMenuItemList filteredMenuItems;
    UIResponder *responder = [UIResponder currentFirstResponder];

    for (int i = 0; i < menuItems.count(); ++i) {
        QIOSMenuItem *menuItem = menuItems.at(i);
#ifndef QT_NO_SHORTCUT
        QKeySequence shortcut = menuItem->m_shortcut;
        if ((shortcut == QKeySequence::Cut && [responder canPerformAction:@selector(cut:) withSender:nil])
                || (shortcut == QKeySequence::Copy && [responder canPerformAction:@selector(copy:) withSender:nil])
                || (shortcut == QKeySequence::Paste && [responder canPerformAction:@selector(paste:) withSender:nil])
                || (shortcut == QKeySequence::Delete && [responder canPerformAction:@selector(delete:) withSender:nil])
                || (shortcut == QKeySequence::SelectAll && [responder canPerformAction:@selector(selectAll:) withSender:nil])
                || (shortcut == QKeySequence::Undo && [responder canPerformAction:@selector(undo:) withSender:nil])
                || (shortcut == QKeySequence::Redo && [responder canPerformAction:@selector(redo:) withSender:nil])
                || (shortcut == QKeySequence::Bold && [responder canPerformAction:@selector(toggleBoldface:) withSender:nil])
                || (shortcut == QKeySequence::Italic && [responder canPerformAction:@selector(toggleItalics:) withSender:nil])
                || (shortcut == QKeySequence::Underline && [responder canPerformAction:@selector(toggleUnderline:) withSender:nil])) {
            continue;
        }
#endif
        filteredMenuItems.append(menuItem);
    }
    return filteredMenuItems;
}

void QIOSMenu::repositionMenu()
{
    switch (m_effectiveMenuType) {
    case EditMenu: {
        UIView *view = reinterpret_cast<UIView *>(m_parentWindow->winId());
        [[UIMenuController sharedMenuController] setTargetRect:m_targetRect.toCGRect() inView:view];
        [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
        break; }
    default:
        break;
    }
}

QPlatformMenuItem *QIOSMenu::menuItemAt(int position) const
{
    if (position < 0 || position >= m_menuItems.size())
        return 0;
    return m_menuItems.at(position);
}

QPlatformMenuItem *QIOSMenu::menuItemForTag(quintptr tag) const
{
    for (int i = 0; i < m_menuItems.size(); ++i) {
        QPlatformMenuItem *item = m_menuItems.at(i);
        if (item->tag() == tag)
            return item;
    }
    return 0;
}
