/****************************************************************************
**
** 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 <qpa/qplatformtheme.h>

#include "qcocoahelpers.h"
#include "qnsview.h"

#include <QtCore>
#include <QtGui>
#include <qpa/qplatformscreen.h>
#include <private/qguiapplication_p.h>
#include <private/qwindow_p.h>
#include <QtGui/private/qcoregraphics_p.h>

#ifndef QT_NO_WIDGETS
#include <QtWidgets/QWidget>
#endif

#include <algorithm>

#include <mach-o/dyld.h>
#include <dlfcn.h>

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
Q_LOGGING_CATEGORY(lcQpaDrawing, "qt.qpa.drawing");
Q_LOGGING_CATEGORY(lcQpaMouse, "qt.qpa.input.mouse", QtCriticalMsg);
Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen", QtCriticalMsg);

//
// Conversion Functions
//

QStringList qt_mac_NSArrayToQStringList(NSArray<NSString *> *array)
{
    QStringList result;
    for (NSString *string in array)
        result << QString::fromNSString(string);
    return result;
}

NSMutableArray<NSString *> *qt_mac_QStringListToNSMutableArray(const QStringList &list)
{
    NSMutableArray<NSString *> *result = [NSMutableArray<NSString *> arrayWithCapacity:list.size()];
    for (const QString &string : list)
        [result addObject:string.toNSString()];
    return result;
}

struct dndenum_mapper
{
    NSDragOperation mac_code;
    Qt::DropAction qt_code;
    bool Qt2Mac;
};

static dndenum_mapper dnd_enums[] = {
    { NSDragOperationLink,  Qt::LinkAction, true },
    { NSDragOperationMove,  Qt::MoveAction, true },
    { NSDragOperationDelete,  Qt::MoveAction, true },
    { NSDragOperationCopy,  Qt::CopyAction, true },
    { NSDragOperationGeneric,  Qt::CopyAction, false },
    { NSDragOperationEvery, Qt::ActionMask, false },
    { NSDragOperationNone, Qt::IgnoreAction, false }
};

NSDragOperation qt_mac_mapDropAction(Qt::DropAction action)
{
    for (int i=0; dnd_enums[i].qt_code; i++) {
        if (dnd_enums[i].Qt2Mac && (action & dnd_enums[i].qt_code)) {
            return dnd_enums[i].mac_code;
        }
    }
    return NSDragOperationNone;
}

NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions)
{
    NSDragOperation nsActions = NSDragOperationNone;
    for (int i=0; dnd_enums[i].qt_code; i++) {
        if (dnd_enums[i].Qt2Mac && (actions & dnd_enums[i].qt_code))
            nsActions |= dnd_enums[i].mac_code;
    }
    return nsActions;
}

Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions)
{
    Qt::DropAction action = Qt::IgnoreAction;
    for (int i=0; dnd_enums[i].mac_code; i++) {
        if (nsActions & dnd_enums[i].mac_code)
            return dnd_enums[i].qt_code;
    }
    return action;
}

Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
{
    Qt::DropActions actions = Qt::IgnoreAction;

    for (int i=0; dnd_enums[i].mac_code; i++) {
        if (dnd_enums[i].mac_code == NSDragOperationEvery)
            continue;

        if (nsActions & dnd_enums[i].mac_code)
            actions |= dnd_enums[i].qt_code;
    }
    return actions;
}

/*!
    Returns the view cast to a QNSview if possible.

    If the view is not a QNSView, nil is returned, which is safe to
    send messages to, effectivly making [qnsview_cast(view) message]
    a no-op.

    For extra verbosity and clearer code, please consider checking
    that the platform window is not a foreign window before using
    this cast, via QPlatformWindow::isForeignWindow().

    Do not use this method soley to check for foreign windows, as
    that will make the code harder to read for people not working
    primarily on macOS, who do not know the difference between the
    NSView and QNSView cases.
*/
QNSView *qnsview_cast(NSView *view)
{
    return qt_objc_cast<QNSView *>(view);
}

//
// Misc
//

// Sets the activation policy for this process to NSApplicationActivationPolicyRegular,
// unless either LSUIElement or LSBackgroundOnly is set in the Info.plist.
void qt_mac_transformProccessToForegroundApplication()
{
    bool forceTransform = true;
    CFTypeRef value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
                                                           CFSTR("LSUIElement"));
    if (value) {
        CFTypeID valueType = CFGetTypeID(value);
        // Officially it's supposed to be a string, a boolean makes sense, so we'll check.
        // A number less so, but OK.
        if (valueType == CFStringGetTypeID())
            forceTransform = !(QString::fromCFString(static_cast<CFStringRef>(value)).toInt());
        else if (valueType == CFBooleanGetTypeID())
            forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
        else if (valueType == CFNumberGetTypeID()) {
            int valueAsInt;
            CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
            forceTransform = !valueAsInt;
        }
    }

    if (forceTransform) {
        value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
                                                     CFSTR("LSBackgroundOnly"));
        if (value) {
            CFTypeID valueType = CFGetTypeID(value);
            if (valueType == CFBooleanGetTypeID())
                forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
            else if (valueType == CFStringGetTypeID())
                forceTransform = !(QString::fromCFString(static_cast<CFStringRef>(value)).toInt());
            else if (valueType == CFNumberGetTypeID()) {
                int valueAsInt;
                CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
                forceTransform = !valueAsInt;
            }
        }
    }

    if (forceTransform) {
        [[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular];
    }
}

QString qt_mac_applicationName()
{
    QString appName;
    CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("CFBundleName"));
    if (string)
        appName = QString::fromCFString(static_cast<CFStringRef>(string));

    if (appName.isEmpty()) {
        QString arg0 = QGuiApplicationPrivate::instance()->appName();
        if (arg0.contains("/")) {
            QStringList parts = arg0.split(QLatin1Char('/'));
            appName = parts.at(parts.count() - 1);
        } else {
            appName = arg0;
        }
    }
    return appName;
}

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

/*!
    \fn QPointF qt_mac_flip(const QPointF &pos, const QRectF &reference)
    \fn QRectF qt_mac_flip(const QRectF &rect, const QRectF &reference)

    Flips the Y coordinate of the point/rect between quadrant I and IV.

    The native coordinate system on macOS uses quadrant I, with origin
    in bottom left, and Qt uses quadrant IV, with origin in top left.

    By flipping the Y coordinate, we can map the point/rect between
    the two coordinate systems.

    The flip is always in relation to a reference rectangle, e.g.
    the frame of the parent view, or the screen geometry. In the
    latter case the specialized QCocoaScreen::mapFrom/To functions
    should be used instead.
*/
QPointF qt_mac_flip(const QPointF &pos, const QRectF &reference)
{
    return QPointF(pos.x(), reference.height() - pos.y());
}

QRectF qt_mac_flip(const QRectF &rect, const QRectF &reference)
{
    return QRectF(qt_mac_flip(rect.bottomLeft(), reference), rect.size());
}

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

/*!
  \fn Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)

  Returns the Qt::Button that corresponds to an NSEvent.buttonNumber.

  \note AppKit will use buttonNumber 0 to indicate both "left button"
  and "no button". Only NSEvents that describes mouse press/release
  events (e.g NSEventTypeOtherMouseDown) will contain a valid
  button number.
*/
Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
{
    if (buttonNum >= 0 && buttonNum <= 31)
        return Qt::MouseButton(1 << buttonNum);
    return Qt::NoButton;
}

/*!
  \fn Qt::MouseButton cocoaButton2QtButton(NSEvent *event)

  Returns the Qt::Button that corresponds to an NSEvent.buttonNumber.

  \note AppKit will use buttonNumber 0 to indicate both "left button"
  and "no button". Only NSEvents that describes mouse press/release/dragging
  events (e.g NSEventTypeOtherMouseDown) will contain a valid
  button number.

  \note Wacom tablet might not return the correct button number for NSEvent buttonNumber
  on right clicks. Decide here that the button is the "right" button.
*/
Qt::MouseButton cocoaButton2QtButton(NSEvent *event)
{
    if (cocoaEvent2QtMouseEvent(event) == QEvent::MouseMove)
        return Qt::NoButton;

    switch (event.type) {
    case NSEventTypeRightMouseUp:
    case NSEventTypeRightMouseDown:
        return Qt::RightButton;

    default:
        break;
    }

    return cocoaButton2QtButton(event.buttonNumber);
}

/*!
  \fn QEvent::Type cocoaEvent2QtMouseEvent(NSEvent *event)

  Returns the QEvent::Type that corresponds to an NSEvent.type.
*/
QEvent::Type cocoaEvent2QtMouseEvent(NSEvent *event)
{
    switch (event.type) {
    case NSEventTypeLeftMouseDown:
    case NSEventTypeRightMouseDown:
    case NSEventTypeOtherMouseDown:
        return QEvent::MouseButtonPress;

    case NSEventTypeLeftMouseUp:
    case NSEventTypeRightMouseUp:
    case NSEventTypeOtherMouseUp:
        return QEvent::MouseButtonRelease;

    case NSEventTypeLeftMouseDragged:
    case NSEventTypeRightMouseDragged:
    case NSEventTypeOtherMouseDragged:
        return QEvent::MouseMove;

    case NSEventTypeMouseMoved:
        return QEvent::MouseMove;

    default:
        break;
    }

    return QEvent::None;
}

/*!
  \fn Qt::MouseButtons cocoaMouseButtons2QtMouseButtons(NSInteger pressedMouseButtons)

  Returns the Qt::MouseButtons that corresponds to an NSEvent.pressedMouseButtons.
*/
Qt::MouseButtons cocoaMouseButtons2QtMouseButtons(NSInteger pressedMouseButtons)
{
  return static_cast<Qt::MouseButton>(pressedMouseButtons & Qt::MouseButtonMask);
}

/*!
  \fn Qt::MouseButtons currentlyPressedMouseButtons()

  Returns the Qt::MouseButtons that corresponds to an NSEvent.pressedMouseButtons.
*/
Qt::MouseButtons currentlyPressedMouseButtons()
{
  return cocoaMouseButtons2QtMouseButtons(NSEvent.pressedMouseButtons);
}

QString qt_mac_removeAmpersandEscapes(QString s)
{
    return QPlatformTheme::removeMnemonics(s).trimmed();
}

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

#if !defined(Q_PROCESSOR_X86_64)
#error "32-bit builds are not supported"
#endif

QOperatingSystemVersion QMacVersion::buildSDK(VersionTarget target)
{
    switch (target) {
    case ApplicationBinary: return applicationVersion().second;
    case QtLibraries: return libraryVersion().second;
    }
    Q_UNREACHABLE();
}

QOperatingSystemVersion QMacVersion::deploymentTarget(VersionTarget target)
{
    switch (target) {
    case ApplicationBinary: return applicationVersion().first;
    case QtLibraries: return libraryVersion().first;
    }
    Q_UNREACHABLE();
}

QOperatingSystemVersion QMacVersion::currentRuntime()
{
    return QOperatingSystemVersion::current();
}

QMacVersion::VersionTuple QMacVersion::versionsForImage(const mach_header *machHeader)
{
    static auto makeVersionTuple = [](uint32_t dt, uint32_t sdk) {
        return qMakePair(
            QOperatingSystemVersion(QOperatingSystemVersion::MacOS,
                dt >> 16 & 0xffff, dt >> 8 & 0xff, dt & 0xff),
            QOperatingSystemVersion(QOperatingSystemVersion::MacOS,
                sdk >> 16 & 0xffff, sdk >> 8 & 0xff, sdk & 0xff)
        );
    };

    auto commandCursor = uintptr_t(machHeader) + sizeof(mach_header_64);
    for (uint32_t i = 0; i < machHeader->ncmds; ++i) {
        load_command *loadCommand = reinterpret_cast<load_command *>(commandCursor);
        if (loadCommand->cmd == LC_VERSION_MIN_MACOSX) {
            auto versionCommand = reinterpret_cast<version_min_command *>(loadCommand);
            return makeVersionTuple(versionCommand->version, versionCommand->sdk);
#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_13)
        } else if (loadCommand->cmd == LC_BUILD_VERSION) {
            auto versionCommand = reinterpret_cast<build_version_command *>(loadCommand);
            return makeVersionTuple(versionCommand->minos, versionCommand->sdk);
#endif
        }
        commandCursor += loadCommand->cmdsize;
    }
    Q_ASSERT_X(false, "QCocoaIntegration", "Could not find any version load command");
    Q_UNREACHABLE();
}

QMacVersion::VersionTuple QMacVersion::applicationVersion()
{
    static VersionTuple version = []() {
        const mach_header *executableHeader = nullptr;
        for (uint32_t i = 0; i < _dyld_image_count(); ++i) {
            auto header = _dyld_get_image_header(i);
            if (header->filetype == MH_EXECUTE) {
                executableHeader = header;
                break;
            }
        }
        Q_ASSERT_X(executableHeader, "QCocoaIntegration", "Failed to resolve Mach-O header of executable");
        return versionsForImage(executableHeader);
    }();
    return version;
}

QMacVersion::VersionTuple QMacVersion::libraryVersion()
{
    static VersionTuple version = []() {
        Dl_info cocoaPluginImage;
        dladdr((const void *)&QMacVersion::libraryVersion, &cocoaPluginImage);
        Q_ASSERT_X(cocoaPluginImage.dli_fbase, "QCocoaIntegration", "Failed to resolve Mach-O header of Cocoa plugin");
        return versionsForImage(static_cast<mach_header*>(cocoaPluginImage.dli_fbase));
    }();
    return version;
}

QT_END_NAMESPACE

/*! \internal

    This NSView derived class is used to add OK/Cancel
    buttons to NSColorPanel and NSFontPanel. It replaces
    the panel's content view, while reparenting the former
    content view into itself. It also takes care of setting
    the target-action for the OK/Cancel buttons and making
    sure the layout is consistent.
 */
@implementation QNSPanelContentsWrapper {
    NSButton *_okButton;
    NSButton *_cancelButton;
    NSView *_panelContents;
    NSEdgeInsets _panelContentsMargins;
}

@synthesize okButton = _okButton;
@synthesize cancelButton = _cancelButton;
@synthesize panelContents = _panelContents;
@synthesize panelContentsMargins = _panelContentsMargins;

- (instancetype)initWithPanelDelegate:(id<QNSPanelDelegate>)panelDelegate
{
    if ((self = [super initWithFrame:NSZeroRect])) {
        // create OK and Cancel buttons and add these as subviews
        _okButton = [self createButtonWithTitle:"&OK"];
        _okButton.action = @selector(onOkClicked);
        _okButton.target = panelDelegate;

        _cancelButton = [self createButtonWithTitle:"Cancel"];
        _cancelButton.action = @selector(onCancelClicked);
        _cancelButton.target = panelDelegate;

        _panelContents = nil;

        _panelContentsMargins = NSEdgeInsetsMake(0, 0, 0, 0);
    }

    return self;
}

- (void)dealloc
{
    [_okButton release];
    _okButton = nil;
    [_cancelButton release];
    _cancelButton = nil;

    _panelContents = nil;

    [super dealloc];
}

- (NSButton *)createButtonWithTitle:(const char *)title
{
    NSButton *button = [[NSButton alloc] initWithFrame:NSZeroRect];
    button.buttonType = NSMomentaryLightButton;
    button.bezelStyle = NSRoundedBezelStyle;
    const QString &cleanTitle = QPlatformTheme::removeMnemonics(QCoreApplication::translate("QDialogButtonBox", title));
    // FIXME: Not obvious, from Cocoa's documentation, that QString::toNSString() makes a deep copy
    button.title = (NSString *)cleanTitle.toCFString();
    ((NSButtonCell *)button.cell).font =
            [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSControlSizeRegular]];
    [self addSubview:button];
    return button;
}

- (void)layout
{
    static const CGFloat ButtonMinWidth = 78.0; // 84.0 for Carbon
    static const CGFloat ButtonMinHeight = 32.0;
    static const CGFloat ButtonSpacing = 0.0;
    static const CGFloat ButtonTopMargin = 0.0;
    static const CGFloat ButtonBottomMargin = 7.0;
    static const CGFloat ButtonSideMargin = 9.0;

    NSSize frameSize = self.frame.size;

    [self.okButton sizeToFit];
    NSSize okSizeHint = self.okButton.frame.size;

    [self.cancelButton sizeToFit];
    NSSize cancelSizeHint = self.cancelButton.frame.size;

    const CGFloat buttonWidth = qMin(qMax(ButtonMinWidth,
                                          qMax(okSizeHint.width, cancelSizeHint.width)),
                                     CGFloat((frameSize.width - 2.0 * ButtonSideMargin - ButtonSpacing) * 0.5));
    const CGFloat buttonHeight = qMax(ButtonMinHeight,
                                     qMax(okSizeHint.height, cancelSizeHint.height));

    NSRect okRect = { { frameSize.width - ButtonSideMargin - buttonWidth,
                        ButtonBottomMargin },
                      { buttonWidth, buttonHeight } };
    self.okButton.frame = okRect;
    self.okButton.needsDisplay = YES;

    NSRect cancelRect = { { okRect.origin.x - ButtonSpacing - buttonWidth,
                            ButtonBottomMargin },
                            { buttonWidth, buttonHeight } };
    self.cancelButton.frame = cancelRect;
    self.cancelButton.needsDisplay = YES;

    // The third view should be the original panel contents. Cache it.
    if (!self.panelContents)
        for (NSView *view in self.subviews)
            if (view != self.okButton && view != self.cancelButton) {
                _panelContents = view;
                break;
            }

    const CGFloat buttonBoxHeight = ButtonBottomMargin + buttonHeight + ButtonTopMargin;
    const NSRect panelContentsFrame = NSMakeRect(
                self.panelContentsMargins.left,
                buttonBoxHeight + self.panelContentsMargins.bottom,
                frameSize.width - (self.panelContentsMargins.left + self.panelContentsMargins.right),
                frameSize.height - buttonBoxHeight - (self.panelContentsMargins.top + self.panelContentsMargins.bottom));
    self.panelContents.frame = panelContentsFrame;
    self.panelContents.needsDisplay = YES;

    self.needsDisplay = YES;
    [super layout];
}

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

io_object_t q_IOObjectRetain(io_object_t obj)
{
    kern_return_t ret = IOObjectRetain(obj);
    Q_ASSERT(!ret);
    return obj;
}

void q_IOObjectRelease(io_object_t obj)
{
    kern_return_t ret = IOObjectRelease(obj);
    Q_ASSERT(!ret);
}

@end
