/*
 * Copyright (C) 2022 ~ 2024 Deepin Technology Co., Ltd.
 *
 * Author:     xupeidong <xupeidong@uniontech.com>
 *
 * Maintainer: xupeidong <xupeidong@uniontech.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "watermark.h"
#include "utils.h"

#include <QApplication>
#include <QDesktopWidget>
#include <QPainter>
#include <QDebug>
#include <QPixmap>
#include <QBitmap>
#include <QPaintEvent>
#include <QScreen>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDBusInterface>
#include <QDBusReply>
#include <QProcess>
#include <QTimer>
#include <QJsonParseError>
#include <QJsonObject>
#include <QSettings>
#include <QStandardPaths>
#include <QFileInfo>
#include <QDBusConnectionInterface>
#include <QDateTime>
#include <QPainterPath>
#include <QX11Info>
#include <QWindow>
#include <QThread>

Q_LOGGING_CATEGORY(WATERMARK, "deepinwatermark")
// 水印配置文件
const QString WATERMARK_CONFIG = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/kwatermark";
const int TIME_INTERVAL = 1000;
const int DEFAULT_ERROR = -4;
const float DENSITY = 0.15;
const int LEAN_ANGLE = -30;

Watermark::Watermark(bool active, QWidget *parent) :
    QWidget(parent),
    m_compositorActive(active)
{
    // 判断当前平台是x11还是wayland
    m_isX11Server = QX11Info::isPlatformX11();
    /*
     * Qt::FramelessWindowHint : 产生一个无窗口边框的窗口,此时用户无法移动该窗口和改变它的大小。
     * Qt::X11BypassWindowManagerHint : 完全忽视窗口管理器,它的作用是产生一个根本不被管理器的无窗口边框的窗口,此时,用户无法使用键盘进行输入,除非手动调用QWidget::ActivateWindow()函数。
     * Qt::WindowStaysOnTopHint : 置于所有窗口最上层
     */
    setAttribute(Qt::WA_ShowWithoutActivating);
    setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint | Qt::Tool | Qt::WindowDoesNotAcceptFocus);
    if (!m_isX11Server) {
        create();
        this->windowHandle()->setProperty("_d_dwayland_window-type", "onScreenDisplay");
    }
    setAttribute(Qt::WA_TranslucentBackground, true);
    setWindowState(Qt::WindowNoState);
    setFocusPolicy(Qt::NoFocus);
    setWindowTitle("deepin-watermark");
    // x11设置鼠标穿透
    if (m_isX11Server) {
        Utils::passInputEvent(winId());
    }
    m_painter = new QPainter(this);
    m_primaryScreenWidth = QGuiApplication::primaryScreen()->geometry().width();
    m_primaryScreenHeight = QGuiApplication::primaryScreen()->geometry().height();

    // 监听lockFront锁屏信号
    QDBusConnection::sessionBus().connect("com.deepin.dde.lockFront", "/com/deepin/dde/lockFront", "com.deepin.dde.lockFront", "Visible", this, SLOT(onlockFrontStatusChanged(bool)));
    QDBusInterface lockFrontInterface("com.deepin.dde.lockFront", "/com/deepin/dde/lockFront", "com.deepin.dde.lockFront");
    m_lockFrontStatus = lockFrontInterface.property("Visible").toBool();

    // TODO: Is it really necessary? Is there a lock screen interface but the lock screen state is entered?
    QDBusConnection::sessionBus().connect("com.deepin.SessionManager", "/com/deepin/SessionManager", "org.freedesktop.DBus.Properties", "PropertiesChanged", "sa{sv}as", this, SLOT(LockProperty(QString, QVariantMap, QStringList)));

    QDBusConnection::sessionBus().connect("com.deepin.dde.shutdownFront", "/com/deepin/dde/shutdownFront", "com.deepin.dde.shutdownFront", "Visible", this, SLOT(onShutdownFrontVisibleChanged(bool)));
    QDBusInterface iface("com.deepin.dde.shutdownFront", "/com/deepin/dde/shutdownFront", "org.freedesktop.DBus.Properties");
    QDBusReply<QVariant> reply = iface.call("Get", "com.deepin.dde.shutdownFront", "Visible");
    if (reply.isValid()) {
        m_shutDownFrontStatus = reply.value().toBool();
    }

    // 监听控制中心字体变化
    QDBusConnection::sessionBus().connect("com.deepin.daemon.Appearance", "/com/deepin/daemon/Appearance", "com.deepin.daemon.Appearance", "Changed", this, SLOT(fontChanged(QString, QString)));

    // 监听时间日期更改
    QDBusConnection::sessionBus().connect("com.deepin.daemon.Timedate", "/com/deepin/daemon/Timedate", "com.deepin.daemon.Timedate", "TimeUpdate", this, SLOT(updateTime()));

    m_currentTime = new QTimer(this);
    m_currentTime->setInterval(TIME_INTERVAL);
    connect(m_currentTime, &QTimer::timeout, this, [this](){
       QString strCurrentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd");
       if (m_currentTimeString != strCurrentTime) {
           m_currentTimeString = strCurrentTime;
           clearMask();
           update();
       }
    });

    initConfig();
    refreshWindow();
}

Watermark::~Watermark()
{
}

void Watermark::clearConfig()
{
    m_isOpen = false;
    m_content = "";
    m_showTime = false;
    m_currentTimeString = "";
    m_fontSize = 11;
    m_transparency = 50;
    m_density = 5;
    m_fontFormate = FORMAT_LEAN;

    m_showUsrName = false;
    m_usrName = "";
    m_showHostName = false;
    m_hostName = "";
    m_showTerminalAliasName = false;
    m_terminalAliasName = "";
    m_showIpAddress = false;
    m_ipAddress = "";
    m_showMacAddress = false;
    m_macAddress = "";

    writeConfig();
}

void Watermark::writeConfig()
{
    QSettings settings(WATERMARK_CONFIG, QSettings::IniFormat);
    settings.setIniCodec("UTF8");
    settings.beginGroup("basic");
    settings.setValue("status", m_isOpen);
    settings.setValue("font_size", m_fontSize);
    settings.setValue("transparency", m_transparency);
    settings.setValue("density_grade", m_density);
    settings.setValue("format", m_fontFormate);
    settings.endGroup();

    settings.beginGroup("custom_display");
    settings.setValue("content", m_content);
    settings.setValue("index", m_redisplayOrder.contains(displayCustom) ? m_redisplayOrder[displayCustom] : -1);
    settings.endGroup();

    settings.beginGroup("current_time_display");
    settings.setValue("status", m_showTime);
    settings.setValue("index", m_redisplayOrder.contains(displayTime) ? m_redisplayOrder[displayTime] : -1);
    settings.endGroup();

    settings.beginGroup("username_display");
    settings.setValue("status", m_showUsrName);
    settings.setValue("content", m_usrName);
    settings.setValue("index", m_redisplayOrder.contains(displayUser) ? m_redisplayOrder[displayUser] : -1);
    settings.endGroup();

    settings.beginGroup("hostname_display");
    settings.setValue("status", m_showHostName);
    settings.setValue("content", m_hostName);
    settings.setValue("index", m_redisplayOrder.contains(displayHost) ? m_redisplayOrder[displayHost] : -1);
    settings.endGroup();

    settings.beginGroup("terminal_alias_display");
    settings.setValue("status", m_showTerminalAliasName);
    settings.setValue("content", m_terminalAliasName);
    settings.setValue("index", m_redisplayOrder.contains(displayTerminal) ? m_redisplayOrder[displayTerminal] : -1);
    settings.endGroup();

    settings.beginGroup("ip_address_display");
    settings.setValue("status", m_showIpAddress);
    settings.setValue("content", m_ipAddress);
    settings.setValue("index", m_redisplayOrder.contains(displayIp) ? m_redisplayOrder[displayIp] : -1);
    settings.endGroup();

    settings.beginGroup("mac_address_display");
    settings.setValue("status", m_showMacAddress);
    settings.setValue("content", m_macAddress);
    settings.setValue("index", m_redisplayOrder.contains(displayMac) ? m_redisplayOrder[displayMac] : -1);
    settings.endGroup();
}

void Watermark::readConfig()
{
    m_displayOrder.clear();
    m_redisplayOrder.clear();

    QSettings settings(WATERMARK_CONFIG, QSettings::IniFormat);
    settings.setIniCodec("UTF8");
    m_isOpen = settings.value("basic/status").toBool();
    m_fontSize = settings.value("basic/font_size").toInt();
    m_transparency = settings.value("basic/transparency").toInt();
    m_density = settings.value("basic/density_grade").toInt();
    m_fontFormate = settings.value("basic/format").toInt();

    m_content = settings.value("custom_display/content").toString();
    int index = settings.value("custom_display/index").toInt();
    if (index >= 0) {
        m_displayOrder.insert(index, displayCustom);
        m_redisplayOrder.insert(displayCustom, index);
    }

    m_showTime = settings.value("current_time_display/status").toBool();
    index = settings.value("current_time_display/index").toInt();
    if (index >= 0) {
        m_displayOrder.insert(index, displayTime);
        m_redisplayOrder.insert(displayTime, index);
    }

    m_showUsrName = settings.value("username_display/status").toBool();
    m_usrName = settings.value("username_display/content").toString();
    index = settings.value("username_display/index").toInt();
    if (index >= 0) {
        m_displayOrder.insert(index, displayUser);
        m_redisplayOrder.insert(displayUser, index);
    }

    m_showHostName = settings.value("hostname_display/status").toBool();
    m_hostName = settings.value("hostname_display/content").toString();
    index = settings.value("hostname_display/index").toInt();
    if (index >= 0) {
        m_displayOrder.insert(index, displayHost);
        m_redisplayOrder.insert(displayHost, index);
    }

    m_showTerminalAliasName = settings.value("terminal_alias_display/status").toBool();
    m_terminalAliasName = settings.value("terminal_alias_display/content").toString();
    index = settings.value("terminal_alias_display/index").toInt();
    if (index >= 0) {
        m_displayOrder.insert(index, displayTerminal);
        m_redisplayOrder.insert(displayTerminal, index);
    }

    m_showIpAddress = settings.value("ip_address_display/status").toBool();
    m_ipAddress = settings.value("ip_address_display/content").toString();
    index = settings.value("ip_address_display/index").toInt();
    if (index >= 0) {
        m_displayOrder.insert(index, displayIp);
        m_redisplayOrder.insert(displayIp, index);
    }

    m_showMacAddress = settings.value("mac_address_display/status").toBool();
    m_macAddress = settings.value("mac_address_display/content").toString();
    index = settings.value("mac_address_display/index").toInt();
    if (index >= 0) {
        m_displayOrder.insert(index, displayMac);
        m_redisplayOrder.insert(displayMac, index);
    }
}

bool Watermark::isValidInvoker(const uint &pid)
{
    QFileInfo fileInfo(QString("/proc/%1/exe").arg(pid));
    if (!fileInfo.exists()) {
        return false;
    }
    readConfig();
    QString invokerPath = fileInfo.canonicalFilePath().split("/").last();
    return m_whiteProcess.contains(invokerPath);
}

void Watermark::updateVisable()
{
    m_watermarkStatus = m_isOpen && !m_lockFrontStatus && !m_shutDownFrontStatus && !m_lockPropertyStatus;
    if (m_watermarkStatus)
        show();
    else
        hide();
}


void Watermark::refreshWindow()
{
    clearMask();

    if (m_showTime) {
        m_currentTimeString = QDateTime::currentDateTime().toString("yyyy-MM-dd");
        m_currentTime->start();
    } else {
        m_currentTime->stop();
    }
    updateVisable();
    update();
}

QString Watermark::getCustomContent() const
{
    // 水印顺序:自定义内容+用户名+主机名+终端别名+当前时间+IP地址+MAC地址
    QString strContent;
    QMap<int, int>::const_iterator i = m_displayOrder.constBegin();
    while (i != m_displayOrder.constEnd())
    {
        switch (i.value())
        {
        case displayCustom:
            if (!m_content.isEmpty()) {
                strContent.append(m_content + " ");
            }
            break;
        case displayUser:
            if (m_showUsrName) {
                strContent.append(m_usrName + " ");
            }
            break;
        case displayHost:
            if (m_showHostName) {
                strContent.append(m_hostName + " ");
            }
            break;
        case displayTerminal:
            if (m_showTerminalAliasName) {
                strContent.append(m_terminalAliasName + " ");
            }
            break;
        case displayTime:
            if (m_showTime) {
                strContent.append(m_currentTimeString + " ");
            }
            break;
        case displayIp:
            if (m_showIpAddress) {
                strContent.append(m_ipAddress + " ");
            }
            break;
        case displayMac:
            if (m_showMacAddress) {
                strContent.append(m_macAddress + " ");
            }
            break;
        default:
            break;
        }
        ++i;
    }

    return strContent.trimmed();
}

QString Watermark::jsonAutoTest() const
{
    QJsonObject jsonObj;
    jsonObj.insert("status", true);
    jsonObj.insert("custom_content", "xxx");
    jsonObj.insert("current_time_display", true);
    jsonObj.insert("font_size", 11);
    jsonObj.insert("transparency", 50);
    jsonObj.insert("density_grade", 15);
    jsonObj.insert("format", 1);
    QJsonObject objUsrname;
    objUsrname.insert("status", true);
    objUsrname.insert("content", "xxx");
    jsonObj.insert("username_display", objUsrname);
    QJsonObject objHostname;
    objHostname.insert("status", true);
    objHostname.insert("content", "xxx");
    jsonObj.insert("hostname_display", objHostname);
    QJsonObject objTerminal;
    objTerminal.insert("status", true);
    objTerminal.insert("content", "xxx");
    jsonObj.insert("terminal_alias_display", objTerminal);
    QJsonObject objIpaddress;
    objIpaddress.insert("status", true);
    objIpaddress.insert("content", "xxx");
    jsonObj.insert("ip_address_display", objIpaddress);
    QJsonObject objMacaddress;
    objMacaddress.insert("status", true);
    objMacaddress.insert("content", "xxx");
    jsonObj.insert("mac_address_display", objMacaddress);
    QJsonDocument doc;
    doc.setObject(jsonObj);
    return QString(doc.toJson(QJsonDocument::Compact));
}

int Watermark::calculateCoordinate(const int &index, const int &textWidth, const int &hSpace)
{
    int startX = 0;
    int tmpWidth = index * hSpace;
    if (tmpWidth == hSpace) {
        startX = hSpace;
    }else {
        // 计算本行首个水印需要展示的位置
        QStringList listSpace = QString::number(float(tmpWidth) / textWidth, 'f', 2).split(".");
        if (listSpace.size() > 1) {
            if (listSpace.at(1).toInt() > 0) {
                startX = -(textWidth - (listSpace.at(1).toFloat() / 100) * textWidth);
            }
        }
    }
    return startX;
}

bool Watermark::watermarkStatus() const
{
    return m_watermarkStatus;
}

void Watermark::compositingSetup()
{
    qCDebug(WATERMARK) << "kwin compositor setup" << __FUNCTION__ << __LINE__;
    // 部分机器防止2D切3D的时候屏幕闪黑，先隐藏水印
    hide();
}

bool Watermark::watermarkOpen()
{
    return m_isOpen;
}

bool Watermark::lockFrontStatus()
{
    return m_lockFrontStatus;
}

void Watermark::setScreenWatermark(const QString &strPolicy)
{
    qCDebug(WATERMARK) << strPolicy << __FUNCTION__ << __LINE__ ;
    m_displayOrder.clear();
    m_redisplayOrder.clear();

    bool isUpdateConf = true;
    QJsonObject jsonObj;
    QJsonParseError jsonError;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(strPolicy.toUtf8(), &jsonError);
    if (jsonError.error == QJsonParseError::NoError) {
        if (jsonDoc.isObject()) {
            jsonObj = jsonDoc.object();
            if (jsonObj.contains("status")) {
                m_isOpen = jsonObj.take("status").toBool();
            }
            if (jsonObj.contains("custom_display")) {
                QJsonObject objContent = jsonObj.take("custom_display").toObject();
                if (objContent.contains("content")) {
                    m_content = objContent.take("content").toString();
                }
                if (objContent.contains("index")) {
                    int i = objContent.take("index").toInt();
                    if (i >= 0) {
                        m_displayOrder.insert(i, displayCustom);
                        m_redisplayOrder.insert(displayCustom, i);
                    }
                }
            }
            if (jsonObj.contains("current_time_display")) {
                QJsonObject objTime = jsonObj.take("current_time_display").toObject();
                if (objTime.contains("status")) {
                   m_showTime = objTime.take("status").toBool(); 
                }
                if (m_showTime && objTime.contains("index")) {
                    int i = objTime.take("index").toInt();
                    if (i >= 0) {
                        m_displayOrder.insert(i, displayTime);
                        m_redisplayOrder.insert(displayTime, i);
                    }
                }
                // m_showTime = jsonObj.take("current_time_display").toBool();
            }
            if (jsonObj.contains("font_size")) {
                int i = jsonObj.take("font_size").toInt();
                if (i >= 0)
                    m_fontSize = i;
            }
            if (jsonObj.contains("transparency")) {
                m_transparency = jsonObj.take("transparency").toInt();
            }
            if (jsonObj.contains("density_grade")) {
                int i = jsonObj.take("density_grade").toInt();
                if (i >= 0)
                   m_density = i;
            }
            if (jsonObj.contains("format")) {
                m_fontFormate = jsonObj.take("format").toInt();
            }
            if (jsonObj.contains("username_display")) {
                QJsonObject objUsername = jsonObj.take("username_display").toObject();
                if (objUsername.contains("status")) {
                    m_showUsrName = objUsername.take("status").toBool();
                }
                if (objUsername.contains("content")) {
                    m_usrName = objUsername.take("content").toString();
                }
                if (m_showUsrName && objUsername.contains("index")) {
                    int i = objUsername.take("index").toInt();
                    if (i >= 0) {
                        m_displayOrder.insert(i, displayUser);
                        m_redisplayOrder.insert(displayUser, i);
                    }
                }
            }
            if (jsonObj.contains("hostname_display")) {
                QJsonObject objHostname = jsonObj.take("hostname_display").toObject();
                if (objHostname.contains("status")) {
                    m_showHostName = objHostname.take("status").toBool();
                }
                if (objHostname.contains("content")) {
                    m_hostName = objHostname.take("content").toString();
                }
                if (m_showHostName && objHostname.contains("index")) {
                    int i = objHostname.take("index").toInt();
                    if (i >= 0) {
                        m_displayOrder.insert(i, displayHost);
                        m_redisplayOrder.insert(displayHost, i);
                    }
                }
            }
            if (jsonObj.contains("terminal_alias_display")) {
                QJsonObject objTerminalName = jsonObj.take("terminal_alias_display").toObject();
                if (objTerminalName.contains("status")) {
                    m_showTerminalAliasName = objTerminalName.take("status").toBool();
                }
                if (objTerminalName.contains("content")) {
                    m_terminalAliasName = objTerminalName.take("content").toString();
                }
                if (m_showTerminalAliasName && objTerminalName.contains("index")) {
                    int i = objTerminalName.take("index").toInt();
                    if (i >= 0) {
                        m_displayOrder.insert(i, displayTerminal);
                        m_redisplayOrder.insert(displayTerminal, i);
                    }
                }
            }
            if (jsonObj.contains("ip_address_display")) {
                QJsonObject objIpaddress = jsonObj.take("ip_address_display").toObject();
                if (objIpaddress.contains("status")) {
                    m_showIpAddress = objIpaddress.take("status").toBool();
                }
                if (objIpaddress.contains("content")) {
                    m_ipAddress = objIpaddress.take("content").toString();
                }
                if (m_showIpAddress && objIpaddress.contains("index")) {
                    int i = objIpaddress.take("index").toInt();
                    if (i >= 0) {
                        m_displayOrder.insert(i, displayIp);
                        m_redisplayOrder.insert(displayIp, i);
                    }
                }
            }
            if (jsonObj.contains("mac_address_display")) {
                QJsonObject objMacaddress = jsonObj.take("mac_address_display").toObject();
                if (objMacaddress.contains("status")) {
                    m_showMacAddress = objMacaddress.take("status").toBool();
                }
                if (objMacaddress.contains("content")) {
                    m_macAddress = objMacaddress.take("content").toString();
                }
                if (m_showMacAddress && objMacaddress.contains("index")) {
                    int i = objMacaddress.take("index").toInt();
                    if (i >= 0) {
                        m_displayOrder.insert(i, displayMac);
                        m_redisplayOrder.insert(displayMac, i);
                    }
                }
            }
        }
    } else {
        isUpdateConf = false;
        qCDebug(WATERMARK) << "this string is not a json object" << __FUNCTION__ << __LINE__;
    }
    if (isUpdateConf) {
        writeConfig();
        refreshWindow();
    }
}

void Watermark::initConfig()
{
    QFile file(WATERMARK_CONFIG);
    if (file.exists()) {
        readConfig();
    } else {
        if (file.open(QIODevice::ReadOnly | QIODevice::WriteOnly)) {
            writeConfig();
            file.close();
        }
    }
}

void Watermark::paintEvent(QPaintEvent *event)
{
    if (nullptr == m_painter) {
        return;
    }

    // 获取水印展示内容
    QString text = getCustomContent();
    // 如果水印文案为空的时候，2D下会出现黑屏
    if (text.isEmpty()) {
        hide();
        return;
    }

    int pixmapWidth = m_screenWidth;
    int pixmapHeight = m_screenHeight;
    // 计算旋转矩阵
    QTransform transform;
    int transformx = m_x;
    int transformy = m_y;
    if (m_fontFormate == FORMAT_LEAN) {
        transform.translate(m_screenWidth / 2, m_screenHeight / 2);
        transform.rotate(LEAN_ANGLE);
        transform.translate(-m_screenWidth / 2, -m_screenHeight / 2);
        transformx = transform.m11() * 0 + transform.m21() * 0 + transform.dx();
        transformy = transform.m22() * 0 + transform.m12() * m_screenWidth + transform.dy();
        pixmapWidth = m_screenWidth + qAbs(transformx) * 2;
        pixmapHeight = m_screenHeight + qAbs(transformy) * 2;
    }

    QPixmap pixmap(pixmapWidth, pixmapHeight);
    pixmap.fill(Qt::transparent);
    m_painter->begin(&pixmap);
    m_painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    QFont font = m_painter->font();
    font.setFamily(m_fontFamily);
    font.setPointSize(m_fontSize);
    m_painter->setFont(font);
    //根据分辨率设置密度
    int hSpace = 0;
    int vSpace = 0;
    if (m_compositorActive) {
        hSpace = m_primaryScreenWidth * (m_density / 100.0f);
        vSpace = m_primaryScreenHeight * (m_density / 100.0f);
    }else {
        hSpace = m_primaryScreenWidth * DENSITY;
        vSpace = m_primaryScreenHeight * DENSITY;
    }
    // 获取字体的长和宽
    QFontMetrics fm(font);
    QRect rec = fm.boundingRect(text);
    int textWidth = hSpace + rec.width();
    int textHeight = vSpace + rec.height();
    int index = 0;
    bool isBreak = false;
    // 设置绘制区域
    int xStart = 0;
    int yStart = rec.height();
    int xEnd = m_screenWidth;
    int yEnd = m_screenHeight;
    if (m_fontFormate == FORMAT_LEAN) {
        xStart = transformx;
        yStart = transformy;
        xEnd = pixmapWidth;
        yEnd = pixmapHeight;
    }
    int borderTransparency = 3;
    for (int yCoord = yStart; yCoord < yEnd; yCoord += textHeight, index++) {
        isBreak = false;
        for (int xCoord = xStart; xCoord < xEnd; xCoord += textWidth) {
            if (index > 0) {
                if (!isBreak) {
                    isBreak = true;
                    xCoord = calculateCoordinate(index, textWidth, hSpace);
                }
            }

            m_painter->save();
            // 2D下的旋转
            if (m_fontFormate == FORMAT_HORIZONTAL && !m_compositorActive) {
                m_painter->rotate(0);
            }else if (m_fontFormate == FORMAT_LEAN && !m_compositorActive) {
                m_painter->translate(pixmapWidth / 2, pixmapHeight / 2);
                m_painter->rotate(LEAN_ANGLE);
                m_painter->translate(-pixmapWidth / 2, -pixmapHeight / 2);
            }
            QPen pen;
            pen.setWidth(1);
            if (m_compositorActive) {
                QPainterPath path;
                path.addText(xCoord, yCoord, font, text);
                pen.setColor(QColor("#000000"));
                {
                    // 描边的透明度是0到5,默认3%,字体透明度是0到20%时，描边的透明度都是1%,以此类推
                    if (m_transparency >= 0 && m_transparency <= 20) {
                        borderTransparency = 1;
                    } else if (m_transparency > 20 && m_transparency <= 40) {
                        borderTransparency = 2;
                    } else if (m_transparency > 40 && m_transparency <= 60) {
                        borderTransparency = 3;
                    } else if (m_transparency > 60 && m_transparency <= 80) {
                        borderTransparency = 4;
                    } else if (m_transparency > 80 && m_transparency <= 100) {
                        borderTransparency = 5;
                    }
                    m_painter->setOpacity(borderTransparency / 100.0f);
                }
                m_painter->strokePath(path, pen);
                m_painter->drawPath(path);
                {
                    // 文字的透明度是0到100,默认50%
                    m_painter->setOpacity(m_transparency / 100.0f);
                }
                m_painter->fillPath(path, QBrush(QColor("#DFDFDF")));
            } else {
                pen.setColor(QColor("#DFDFDF"));
                m_painter->setPen(pen);
                m_painter->drawText(xCoord, yCoord, text);
            }
            m_painter->restore();
        }
    }
    m_painter->end();
    
    if (!m_isX11Server) {
        setMask(QRegion(0,0,1,1));
    } else {
        if (!m_compositorActive) {
            setMask(pixmap.mask());
        }
    }
    m_painter->begin(this);
    int pixmapX = 0;
    int pixmapY = 0;
    // 3D下的旋转
    if (m_fontFormate == FORMAT_HORIZONTAL && m_compositorActive) {
        m_painter->rotate(0);
    }else if (m_fontFormate == FORMAT_LEAN && m_compositorActive) {
        m_painter->setTransform(transform);
        pixmapX = transformx;
        pixmapY = transformy;
    }
    m_painter->drawPixmap(QPoint(pixmapX, pixmapY), pixmap);
    m_painter->end();
    event->accept();
}

void Watermark::setWaterMarkGeometry(int x, int y, int width, int height)
{
    m_x = x;
    m_y = y;
    m_screenWidth = width;
    m_screenHeight = height;
    setGeometry(x, y, width, height);
}

void Watermark::onlockFrontStatusChanged(bool visible)
{
    // 监听到锁屏界面状态
    if (m_lockFrontStatus == visible)
        return;
    m_lockFrontStatus = visible;
    if (!m_lockFrontStatus) {
        QThread::msleep(200);
    }
    updateVisable();
}

void Watermark::onShutdownFrontVisibleChanged(bool visible)
{
    if (m_shutDownFrontStatus == visible)
        return;

    m_shutDownFrontStatus = visible;
    updateVisable();
}


void Watermark::fontChanged(const QString &fontType, const QString &fontName)
{
    if (fontType == "standardfont" || fontType == "monospacefont") {
        clearMask();
        m_fontFamily = fontName;
        update();
    }
}

void Watermark::updateTime()
{
    m_currentTimeString = QDateTime::currentDateTime().toString("yyyy-MM-dd");
    clearMask();
    update();
}

void Watermark::displayProperty(QString type, QVariantMap map, QStringList list)
{
    Q_UNUSED(type);
    Q_UNUSED(list);
    if (map.contains("ScreenWidth")) {
        m_screenWidth = map.take("ScreenWidth").toInt();
    }
    if (map.contains("ScreenHeight")) {
        m_screenHeight = map.take("ScreenHeight").toInt();
    }
    m_primaryScreenWidth = QGuiApplication::primaryScreen()->geometry().width();
    m_primaryScreenHeight = QGuiApplication::primaryScreen()->geometry().height();
    clearMask();
    setGeometry(0, 0, m_screenWidth, m_screenHeight);
    update();
}

void Watermark::LockProperty(QString type, QVariantMap map, QStringList list)
{
    Q_UNUSED(type);
    Q_UNUSED(list);

    if (map.contains("Locked")) {
        m_lockPropertyStatus = map.take("Locked").toBool();
        if (!m_lockPropertyStatus)
            QThread::msleep(200);
        updateVisable();
    }
}
