/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * Copyright (C) 2019 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 2 of the License, 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, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */
#include "homepagewidget.h"
#include "ui_homepagewidget.h"

#include <QLabel>
#include <QSignalMapper>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QListWidget>
#include <QDBusInterface>
#include <QDebug>
#include <QScrollBar>
#include <QStringList>

#include <QSvgRenderer>

#include <kysdk/applications/accessinfohelper.h>

#include "mainwindow.h"
#include "utils/functionselect.h"
#include "interface/ukcccommon.h"
using namespace ukcc;
#include "flowlayout.h"
#include "utils/modulefactory.h"

#define STYLE_FONT_SCHEMA  "org.ukui.style"
#define MODULE_LABEL_MAXWIDTH 198

const QStringList KexcludeModule{"update","security","application","search_f"};

HomePageWidget::HomePageWidget(QWidget *parent, QMap<QString, QGSettings *> map) :
    QWidget(parent),
    vecGsettins(map),
    ui(new Ui::HomePageWidget)
{
    qApp->installEventFilter(this);
    ui->setupUi(this);
    // 获取主窗口
    this->setParent(parent);
    pmainWindow = (MainWindow *)parentWidget();

    // 初始化首页
    initUI();
    ui->scrollArea->setBackgroundRole(QPalette::Base);
    ui->scrollArea->verticalScrollBar()->setProperty("drawScrollBarGroove", false);
    ui->scrollArea->verticalScrollBar()->setVisible(false);
    ui->scrollArea->horizontalScrollBar()->setVisible(false);

}

HomePageWidget::~HomePageWidget()
{
    delete ui;
    ui = nullptr;
}

void HomePageWidget::initUI() {
    FlowLayout * flowLayout = new FlowLayout(ui->widget_2, true, 0);
    flowLayout->setContentsMargins(70, 0, 70, 0);
    mModuleMap = UkccCommon::getModuleHideStatus();

    QSignalMapper * moduleSignalMapper = new QSignalMapper(this);
    int totalModule = ModulesFactory::size();
#ifdef WITHKYSEC
        bool isOpen3adm = false;
        if (!kysec_is_disabled() && kysec_get_3adm_status() && (getuid() || geteuid())){
            isOpen3adm = true;
        }
#endif
    for(int index = 0; index < totalModule; index++) {
        ModuleInfo *curModuleInfo = ModulesFactory::getModuleInfoByIndex(index);
        if (curModuleInfo == nullptr) {
            continue;
        }
        //获取当前模块名
        const QString locale = QLocale::system().name();
        QString modulenamei18nString = curModuleInfo->getModuleNameLocale(locale);
        QString modulenameString = curModuleInfo->moduleName;

        if ((mModuleMap.keys().contains(modulenameString) && !mModuleMap[modulenameString].toBool())
                || (UkccCommon::isTablet() && KexcludeModule.contains(modulenameString))) {
            continue;
        }

        // pangw无安全模块-不显示 社区无更新和安全-不显示
        if ((modulenameString == "security" || modulenameString == "update") && UkccCommon::isCommunity()) {
            continue;
        }

        //三权分立下非root用户，不可设置网络、时间语言、更新
#ifdef WITHKYSEC
        if (isOpen3adm){
            if (modulenameString == "network" || modulenameString == "datetime" || modulenameString == "update") {
                continue;
            }
        }
#endif

        //构建首页10个模块
        //基础Widget
        QWidget * baseWidget = new QWidget();
        baseWidget->setAttribute(Qt::WA_DeleteOnClose);
        baseWidget->setObjectName("itemBaseWidget");
        //baseWidget 的顶级布局
        QVBoxLayout * baseVerLayout = new QVBoxLayout(baseWidget);
        baseVerLayout->setMargin(0);
        baseVerLayout->setSpacing(0);
        //包含显示内容的布局
        QBoxLayout * majorHorLayout = new QHBoxLayout();
        majorHorLayout->setMargin(0);
        majorHorLayout->setSpacing(0);

        //内容Widget的构建
        QPushButton * widget = new QPushButton();
        QString picModuleName = modulenameString;
        widget->setMinimumWidth(300);
        widget->setMinimumHeight(97);
        widget->setAttribute(Qt::WA_DeleteOnClose);
        widget->setProperty("useButtonPalette", true);

        if (picModuleName == "search_f") {
            picModuleName = "search";
        }
        widget->setObjectName("itemWidget");
        widget->setFlat(true);
        KDK_EXTEND_ALL_INFO_FORMAT(widget, "", modulenameString, "Button of home page widget");
        QHBoxLayout * mainHorLayout = new QHBoxLayout(widget);
        mainHorLayout->setMargin(16);
        mainHorLayout->setSpacing(16);

        QLabel * logoLabel = new QLabel(widget);
        logoLabel->setFixedSize(48, 48);
        logoLabel->setObjectName("logoLabel");
        KDK_EXTEND_ALL_INFO_FORMAT(logoLabel, "", picModuleName, "logo of home page widget");
        logoLabel->setScaledContents(true);
        QString themeIconName = curModuleInfo->themeIconName;
        QString localIconName = curModuleInfo->localIconName;
        logoLabel->setPixmap(QIcon::fromTheme(themeIconName,QIcon(localIconName))
                             .pixmap(logoLabel->size()));
        const QByteArray settingId(STYLE_FONT_SCHEMA);
        if (QGSettings::isSchemaInstalled(settingId)) {
            QGSettings *mQtSettings = new QGSettings(settingId, QByteArray(), this);
            connect(mQtSettings, &QGSettings::changed, this, [=](QString key) {
                if (key == "iconThemeName") {
                    logoLabel->setPixmap(QIcon::fromTheme(themeIconName,QIcon(localIconName))
                                         .pixmap(logoLabel->size()));
                }
            });
        }
        QVBoxLayout * rightVerLayout = new QVBoxLayout();
        rightVerLayout->setContentsMargins(0, 2, 0, 0);
        rightVerLayout->setSpacing(8);

        QLabel * titleLabel = new QLabel(widget);
        titleLabel->setObjectName("mptitleLabel");
        KDK_EXTEND_ALL_INFO_FORMAT(titleLabel, "", modulenameString, "title of home page widget");
        titleLabel->setText(modulenamei18nString);

        QHBoxLayout * funcHorLayout = new QHBoxLayout();
        funcHorLayout->setSpacing(8);

        uint AllWidth = 0;
        QList<KLabel *> Labels;
        QList<PluginInfo> tmpList = curModuleInfo->pluginInfoList;
        int showModuleCount = 0;
        for (int funcIndex = 0; funcIndex < tmpList.size(); funcIndex++) {
            PluginInfo single = tmpList.at(funcIndex);
            qDebug() << showModuleCount << modulenameString << single.type << single.nameString << single.isEnable << single.namei18nString << single.mainShow;
            // 跳过不在首页显示的功能
            if (!single.mainShow) {
                continue;
            }
            if (mModuleMap.keys().contains(single.nameString.toLower())) {
                if (!mModuleMap[single.nameString.toLower()].toBool()) {
                    continue;
                }
            }
            QObject* pluginObj = ModulesFactory::getPluginObjectByName(single.namei18nString);
            if (pluginObj == nullptr) {
                continue;
            }

            QString textName = single.namei18nString;
            KLabel *label = new KLabel(widget);
            label->installEventFilter(this);
            KDK_EXTEND_ALL_INFO_FORMAT(label, "", single.nameString, "plugin name on home page widget");
            label->setText(textName);
            label->setTristate(true);

            // 除了设计要求不在首页显示的label，其他label均需监听gsetting变化，动态调整首页label显示
            if (vecGsettins.contains(single.oriNameString)) {
                connect(vecGsettins[single.oriNameString], &QGSettings::changed,[=](QString key){
                    if (key == SHOW_KEY) {
                        CommonInterface* pluginInstance = qobject_cast<CommonInterface*>(pluginObj);
                        bool isShow = vecGsettins[single.oriNameString]->get(SHOW_KEY).toBool();
                        qDebug() << "isEnable = " << pluginInstance->isEnable() << isShow;
                        // 动态调整在首页显示的插件池
                        if (isShow) {
                            if (!mLabels[index].contains(label)) {
                                mLabels[index].insert(funcIndex, label);
                            }
                            int MWidth = 0;
                            int shownCount = 0;
                            for (KLabel * label : mLabels[index]) {
                                QFontMetrics fontMetrics(this->font());
                                int fontSize = fontMetrics.width(label->text());
                                // 设置label宽度为字符串宽度，最大为能显示的label的最大宽度
                                label->setFixedWidth(fontSize > MODULE_LABEL_MAXWIDTH ? MODULE_LABEL_MAXWIDTH : fontSize);
                                // 总宽度大于最大宽度
                                if (MWidth + label->width() + funcHorLayout->spacing() > MODULE_LABEL_MAXWIDTH) {
                                    // 已显示的label数量为0
                                    if (shownCount == 0) {
                                        label->setVisible(true);
                                        shownCount++;
                                        MWidth += label->width() + funcHorLayout->spacing();
                                    } else {
                                        label->setVisible(false);
                                    }
                                // 总宽度小于最大宽度
                                } else {
                                    shownCount++;
                                    label->setVisible(true);
                                    MWidth += label->width() + funcHorLayout->spacing();
                                }
                            }
                        } else {
                            if (mLabels[index].contains(label)) {
                                mLabels[index].removeOne(label);
                            }
                            label->setVisible(false);
                        }
                    }
                });
            }

            connect(label, &KLabel::clicked, moduleSignalMapper, [=](){
                moduleSignalMapper->map();
            });
            moduleSignalMapper->setMapping(label, pluginObj);
            funcHorLayout->addWidget(label);

            // 插件未启用直接隐藏该label
            if (vecGsettins.contains(single.oriNameString)) {
               if (!vecGsettins[single.oriNameString]->get(SHOW_KEY).toBool()) {
                   label->setVisible(false);
                   continue;
               } else {
                   Labels.append(label);
               }
            } else {
                // gsetting不存在，判断isenable
                if (!single.isEnable) {
                    label->setVisible(false);
                    continue;
                } else {
                    Labels.append(label);
                }
            }

            qDebug() << AllWidth << label->width() << showModuleCount;
            QFontMetrics fontMetrics(this->font());
            int fontSize = fontMetrics.width(label->text());
            // 设置label宽度为字符串宽度，最大为能显示的label的最大宽度
            label->setFixedWidth(fontSize > MODULE_LABEL_MAXWIDTH ? MODULE_LABEL_MAXWIDTH : fontSize);
            // 总宽度大于最大宽度
            if (AllWidth + label->width() + funcHorLayout->spacing() > MODULE_LABEL_MAXWIDTH) {
                // 已显示的label数量为0
                if (showModuleCount == 0) {
                    label->setVisible(true);
                    showModuleCount++;
                    AllWidth += label->width() + funcHorLayout->spacing();
                } else {
                    label->setVisible(false);
                }
            // 总宽度小于最大宽度
            } else {
                showModuleCount++;
                label->setVisible(true);
                AllWidth += label->width() + funcHorLayout->spacing();
            }
        }

        mLabels.insert(index, Labels);
        funcHorLayout->addStretch();

        // 下属无插件，不显示
        if (curModuleInfo->pluginInfoList.size() == 0 || showModuleCount == 0) {
            widget->setVisible(false);
            continue;
        }

        const QByteArray styleID(STYLE_FONT_SCHEMA);
        QGSettings *stylesettings = new QGSettings(styleID, QByteArray(), this);
        connect(stylesettings,&QGSettings::changed, [=](QString key) {
            if ("systemFont" == key || "systemFontSize" == key) {
                 int MWidth = 0;
                 int showModuleCount = 0;
                 for (KLabel * label : Labels) {
                     QFontMetrics fontMetrics(this->font());
                     int fontSize = fontMetrics.width(label->text());
                     // 设置label宽度为字符串宽度，最大为能显示的label的最大宽度
                     label->setFixedWidth(fontSize > MODULE_LABEL_MAXWIDTH ? MODULE_LABEL_MAXWIDTH:fontSize);
                     if (MWidth + label->width() + funcHorLayout->spacing() > MODULE_LABEL_MAXWIDTH) {
                         if (showModuleCount == 0) {
                             label->setVisible(true);
                             showModuleCount++;
                             MWidth += label->width() + funcHorLayout->spacing();
                         } else {
                             label->setVisible(false);
                         }
                     } else {
                         showModuleCount++;
                         label->setVisible(true);
                         MWidth += label->width() + funcHorLayout->spacing();
                     }
                 }
            }
        });
        connect(widget, &QPushButton::clicked, [=]() {
            //获取模块的第一项跳转
            QString firstFunc;
            QList<PluginInfo> tmpList = curModuleInfo->pluginInfoList;
            for (PluginInfo tmpStruct : tmpList) {
                bool isIntel = UkccCommon::isTablet();

                if ((isIntel && tmpStruct.namei18nString == "User Info")
                      || (!isIntel && tmpStruct.namei18nString == "User Info Intel")) {
                    continue;
                }

                if (!tmpStruct.isEnable) {
                    continue;
                }
                QObject* pluginObj = ModulesFactory::getPluginObjectByName(tmpStruct.namei18nString);
                if (pluginObj == nullptr) {
                    continue;
                }

                // 若该插件不启用，跳转为下一项
                if (vecGsettins.contains(tmpStruct.nameString)) {
                    QGSettings *msettings = vecGsettins[tmpStruct.nameString];
                    if (msettings) {
                        if (!msettings->get(SHOW_KEY).toBool()) {
                            continue;
                        }
                    }
                }
                if (mModuleMap.isEmpty() || !mModuleMap.contains(tmpStruct.nameString.toLower()) || mModuleMap[tmpStruct.nameString.toLower()].toBool()) {
                    firstFunc = tmpStruct.namei18nString;
                    UkccCommon::buriedSettings(tmpStruct.nameString, nullptr, "home clicked");
                    //跳转
                    pmainWindow->functionBtnClicked(pluginObj);
                    break;
                }
            }
        });

        rightVerLayout->addStretch();
        rightVerLayout->addWidget(titleLabel);
        rightVerLayout->addLayout(funcHorLayout);
        rightVerLayout->addStretch();

        mainHorLayout->addWidget(logoLabel);
        mainHorLayout->addLayout(rightVerLayout);
        mainHorLayout->addStretch();

        widget->setLayout(mainHorLayout);

        majorHorLayout->addWidget(widget);
        majorHorLayout->addStretch();

        baseVerLayout->addLayout(majorHorLayout);
        baseVerLayout->addStretch();

        baseWidget->setLayout(baseVerLayout);

        flowLayout->addWidget(baseWidget);
    }
    connect(moduleSignalMapper, SIGNAL(mapped(QObject*)), pmainWindow, SLOT(pluginBtnClicked(QObject*)));
}

QGSettings *HomePageWidget::setGsettingsPath(QList<char *> list ,  QString name)
{
    // 为每个插件创建动态QGSettings对象，用于监听插件是否隐藏
    QByteArray ba;
    char *path;
    ba = (QString("%1%2").arg(name).arg("/")).toUtf8();
    path = ba.data();
    const QByteArray id(PLUGINS_SCHEMA);
    if (!QGSettings::isSchemaInstalled(id)) {
        return nullptr;
    }
    QGSettings *settings = nullptr;
    QString plugin = QString("%1%2%3").arg(PLUGINS_PATH).arg(name).arg("/");
    settings = new QGSettings(id, plugin.toUtf8().data(), this);

    //判断是否已存在该路径,不存在则赋初值
    for (int j = 0; j < list.count(); j++) {
        if (!qstrcmp(path, list.at(j))){
            return settings;
        }
    }
    settings->set(PLUGIN_NAME , name);
    settings->set(SHOW_KEY , true);
    return settings;
}

const QPixmap HomePageWidget::loadSvg(const QString &fileName, COLOR color)
{
    int size = 48;
    const auto ratio = qApp->devicePixelRatio();
    if ( 2 == ratio) {
        size = 96;
    } else if (3 == ratio) {
        size = 144;
    }
    QPixmap pixmap(size, size);
    QSvgRenderer renderer(fileName);
    pixmap.fill(Qt::transparent);

    QPainter painter;
    painter.begin(&pixmap);
    renderer.render(&painter);
    painter.end();

    pixmap.setDevicePixelRatio(ratio);
    return drawSymbolicColoredPixmap(pixmap, color);
}

QPixmap HomePageWidget::drawSymbolicColoredPixmap(const QPixmap &source, COLOR cgColor)
{
    QImage img = source.toImage();
    for (int x = 0; x < img.width(); x++) {
        for (int y = 0; y < img.height(); y++) {
            auto color = img.pixelColor(x, y);
            if (color.alpha() > 0) {
                if ( WHITE == cgColor) {
                    color.setRed(255);
                    color.setGreen(255);
                    color.setBlue(255);
                    img.setPixelColor(x, y, color);
                } else if( BLACK == cgColor) {
                    color.setRed(0);
                    color.setGreen(0);
                    color.setBlue(0);
                    img.setPixelColor(x, y, color);
                } else if (GRAY == cgColor) {
                    color.setRed(152);
                    color.setGreen(163);
                    color.setBlue(164);
                    img.setPixelColor(x, y, color);
                } else if(HIGHLIGHT == cgColor){
                    QColor highLightColor = palette().color(QPalette::Highlight);
                    color.setRed(highLightColor.red());
                    color.setGreen(highLightColor.green());
                    color.setBlue(highLightColor.blue());
                    img.setPixelColor(x, y, color);
                }
                else {
                    return source;
                }
            }
        }
    }
    return QPixmap::fromImage(img);
}


bool HomePageWidget::eventFilter(QObject *watched, QEvent *event)
{
    if (event->type() == QEvent::MouseButtonPress) {
        foreach (QList<KLabel *> labels, mLabels) {
            foreach (KLabel *label, labels) {
                if (label == watched) {
                    return true;
                }
            }
        }
    }
    if (event->type() == QEvent::MouseMove) {
        if (ui->scrollArea->geometry().contains(this->mapFromGlobal(QCursor::pos()))) {
            ui->scrollArea->verticalScrollBar()->setVisible(true);
        } else {
            ui->scrollArea->verticalScrollBar()->setVisible(false);
        }
    }
    return QObject::eventFilter(watched, event);
}

