/*
 *  SPDX-FileCopyrightText: 2009 Alan Alpert <alan.alpert@nokia.com>
 *  SPDX-FileCopyrightText: 2010 Ménard Alexis <menard@kde.org>
 *  SPDX-FileCopyrightText: 2010 Marco Martin <mart@kde.org>
 *
 *  SPDX-License-Identifier: LGPL-2.0-or-later
 */

#include "kirigamicontrolsplugin.h"

#include <QIcon>
#if defined(Q_OS_ANDROID)
#include <QResource>
#endif
#include <QQmlContext>
#include <QQuickItem>

#include "platform/styleselector.h"

#ifdef KIRIGAMI_BUILD_TYPE_STATIC
#include "loggingcategory.h"
#include <QDebug>
#endif

using namespace Qt::StringLiterals;

// This is required for declarative registration to work on Windows.
// This is normally generated by Qt but since we need a manually written plugin
// file, we need to include this ourselves.
extern void qml_register_types_org_kde_kirigami_controls();
Q_GHS_KEEP_REFERENCE(qml_register_types_org_kde_kirigami_controls)

// we can't do this in the plugin object directly, as that can live in a different thread
// and event filters are only allowed in the same thread as the filtered object
class ControlsLanguageChangeEventFilter : public QObject
{
    Q_OBJECT
public:
    bool eventFilter(QObject *receiver, QEvent *event) override
    {
        if (event->type() == QEvent::LanguageChange && receiver == QCoreApplication::instance()) {
            Q_EMIT languageChangeEvent();
        }
        return QObject::eventFilter(receiver, event);
    }

Q_SIGNALS:
    void languageChangeEvent();
};

KirigamiControlsPlugin::KirigamiControlsPlugin(QObject *parent)
    : QQmlExtensionPlugin(parent)
{
    // See above.
    volatile auto registration = &qml_register_types_org_kde_kirigami_controls;
    Q_UNUSED(registration)

    auto filter = new ControlsLanguageChangeEventFilter;
    filter->moveToThread(QCoreApplication::instance()->thread());
    QCoreApplication::instance()->installEventFilter(filter);
    connect(qApp, &QCoreApplication::destroyed, qApp, [filter] {
        delete filter;
    });
}

QUrl KirigamiControlsPlugin::componentUrl(const QString &fileName) const
{
    return Kirigami::Platform::StyleSelector::componentUrlForModule(u"controls"_s, fileName);
}

void KirigamiControlsPlugin::registerTypes(const char *uri)
{
#if defined(Q_OS_ANDROID)
    QResource::registerResource(u"assets:/android_rcc_bundle.rcc"_s);
#endif

    Q_ASSERT(QLatin1String(uri) == "org.kde.kirigami.controls"_L1);

    if (QIcon::themeName().isEmpty() && !qEnvironmentVariableIsSet("XDG_CURRENT_DESKTOP")) {
#if defined(Q_OS_ANDROID)
        // Don't change the old icons location
        QIcon::setThemeSearchPaths({u"assets:/qml/org/kde/kirigami"_s, u":/../icons"_s});
#else
        QIcon::setThemeSearchPaths({Kirigami::Platform::StyleSelector::resolveFilePath(u"."_s), u":/../icons"_s});
#endif
        QIcon::setThemeName(u"breeze-internal"_s);
    } else {
        QIcon::setFallbackSearchPaths(QIcon::fallbackSearchPaths() << Kirigami::Platform::StyleSelector::resolveFilePath(u"../icons"_s));
    }

    qmlRegisterType(componentUrl(u"Action.qml"_s), uri, 2, 0, "Action");
    qmlRegisterType(componentUrl(u"AbstractApplicationHeader.qml"_s), uri, 2, 0, "AbstractApplicationHeader");
    qmlRegisterType(componentUrl(u"AbstractApplicationWindow.qml"_s), uri, 2, 0, "AbstractApplicationWindow");
    qmlRegisterType(componentUrl(u"ApplicationWindow.qml"_s), uri, 2, 0, "ApplicationWindow");
    qmlRegisterType(componentUrl(u"OverlayDrawer.qml"_s), uri, 2, 0, "OverlayDrawer");
    qmlRegisterType(componentUrl(u"ContextDrawer.qml"_s), uri, 2, 0, "ContextDrawer");
    qmlRegisterType(componentUrl(u"GlobalDrawer.qml"_s), uri, 2, 0, "GlobalDrawer");
    qmlRegisterType(componentUrl(u"Heading.qml"_s), uri, 2, 0, "Heading");
    qmlRegisterType(componentUrl(u"PageRow.qml"_s), uri, 2, 0, "PageRow");
    qmlRegisterType(componentUrl(u"OverlaySheet.qml"_s), uri, 2, 0, "OverlaySheet");
    qmlRegisterType(componentUrl(u"Page.qml"_s), uri, 2, 0, "Page");
    qmlRegisterType(componentUrl(u"ScrollablePage.qml"_s), uri, 2, 0, "ScrollablePage");
    qmlRegisterType(componentUrl(u"SwipeListItem.qml"_s), uri, 2, 0, "SwipeListItem");
    qmlRegisterType(componentUrl(u"AbstractApplicationItem.qml"_s), uri, 2, 0, "AbstractApplicationItem");
    qmlRegisterType(componentUrl(u"ApplicationItem.qml"_s), uri, 2, 0, "ApplicationItem");
    qmlRegisterType(componentUrl(u"AbstractCard.qml"_s), uri, 2, 0, "AbstractCard");
    qmlRegisterType(componentUrl(u"Card.qml"_s), uri, 2, 0, "Card");
    qmlRegisterType(componentUrl(u"CardsListView.qml"_s), uri, 2, 0, "CardsListView");
    qmlRegisterType(componentUrl(u"CardsLayout.qml"_s), uri, 2, 0, "CardsLayout");
    qmlRegisterType(componentUrl(u"InlineMessage.qml"_s), uri, 2, 0, "InlineMessage");
    qmlRegisterType(componentUrl(u"ListItemDragHandle.qml"_s), uri, 2, 0, "ListItemDragHandle");
    qmlRegisterType(componentUrl(u"ActionToolBar.qml"_s), uri, 2, 0, "ActionToolBar");
    qmlRegisterType(componentUrl(u"AboutPage.qml"_s), uri, 2, 0, "AboutPage");
    qmlRegisterType(componentUrl(u"LinkButton.qml"_s), uri, 2, 0, "LinkButton");
    qmlRegisterType(componentUrl(u"UrlButton.qml"_s), uri, 2, 0, "UrlButton");
    qmlRegisterType(componentUrl(u"ActionTextField.qml"_s), uri, 2, 0, "ActionTextField");
    qmlRegisterType(componentUrl(u"SearchField.qml"_s), uri, 2, 0, "SearchField");
    qmlRegisterType(componentUrl(u"PasswordField.qml"_s), uri, 2, 0, "PasswordField");
    qmlRegisterType(componentUrl(u"ListSectionHeader.qml"_s), uri, 2, 0, "ListSectionHeader");
    qmlRegisterType(componentUrl(u"PagePoolAction.qml"_s), uri, 2, 0, "PagePoolAction");
    qmlRegisterType(componentUrl(u"PlaceholderMessage.qml"_s), uri, 2, 0, "PlaceholderMessage");
    qmlRegisterType(componentUrl(u"FlexColumn.qml"_s), uri, 2, 0, "FlexColumn");
    qmlRegisterType(componentUrl(u"AboutItem.qml"_s), uri, 2, 0, "AboutItem");
    qmlRegisterType(componentUrl(u"NavigationTabBar.qml"_s), uri, 2, 0, "NavigationTabBar");
    qmlRegisterType(componentUrl(u"NavigationTabButton.qml"_s), uri, 2, 0, "NavigationTabButton");
    qmlRegisterType(componentUrl(u"Chip.qml"_s), uri, 2, 0, "Chip");
    qmlRegisterType(componentUrl(u"LoadingPlaceholder.qml"_s), uri, 2, 0, "LoadingPlaceholder");
    qmlRegisterType(componentUrl(u"SelectableLabel.qml"_s), uri, 2, 0, "SelectableLabel");
    qmlRegisterType(componentUrl(u"InlineViewHeader.qml"_s), uri, 2, 0, "InlineViewHeader");
    qmlRegisterType(componentUrl(u"ContextualHelpButton.qml"_s), uri, 2, 0, "ContextualHelpButton");
}

void KirigamiControlsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
{
    Q_UNUSED(uri);
    connect(this, &KirigamiControlsPlugin::languageChangeEvent, engine, &QQmlEngine::retranslate);
}

#ifdef KIRIGAMI_BUILD_TYPE_STATIC
KirigamiControlsPlugin &KirigamiControlsPlugin::getInstance()
{
    static KirigamiControlsPlugin instance;
    return instance;
}

void KirigamiControlsPlugin::registerTypes(QQmlEngine *engine)
{
    if (engine) {
        engine->addImportPath(QLatin1String(":/"));
    } else {
        qCWarning(KirigamiControlsLog)
            << "Registering Kirigami on a null QQmlEngine instance - you likely want to pass a valid engine, or you will want to manually add the "
               "qrc root path :/ to your import paths list so the engine is able to load the plugin";
    }
}
#endif

#include "kirigamicontrolsplugin.moc"
#include "moc_kirigamicontrolsplugin.cpp"
