/****************************************************************************
**
** Copyright (C) 2018 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 "qcocoamenuloader.h"

#include "messages.h"
#include "qcocoahelpers.h"
#include "qcocoansmenu.h"
#include "qcocoamenubar.h"
#include "qcocoamenuitem.h"
#include "qcocoaintegration.h"

#include <QtCore/private/qcore_mac_p.h>
#include <QtCore/private/qthread_p.h>
#include <QtCore/qcoreapplication.h>
#include <QtGui/private/qguiapplication_p.h>

@implementation QCocoaMenuLoader {
    NSMenu *theMenu;
    NSMenu *appMenu;
    NSMenuItem *quitItem;
    NSMenuItem *preferencesItem;
    NSMenuItem *aboutItem;
    NSMenuItem *aboutQtItem;
    NSMenuItem *hideItem;
    NSMenuItem *servicesItem;
    NSMenuItem *hideAllOthersItem;
    NSMenuItem *showAllItem;
}

+ (instancetype)sharedMenuLoader
{
    static QCocoaMenuLoader *shared = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [[self alloc] init];
        atexit_b(^{
            [shared release];
            shared = nil;
        });
    });
    return shared;
}

- (instancetype)init
{
    if ((self = [super init])) {
        NSString *appName = qt_mac_applicationName().toNSString();

        // Menubar as menu. Title as set in the NIB file
        theMenu = [[NSMenu alloc] initWithTitle:@"Main Menu"];

        // Application menu. Since 10.6, the first menu
        // is always identified as the application menu.
        NSMenuItem *appItem = [[[NSMenuItem alloc] init] autorelease];
        appItem.title = appName;
        [theMenu addItem:appItem];
        appMenu = [[NSMenu alloc] initWithTitle:appName];
        appItem.submenu = appMenu;

        // About Application
        aboutItem = [[QCocoaNSMenuItem alloc] init];
        aboutItem.title = [@"About " stringByAppendingString:appName];
        // FIXME This seems useless since barely adding a QAction
        // with AboutRole role will reset the target/action
        aboutItem.target = self;
        aboutItem.action = @selector(orderFrontStandardAboutPanel:);
        // Disable until a QAction is associated
        aboutItem.enabled = NO;
        aboutItem.hidden = YES;
        [appMenu addItem:aboutItem];

        // About Qt (shameless self-promotion)
        aboutQtItem = [[QCocoaNSMenuItem alloc] init];
        aboutQtItem.title = @"About Qt";
        // Disable until a QAction is associated
        aboutQtItem.enabled = NO;
        aboutQtItem.hidden = YES;
        [appMenu addItem:aboutQtItem];

        [appMenu addItem:[NSMenuItem separatorItem]];

        // Preferences
        // We'll be adding app specific items after this. The macOS HIG state that,
        // "In general, a Preferences menu item should be the first app-specific menu item."
        // https://developer.apple.com/macos/human-interface-guidelines/menus/menu-bar-menus/
        preferencesItem = [[QCocoaNSMenuItem alloc] init];
        preferencesItem.title = @"Preferences…";
        preferencesItem.keyEquivalent = @",";
        // Disable until a QAction is associated
        preferencesItem.enabled = NO;
        preferencesItem.hidden = YES;
        [appMenu addItem:preferencesItem];

        [appMenu addItem:[NSMenuItem separatorItem]];

        // Services item and menu
        servicesItem = [[NSMenuItem alloc] init];
        servicesItem.title = @"Services";
        NSMenu *servicesMenu = [[[NSMenu alloc] initWithTitle:@"Services"] autorelease];
        servicesItem.submenu = servicesMenu;
        [NSApplication sharedApplication].servicesMenu = servicesMenu;
        [appMenu addItem:servicesItem];

        [appMenu addItem:[NSMenuItem separatorItem]];

        // Hide Application
        hideItem = [[NSMenuItem alloc] initWithTitle:[@"Hide " stringByAppendingString:appName]
                                              action:@selector(hide:)
                                       keyEquivalent:@"h"];
        hideItem.target = self;
        [appMenu addItem:hideItem];

        // Hide Others
        hideAllOthersItem = [[NSMenuItem alloc] initWithTitle:@"Hide Others"
                                                       action:@selector(hideOtherApplications:)
                                                keyEquivalent:@"h"];
        hideAllOthersItem.target = self;
        hideAllOthersItem.keyEquivalentModifierMask = NSEventModifierFlagCommand | NSEventModifierFlagOption;
        [appMenu addItem:hideAllOthersItem];

        // Show All
        showAllItem = [[NSMenuItem alloc] initWithTitle:@"Show All"
                                                 action:@selector(unhideAllApplications:)
                                          keyEquivalent:@""];
        showAllItem.target = self;
        [appMenu addItem:showAllItem];

        [appMenu addItem:[NSMenuItem separatorItem]];

        // Quit Application
        quitItem = [[QCocoaNSMenuItem alloc] init];
        quitItem.title = [@"Quit " stringByAppendingString:appName];
        quitItem.keyEquivalent = @"q";
        // This will remain true until synced with a QCocoaMenuItem.
        // This way, we will always have a functional Quit menu item
        // even if no QAction is added.
        quitItem.action = @selector(terminate:);
        [appMenu addItem:quitItem];
    }

    return self;
}

- (void)dealloc
{
    [theMenu release];
    [appMenu release];
    [aboutItem release];
    [aboutQtItem release];
    [preferencesItem release];
    [servicesItem release];
    [hideItem release];
    [hideAllOthersItem release];
    [showAllItem release];
    [quitItem release];

    [super dealloc];
}

- (void)ensureAppMenuInMenu:(NSMenu *)menu
{
    // The application menu is the menu in the menu bar that contains the
    // 'Quit' item. When changing menu bar (e.g when switching between
    // windows with different menu bars), we never recreate this menu, but
    // instead pull it out the current menu bar and place into the new one:
    NSMenu *mainMenu = [NSApp mainMenu];
    if (mainMenu == menu)
        return; // nothing to do (menu is the current menu bar)!

#ifndef QT_NAMESPACE
    Q_ASSERT(mainMenu);
#endif
    // Grab the app menu out of the current menu.
    auto unparentAppMenu = ^bool (NSMenu *supermenu) {
        auto index = [supermenu indexOfItemWithSubmenu:appMenu];
        if (index != -1) {
            [supermenu removeItemAtIndex:index];
            return true;
        }
        return false;
    };

    if (!mainMenu || !unparentAppMenu(mainMenu))
        if (appMenu.supermenu)
            unparentAppMenu(appMenu.supermenu);

    NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple"
                               action:nil keyEquivalent:@""];
    appMenuItem.submenu = appMenu;
    [menu insertItem:appMenuItem atIndex:0];
}

- (NSMenu *)menu
{
    return [[theMenu retain] autorelease];
}

- (NSMenu *)applicationMenu
{
    return [[appMenu retain] autorelease];
}

- (NSMenuItem *)quitMenuItem
{
    return [[quitItem retain] autorelease];
}

- (NSMenuItem *)preferencesMenuItem
{
    return [[preferencesItem retain] autorelease];
}

- (NSMenuItem *)aboutMenuItem
{
    return [[aboutItem retain] autorelease];
}

- (NSMenuItem *)aboutQtMenuItem
{
    return [[aboutQtItem retain] autorelease];
}

- (NSMenuItem *)hideMenuItem
{
    return [[hideItem retain] autorelease];
}

- (NSMenuItem *)appSpecificMenuItem:(QCocoaMenuItem *)platformItem
{
    // No reason to create the item if it already exists.
    for (NSMenuItem *item in appMenu.itemArray)
        if (qt_objc_cast<QCocoaNSMenuItem *>(item).platformMenuItem == platformItem)
            return item;

    // Create an App-Specific menu item, insert it into the menu and return
    // it as an autorelease item.
    QCocoaNSMenuItem *item;
    if (platformItem->isSeparator())
        item = [QCocoaNSMenuItem separatorItemWithPlatformMenuItem:platformItem];
    else
        item = [[[QCocoaNSMenuItem alloc] initWithPlatformMenuItem:platformItem] autorelease];

    const auto location = [self indexOfLastAppSpecificMenuItem];
    [appMenu insertItem:item atIndex:NSInteger(location) + 1];

    return item;
}

- (void)orderFrontStandardAboutPanel:(id)sender
{
    [NSApp orderFrontStandardAboutPanel:sender];
}

- (void)hideOtherApplications:(id)sender
{
    [NSApp hideOtherApplications:sender];
}

- (void)unhideAllApplications:(id)sender
{
    [NSApp unhideAllApplications:sender];
}

- (void)hide:(id)sender
{
    [NSApp hide:sender];
}

- (void)qtTranslateApplicationMenu
{
#ifndef QT_NO_TRANSLATION
    aboutItem.title = qt_mac_applicationmenu_string(AboutAppMenuItem).arg(qt_mac_applicationName()).toNSString();
    preferencesItem.title = qt_mac_applicationmenu_string(PreferencesAppMenuItem).toNSString();
    servicesItem.title = qt_mac_applicationmenu_string(ServicesAppMenuItem).toNSString();
    hideItem.title = qt_mac_applicationmenu_string(HideAppMenuItem).arg(qt_mac_applicationName()).toNSString();
    hideAllOthersItem.title = qt_mac_applicationmenu_string(HideOthersAppMenuItem).toNSString();
    showAllItem.title = qt_mac_applicationmenu_string(ShowAllAppMenuItem).toNSString();
    quitItem.title = qt_mac_applicationmenu_string(QuitAppMenuItem).arg(qt_mac_applicationName()).toNSString();
#endif
}

- (BOOL)validateMenuItem:(NSMenuItem*)menuItem
{
    if (menuItem.action == @selector(hideOtherApplications:)
        || menuItem.action == @selector(unhideAllApplications:))
        return [NSApp validateMenuItem:menuItem];

    if (menuItem.action == @selector(hide:)) {
        if (QCocoaIntegration::instance()->activePopupWindow())
            return NO;
        return [NSApp validateMenuItem:menuItem];
    }

    return menuItem.enabled;
}

- (NSArray<NSMenuItem *> *)mergeable
{
    // Don't include the quitItem here, since we want it always visible and enabled regardless
    auto items = [NSArray arrayWithObjects:preferencesItem, aboutItem,  aboutQtItem,
                  appMenu.itemArray[[self indexOfLastAppSpecificMenuItem]], nil];
    return items;
}

- (NSUInteger)indexOfLastAppSpecificMenuItem
{
    // Either the 'Preferences', which is the first app specific menu item, or something
    // else we appended later (thus the reverse order):
    const auto location = [appMenu.itemArray indexOfObjectWithOptions:NSEnumerationReverse
                           passingTest:^BOOL(NSMenuItem *item, NSUInteger, BOOL *) {
                               if (auto qtItem = qt_objc_cast<QCocoaNSMenuItem*>(item))
                                   return qtItem != quitItem;
                              return NO;
                           }];
    Q_ASSERT(location != NSNotFound);
    return location;
}


@end
