/*
 * UKUI Framework
 *
 * Copyright (C) 2024, KylinSoft Co., Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library.  If not, see <https://www.gnu.org/licenses/>.
 *
 * Authors: Yue Lan <lanyue@kylinos.cn>
 *
 */

#include "background.h"

#include <QImageReader>

#include <QGSettings/QGSettings>

#undef signals
#include <gio/gio.h>

//决定如何显示墙纸文件名指定的图片。可用的值有：居中、拉伸、填充、平铺、适应、跨区
const QStringList supportOptions = {"centered", "stretched", "scaled", "wallpaper", "zoom", "spanned"};

QByteArray g_bgSettingsSchema = "org.ukui.interface";

bool g_backgroundServiceAvailable = true;

Background::Background(QObject *parent)
    : QObject{parent}
{
    if (QGSettings::isSchemaInstalled(g_bgSettingsSchema)) {
        if (QGSettings::isSchemaInstalled("org.mate.background")) {
            // 壁纸设置兼容
            // 如果是旧版本的ukui，需要监听org.mate.background
            g_bgSettingsSchema = "org.mate.background";
        }
        auto settings = new QGSettings(g_bgSettingsSchema);
        settings->setParent(this);
        BackgroundFile = settings->get("pictureFilename").toString();
        BackgroundOption = settings->get("pictureOptions").toString();

        connect(settings, &QGSettings::changed, this, [=](const QString &key){
            if (key == "pictureFilename") {
                BackgroundFile = settings->get("pictureFilename").toString();
                emit BackgroundFileChanged();
            } else if (key == "pictureOptions") {
                BackgroundOption = settings->get("pictureOptions").toString();
                emit BackgroundOptionChanged();
            }
        });
    } else {
        // 如果没有org.ukui.interface则使用org.mate.background
        if (QGSettings::isSchemaInstalled("org.mate.background")) {
            // 监听org.mate.background
            g_bgSettingsSchema = "org.mate.background";

            auto settings = new QGSettings(g_bgSettingsSchema);
            settings->setParent(this);
            BackgroundFile = settings->get("pictureFilename").toString();
            BackgroundOption = settings->get("pictureOptions").toString();

            connect(settings, &QGSettings::changed, this, [=](const QString &key){
                if (key == "pictureFilename") {
                    BackgroundFile = settings->get("pictureFilename").toString();
                    emit BackgroundFileChanged();
                } else if (key == "pictureOptions") {
                    BackgroundOption = settings->get("pictureOptions").toString();
                    emit BackgroundOptionChanged();
                }
            });
        } else {
            // 设置壁纸功能不可用
            g_backgroundServiceAvailable = false;
        }
    }
}

Background::~Background()
{

}

const QString Background::GetBackgroundFile() const
{
    if (!g_backgroundServiceAvailable) {
        if (calledFromDBus()) {
            sendErrorReply(QDBusError::InvalidService, tr("Background service is not available"));
        }
    }
    return BackgroundFile;
}

bool Background::SetBackgroundFile(const QString &filePath)
{
    if (!g_backgroundServiceAvailable) {
        if (calledFromDBus()) {
            sendErrorReply(QDBusError::InvalidService, tr("Background service is not available"));
        }
        return false;
    }

    if (BackgroundFile == filePath) {
        if (calledFromDBus()) {
            sendErrorReply(QDBusError::Failed, tr("Can not set background repeatly"));
        }
        return false;
    }

    QImageReader imgReader(filePath);
    if (!imgReader.canRead()) {
        if (calledFromDBus()) {
            sendErrorReply(QDBusError::NotSupported, tr("Can not read image from: %1").arg(filePath));
        }
        return false;
    }

    g_autoptr (GSettings) scopedSettings = g_settings_new(g_bgSettingsSchema.constData());
    if (g_settings_set_string(scopedSettings, "picture-filename", filePath.toLocal8Bit().constData())) {
        return true;
    }

    return false;
}

const QStringList Background::GetSupportedBackgroundOptions()
{
    if (!g_backgroundServiceAvailable) {
        if (calledFromDBus()) {
            sendErrorReply(QDBusError::InvalidService, tr("Background service is not available"));
        }
    }
    return supportOptions;
}

const QString Background::GetBackgroundOption() const
{
    if (!g_backgroundServiceAvailable) {
        if (calledFromDBus()) {
            sendErrorReply(QDBusError::InvalidService, tr("Background service is not available"));
        }
    }
    return BackgroundOption;
}

bool Background::SetBackgroundOption(const QString &option)
{
    if (!g_backgroundServiceAvailable) {
        if (calledFromDBus()) {
            sendErrorReply(QDBusError::InvalidService, tr("Background service is not available"));
        }
        return false;
    }

    if (BackgroundOption == option)
        return false;

    if (supportOptions.contains(option)) {
        g_autoptr (GSettings) scopedSettings = g_settings_new(g_bgSettingsSchema.constData());
        if (g_settings_set_string(scopedSettings, "picture-options", option.toLocal8Bit().constData())) {
            return true;
        }
    } else {
        if (calledFromDBus()) {
            sendErrorReply(QDBusError::InvalidArgs, tr("Invalid background option: %s, support options: [%1]").arg(supportOptions.join(", ")));
        }
        return false;
    }

    return false;
}
