/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Labs Platform module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickplatformmenubar_p.h"
#include "qquickplatformmenu_p.h"

#include <QtCore/qloggingcategory.h>
#include <QtGui/qpa/qplatformmenu.h>
#include <QtGui/qpa/qplatformtheme.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtQuick/qquickwindow.h>
#include <QtQuick/qquickitem.h>

QT_BEGIN_NAMESPACE

/*!
    \qmltype MenuBar
    \inherits QtObject
//!     \instantiates QQuickPlatformMenuBar
    \inqmlmodule Qt.labs.platform
    \since 5.8
    \brief A native menubar.

    The MenuBar type provides a QML API for native platform menubars.

    \image qtlabsplatform-menubar.png

    A menubar consists of a list of drop-down menus.

    \code
    MenuBar {
        id: menuBar

        Menu {
            id: fileMenu
            title: qsTr("File")
            // ...
        }

        Menu {
            id: editMenu
            title: qsTr("&Edit")
            // ...
        }

        Menu {
            id: viewMenu
            title: qsTr("&View")
            // ...
        }

        Menu {
            id: helpMenu
            title: qsTr("&Help")
            // ...
        }
    }
    \endcode

    MenuBar is currently available on the following platforms:

    \list
    \li macOS
    \li Android
    \li Linux (only available on desktop environments that provide a global D-Bus menu bar)
    \endlist

    \labs

    \sa Menu
*/

Q_DECLARE_LOGGING_CATEGORY(qtLabsPlatformMenus)

QQuickPlatformMenuBar::QQuickPlatformMenuBar(QObject *parent)
    : QObject(parent),
      m_complete(false),
      m_window(nullptr),
      m_handle(nullptr)
{
    m_handle = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar();
    qCDebug(qtLabsPlatformMenus) << "MenuBar ->" << m_handle;
}

QQuickPlatformMenuBar::~QQuickPlatformMenuBar()
{
    for (QQuickPlatformMenu *menu : qAsConst(m_menus))
        menu->setMenuBar(nullptr);
    delete m_handle;
    m_handle = nullptr;
}

QPlatformMenuBar *QQuickPlatformMenuBar::handle() const
{
    return m_handle;
}

/*!
    \default
    \qmlproperty list<Object> Qt.labs.platform::MenuBar::data

    This default property holds the list of all objects declared as children of
    the menubar. The data property includes objects that are not \l Menu instances,
    such as \l Timer and \l QtObject.

    \sa menus
*/
QQmlListProperty<QObject> QQuickPlatformMenuBar::data()
{
    return QQmlListProperty<QObject>(this, nullptr, data_append, data_count, data_at, data_clear);
}

/*!
    \qmlproperty list<Menu> Qt.labs.platform::MenuBar::menus

    This property holds the list of menus in the menubar.
*/
QQmlListProperty<QQuickPlatformMenu> QQuickPlatformMenuBar::menus()
{
    return QQmlListProperty<QQuickPlatformMenu>(this, nullptr, menus_append, menus_count, menus_at, menus_clear);
}

/*!
    \qmlproperty Window Qt.labs.platform::MenuBar::window

    This property holds the menubar's window.

    Unless explicitly set, the window is automatically resolved by iterating
    the QML parent objects until a \l Window or an \l Item that has a window
    is found.
*/
QWindow *QQuickPlatformMenuBar::window() const
{
    return m_window;
}

void QQuickPlatformMenuBar::setWindow(QWindow *window)
{
    if (m_window == window)
        return;

    if (m_handle)
        m_handle->handleReparent(window);

    m_window = window;
    emit windowChanged();
}

/*!
    \qmlmethod void Qt.labs.platform::MenuBar::addMenu(Menu menu)

    Adds a \a menu to end of the menubar.
*/
void QQuickPlatformMenuBar::addMenu(QQuickPlatformMenu *menu)
{
    insertMenu(m_menus.count(), menu);
}

/*!
    \qmlmethod void Qt.labs.platform::MenuBar::insertMenu(int index, Menu menu)

    Inserts a \a menu at the specified \a index in the menubar.
*/
void QQuickPlatformMenuBar::insertMenu(int index, QQuickPlatformMenu *menu)
{
    if (!menu || m_menus.contains(menu))
        return;

    QQuickPlatformMenu *before = m_menus.value(index);
    m_menus.insert(index, menu);
    m_data.append(menu);
    menu->setMenuBar(this);
    if (m_handle)
        m_handle->insertMenu(menu->create(), before ? before->handle() : nullptr);
    menu->sync();
    emit menusChanged();
}

/*!
    \qmlmethod void Qt.labs.platform::MenuBar::removeMenu(Menu menu)

    Removes a \a menu from the menubar.
*/
void QQuickPlatformMenuBar::removeMenu(QQuickPlatformMenu *menu)
{
    if (!menu || !m_menus.removeOne(menu))
        return;

    m_data.removeOne(menu);
    if (m_handle)
        m_handle->removeMenu(menu->handle());
    menu->setMenuBar(nullptr);
    emit menusChanged();
}

/*!
    \qmlmethod void Qt.labs.platform::MenuBar::clear()

    Removes all menus from the menubar.
*/
void QQuickPlatformMenuBar::clear()
{
    if (m_menus.isEmpty())
        return;

    for (QQuickPlatformMenu *menu : qAsConst(m_menus)) {
        m_data.removeOne(menu);
        if (m_handle)
            m_handle->removeMenu(menu->handle());
        menu->setMenuBar(nullptr);
        delete menu;
    }

    m_menus.clear();
    emit menusChanged();
}

void QQuickPlatformMenuBar::classBegin()
{
}

void QQuickPlatformMenuBar::componentComplete()
{
    m_complete = true;
    for (QQuickPlatformMenu *menu : qAsConst(m_menus))
        menu->sync();
    if (!m_window)
        setWindow(findWindow());
}

QWindow *QQuickPlatformMenuBar::findWindow() const
{
    QObject *obj = parent();
    while (obj) {
        QWindow *window = qobject_cast<QWindow *>(obj);
        if (window)
            return window;
        QQuickItem *item = qobject_cast<QQuickItem *>(obj);
        if (item && item->window())
            return item->window();
        obj = obj->parent();
    }
    return nullptr;
}

void QQuickPlatformMenuBar::data_append(QQmlListProperty<QObject> *property, QObject *object)
{
    QQuickPlatformMenuBar *menuBar = static_cast<QQuickPlatformMenuBar *>(property->object);
    QQuickPlatformMenu *menu = qobject_cast<QQuickPlatformMenu *>(object);
    if (menu)
        menuBar->addMenu(menu);
    else
        menuBar->m_data.append(object);
}

int QQuickPlatformMenuBar::data_count(QQmlListProperty<QObject> *property)
{
    QQuickPlatformMenuBar *menuBar = static_cast<QQuickPlatformMenuBar *>(property->object);
    return menuBar->m_data.count();
}

QObject *QQuickPlatformMenuBar::data_at(QQmlListProperty<QObject> *property, int index)
{
    QQuickPlatformMenuBar *menuBar = static_cast<QQuickPlatformMenuBar *>(property->object);
    return menuBar->m_data.value(index);
}

void QQuickPlatformMenuBar::data_clear(QQmlListProperty<QObject> *property)
{
    QQuickPlatformMenuBar *menuBar = static_cast<QQuickPlatformMenuBar *>(property->object);
    menuBar->m_data.clear();
}

void QQuickPlatformMenuBar::menus_append(QQmlListProperty<QQuickPlatformMenu> *property, QQuickPlatformMenu *menu)
{
    QQuickPlatformMenuBar *menuBar = static_cast<QQuickPlatformMenuBar *>(property->object);
    menuBar->addMenu(menu);
}

int QQuickPlatformMenuBar::menus_count(QQmlListProperty<QQuickPlatformMenu> *property)
{
    QQuickPlatformMenuBar *menuBar = static_cast<QQuickPlatformMenuBar *>(property->object);
    return menuBar->m_menus.count();
}

QQuickPlatformMenu *QQuickPlatformMenuBar::menus_at(QQmlListProperty<QQuickPlatformMenu> *property, int index)
{
    QQuickPlatformMenuBar *menuBar = static_cast<QQuickPlatformMenuBar *>(property->object);
    return menuBar->m_menus.value(index);
}

void QQuickPlatformMenuBar::menus_clear(QQmlListProperty<QQuickPlatformMenu> *property)
{
    QQuickPlatformMenuBar *menuBar = static_cast<QQuickPlatformMenuBar *>(property->object);
    menuBar->clear();
}

QT_END_NAMESPACE
