/*
 * SPDX-FileCopyrightText: 2015 Kai Uwe Broulik <kde@privat.broulik.de>
 *
 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
 */

#include "grabwidget.h"

#include <QApplication>
#include <QClipboard>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDBusMetaType>
#include <QDBusPendingCall>
#include <QDBusPendingCallWatcher>
#include <QDBusPendingReply>
#include <QMimeData>

#include <KSystemClipboard>

#include <limits>

Q_DECLARE_METATYPE(QColor)

QDBusArgument &operator<<(QDBusArgument &argument, const QColor &color)
{
    argument.beginStructure();
    argument << color.rgba();
    argument.endStructure();
    return argument;
}

const QDBusArgument &operator>>(const QDBusArgument &argument, QColor &color)
{
    argument.beginStructure();
    QRgb rgba;
    argument >> rgba;
    argument.endStructure();
    color = QColor::fromRgba(rgba);
    return argument;
}

GrabWidget::GrabWidget(QObject *parent)
    : QObject(parent)
{
    qDBusRegisterMetaType<QColor>();
}

QColor GrabWidget::currentColor() const
{
    return m_currentColor;
}

void GrabWidget::setCurrentColor(const QColor &color)
{
    // don't return early if color is unchanged; the widget needs the Changed signal
    // to know that a color has been picked
    m_currentColor = color;

    Q_EMIT currentColorChanged();
}

void GrabWidget::pick()
{
    QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"),
                                                      QStringLiteral("/ColorPicker"),
                                                      QStringLiteral("org.kde.kwin.ColorPicker"),
                                                      QStringLiteral("pick"));
    auto call = QDBusConnection::sessionBus().asyncCall(msg, std::numeric_limits<int>::max());
    QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this);
    connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
        watcher->deleteLater();
        QDBusPendingReply<QColor> reply = *watcher;
        if (!reply.isError()) {
            setCurrentColor(reply.value());
        }
    });
}

void GrabWidget::copyToClipboard(const QString &text)
{
    auto *mimeData = new QMimeData();
    mimeData->setText(text);
    KSystemClipboard::instance()->setMimeData(mimeData, QClipboard::Clipboard);
}
