/*
* Copyright (C) 2020 Tianjin KYLIN Information Technology Co., Ltd.
*
* 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, or (at your option)
* 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/&gt;.
*
*/
#include "wifiwidget.h"
#include <QApplication>
#include <QPalette>

WifiWidget::WifiWidget(QWidget *parent) : QWidget(parent)
{
    initMemberVariables();
    initLayout();
    updateIcon();
    initNetworkManagerConnect();
}

WifiWidget::~WifiWidget()
{

}

//变量初始化
void WifiWidget::initMemberVariables()
{
    m_pWifiIconLabel = new QLabel(this);
    m_pWifiIconLabel->setFixedSize(24, 24);

    m_pWifihNameLabel = new QLabel(this);
    m_pWifihNameLabel->setText("");
    m_pWifihNameLabel->setFixedSize(68, 18);

    QPalette palette;
    palette.setBrush(QPalette::WindowText, Qt::black);

    QFont ft;
    ft.setPixelSize(12);
    m_pWifihNameLabel->setFont(ft);
    m_pWifihNameLabel->setAlignment(Qt::AlignHCenter);

    m_pWidgetButton = new WifiLabel(this);

    this->setStyle(new customstyle_switchNormalStatus("ukui-default"));
    this->setFixedSize(148, 56);
    this->setContentsMargins(0, 0, 0, 0);

    return;
}

/* 初始化布局 */
void WifiWidget::initLayout()
{
    m_pHboxButtonLayout = new QHBoxLayout(this);
    m_pHboxButtonLayout->setContentsMargins(0, 0, 0, 0);
    m_pHboxButtonLayout->setSpacing(0);
    m_pHboxButtonLayout->addItem(new QSpacerItem(12, 4));
    m_pHboxButtonLayout->addWidget(m_pWifiIconLabel);
    m_pHboxButtonLayout->addItem(new QSpacerItem(8, 4));
    m_pHboxButtonLayout->addWidget(m_pWifihNameLabel);
    m_pHboxButtonLayout->addItem(new QSpacerItem(18, 4));
    m_pHboxButtonLayout->addWidget(m_pWidgetButton);
    m_pHboxButtonLayout->addItem(new QSpacerItem(4, 1));
    this->setLayout(m_pHboxButtonLayout);

    return;
}

void WifiWidget::initNetworkManagerConnect()
{
    QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"),
                                         QString("/org/freedesktop/NetworkManager"),
                                         QString("org.freedesktop.NetworkManager"),
                                         QString("PropertiesChanged"), this, SLOT(onPropertiesChanged(QVariantMap)));
}


//更新图标
void WifiWidget::updateIcon()
{
    bool isFindWifi = false;
    QString wifiName("");
    QString wifiDbusPath("");
    int wifisignal = 0;

    QDBusInterface interface( "org.freedesktop.NetworkManager",
                              "/org/freedesktop/NetworkManager",
                              "org.freedesktop.DBus.Properties",
                              QDBusConnection::systemBus() );

    //获取已经连接了那些网络，及这些网络对应的网络类型(ethernet or wifi)
    QDBusMessage result = interface.call("Get", "org.freedesktop.NetworkManager", "ActiveConnections");
    QList<QVariant> outArgs = result.arguments();
    QVariant first = outArgs.at(0);
    QDBusVariant dbvFirst = first.value<QDBusVariant>();
    QVariant vFirst = dbvFirst.variant();
    QDBusArgument dbusArgs = vFirst.value<QDBusArgument>();

    QDBusObjectPath objPath;
    dbusArgs.beginArray();
    while (!dbusArgs.atEnd()) {
        dbusArgs >> objPath;
        QDBusInterface interface( "org.freedesktop.NetworkManager",
                                  objPath.path(),
                                  "org.freedesktop.DBus.Properties",
                                  QDBusConnection::systemBus() );

        QDBusReply<QVariant> replyType = interface.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Type");
        if (replyType.isValid()) {
            QDBusReply<QVariant> replyId = interface.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Id");
            if (replyId.isValid()) {
                if (replyType.value().toString() == "802-3-ethernet") {
                    m_pWifiIconLabel->setPixmap((QIcon::fromTheme(KYLIN_LINE_PRESS_NAME, QIcon(KYLIN_LINE_PRESS_PATH))).pixmap(m_pWifiIconLabel->size()));
                    setLabelText(m_wired_connection);
                    return;
                } else if (replyType.value().toString() == "802-11-wireless" && !isFindWifi) {
                    isFindWifi = true;
                    wifiName = replyId.value().toString();
                    QDBusMessage reply = interface.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "SpecificObject");
                    QDBusObjectPath dbusPathIp4 = reply.arguments().at(0).value<QDBusVariant>().variant().value<QDBusObjectPath>();
                    wifiDbusPath = dbusPathIp4.path();
                } else {
                    qWarning() << "not wireless or wired :" << replyType.value().toString();
                }
            }
        }
    }
    if (isFindWifi) {
        getWifiSignal(wifiDbusPath,wifisignal);
        setwifi(wifiName,wifisignal);
    } else {
        setwifi("", -1);
    }
}

//获取信号强度
void WifiWidget::getWifiSignal(const QString dBusPath, int& singalStrength)
{
    singalStrength = 0;

    QDBusInterface interface("org.freedesktop.NetworkManager",
                              dBusPath,
                              "org.freedesktop.DBus.Properties",
                              QDBusConnection::systemBus());

    QDBusReply<QVariant> reply = interface.call("Get", "org.freedesktop.NetworkManager.AccessPoint", "Strength");
    if (reply.isValid()) {
        singalStrength = reply.value().toInt();
    }
}

//获取无线网络开关
bool WifiWidget::checkWifiIsEnable()
{
    QDBusInterface interface( "org.freedesktop.NetworkManager",
                              "/org/freedesktop/NetworkManager",
                              "org.freedesktop.DBus.Properties",
                              QDBusConnection::systemBus() );

    QDBusReply<QVariant> reply = interface.call("Get", "org.freedesktop.NetworkManager", "WirelessEnabled");
    if (reply.isValid()) {
        return reply.value().toBool();
    }
    return false;
}

//wifi图标计算
void WifiWidget::setwifi(QString wifiName, int wifisignal)
{
    if (wifisignal <= 75 && wifisignal > 55){
        m_pWifiIconLabel->setPixmap((QIcon::fromTheme(KYLIN_WIFI_80_PATH_NAME, QIcon(KYLIN_WIFI_80_PATH))).pixmap(m_pWifiIconLabel->size()));
    } else if (wifisignal <= 55 && wifisignal > 35){
        m_pWifiIconLabel->setPixmap((QIcon::fromTheme(KYLIN_WIFI_30_PATH_NAME, QIcon(KYLIN_WIFI_30_PATH))).pixmap(m_pWifiIconLabel->size()));
    } else if (wifisignal <= 35 && wifisignal > 15){
        m_pWifiIconLabel->setPixmap((QIcon::fromTheme(KYLIN_WIFI_10_PATH_NAME, QIcon(KYLIN_WIFI_10_PATH))).pixmap(m_pWifiIconLabel->size()));
    } else if (wifisignal == -1 || wifisignal <= 15) {
        m_pWifiIconLabel->setPixmap((QIcon::fromTheme(KYLIN_WIFI_no_PATH_NAME, QIcon(KYLIN_WIFI_NO_PATH))).pixmap(m_pWifiIconLabel->size()));
    } else if (wifisignal > 75) {
        m_pWifiIconLabel->setPixmap((QIcon::fromTheme(KYLIN_WIFI_100_PATH_NAME, QIcon(KYLIN_WIFI_100_PATH))).pixmap(m_pWifiIconLabel->size()));
    }
    if (wifiName == "") {
        if (checkWifiIsEnable()) {
            wifiName = m_not_Connected;
        } else {
            wifiName = m_closed;
        }
    }
    setLabelText(wifiName);
}


void WifiWidget::paintEvent(QPaintEvent *event)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);

    p.setBrush(qApp->palette().color(QPalette::Button));
    p.setOpacity(0.3);
    p.setPen(Qt::NoPen);
    p.setRenderHint(QPainter::Antialiasing);  // 反锯齿;
    p.drawRoundedRect(opt.rect,28,28);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
    QWidget::paintEvent(event);

}

//点击唤起网络界面
void WifiWidget::mousePressEvent(QMouseEvent *event)
{
    if(event == nullptr) {
        return;
    }
    WifiButtonClickSlot();
    QWidget::mousePressEvent(event);
}

/* wifi按钮槽函数 */
void WifiWidget::WifiButtonClickSlot()
{
    QStringList args;
    args.append("--sw");
    if(!AppManagerDbus::getInstance()->LaunchAppWithArguments("/etc/xdg/autostart/kylin-nm.desktop",args)) {
        qWarning()<<"AppManagerDbus 接口无效，采用QProcess启动";
        QProcess p(0);
        p.startDetached("kylin-nm --sw");
        p.waitForStarted();
    }

    return;
}

//network-manager PropertiesChange信号槽函数
void WifiWidget::onPropertiesChanged(QVariantMap qvm)
{
    for(QString keyStr : qvm.keys()) {
        //有关已连接网络变化的信号
        if (keyStr == "ActiveConnections") {
            updateIcon();
        }
    }
}

//文字设置
void WifiWidget::setLabelText(QString s)
{
    QFontMetrics fontmetrics(m_pWifihNameLabel->font());
    QString format = s;
    format=fontmetrics.elidedText(format,Qt::ElideRight,m_pWifihNameLabel->width(),Qt::TextShowMnemonic);
    m_pWifihNameLabel->setText(format);
    m_pWifihNameLabel->repaint();
}

WifiLabel::WifiLabel(QWidget *parent) : QLabel(parent)
{
    this->setFixedSize(30, 20);
    QPixmap myPix(KYLIN_WIFI_PRESS_PATH);
    this->setPixmap(myPix);
}

void WifiLabel::mouseReleaseEvent(QMouseEvent *ev)
{
    Q_UNUSED(ev);
    emit LabelClicked();
}
