/*
 * Kylin-video
 *
 * Copyright (C) 2021, 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 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, see <https://www.gnu.org/licenses/>.
 *
 * Authors: Liu Cong <liucong1@kylinos.cn>
 *
 */

#include "playlistwidget.h"
#include "ui_playlistwidget.h"
#include <QPropertyAnimation>
#include <QVariantAnimation>
#include <QDesktopServices>
#include <QListWidget>
#include <QMouseEvent>
#include <QMessageBox>
#include <QHBoxLayout>
#include <QGSettings>
#include <QScrollBar>
#include <QProcess>
#include <QThread>
#include <QDebug>
#include <QUuid>
#include <QDir>

#include "ukui-log4qt.h"
#include "global/functions.h"
#include "global/extensions.h"
#include "global/global.h"
#include "global/paths.h"
#include "ukui-wayland/waylanddialog.h"
#include "kmenu.h"
#include "ffutil.h"
#include "playlist.h"
#include "imagelabel.h"
#include "messagebox.h"
#include "tipwidget/tipwidget.h"

#include "elog.h"
#define LOG_TAG "playlist"

qint64 tests, teste;

using namespace Global;
using namespace KylinUI;

PlayListWidget::PlayListWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::PlayListWidget)
{
    ui->setupUi(this);
    setMaximumWidth(330);
    initStackedWidget();

    //
    QFont f("Noto Sans CJK SC Regular");
    f.setPixelSize(14);
    ui->list_title->setFont(f);

    m_isShow = false;
    m_isMouseEnter = false;

    initMenu();
    // 设置展开按钮属性和样式
    ui->btn_left->setCursor(Qt::PointingHandCursor);
    ui->btn_left->setFixedSize(16, 80);
    m_playListWidget->setStyleSheet("QListWidget{background-color: rgba(255, 255, 255, 0);}"
                                  "QListWidget::item::selected{background-color:rgba(1,1,1,0);}");
    m_markListWidget->setStyleSheet("QListWidget{background-color: rgba(255, 255, 255, 0);}"
                                       "QListWidget::item::selected{background-color:rgba(1,1,1,0);}");
    m_playListWidget->verticalScrollBar()->setProperty("drawScrollBarGroove", false);
    m_markListWidget->verticalScrollBar()->setProperty("drawScrollBarGroove", false);
    initConnection();

    ui->top->setFixedHeight(48);
    ui->btn_order->setFixedSize(16, 16);
    ui->btn_order->setCursor(Qt::PointingHandCursor);

    // 切换列表视图按钮
    ui->btn_view->setFixedSize(16, 16);
    ui->btn_view->setCursor(Qt::PointingHandCursor);
    // 播放列表视图模式
    if(!g_settings->contains("General/list_view"))
        g_settings->setValue("General/list_view", 0);
    m_mode = (ListViewMode)g_settings->value("General/list_view").toInt();

    ui->btn_add->setFixedSize(16, 16);
    ui->btn_add->setCursor(Qt::PointingHandCursor);
    ui->btn_delete->setFixedSize(16, 16);
    ui->btn_delete->setCursor(Qt::PointingHandCursor);

    m_playListWidget->setSpacing(0);
    m_playListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    m_markListWidget->setSpacing(0);
    m_markListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    initDefaultWidget();

    ui->list_title->setFlow(QListView::LeftToRight);
    ui->list_title->addItems(QStringList() << tr("Video") << tr("Marks"));
    for(int i=0; i<ui->list_title->count(); i++)
    {
        QListWidgetItem *it = ui->list_title->item(i);
        it->setTextAlignment(Qt::AlignCenter);
        it->setSizeHint(QSize(50, 24));
    }
    ui->list_title->setFixedWidth(130);
    ui->list_title->setCurrentRow(0);
    ui->list_title->setSpacing(0);
    ui->list_title->setFixedHeight(30);
    ui->list_title->setStyleSheet("QListWidget{background-color: rgba(1,1,1,0);border-radius:10px;}"
                                  "QListWidget::item{border-radius:12px;color:#A6A6A6;}"
                                  "QListWidget::item::selected{background-color:rgba(1,1,1,0);color:rgb(55,144,250);}"
                                  "QListWidget::item::hover{background-color:#f5f5f5;}");
    connect(ui->list_title, &QListWidget::currentRowChanged, [this](int currentRow){
        if (currentRow == 1) {
            ui->btn_add->hide();
        }
        else {
            ui->btn_add->show();
        }
        if (currentRow == 0) {
            currentRow = m_itemMap.size() == 0 ? 2 : 0;
        }
        ui->stackedWidget->setCurrentIndex(currentRow);
        ui->widget_btnline->move(ui->widget_2->width() / 4 - ui->widget_btnline->width() / 2 + currentRow * (ui->widget_2->width() / 2), 0);
    });

    ui->widget_btnline->setFixedSize(24, 4);
    ui->widget_btnline->setStyleSheet("border-top-left-radius:3px;"
                                      "border-top-right-radius:3px;"
                                      "background-color:#3790FA;");
    ui->widget_btnline->move(ui->widget_2->width() / 4 - ui->widget_btnline->width() / 2, 0);

    // 设置悬停提示
    ui->btn_add->setToolTip(tr("Add file"));
    ui->btn_delete->setToolTip(tr("Clear list"));

    setAttribute(Qt::WA_TranslucentBackground);

    initPlayList();
    initAnimation();
    initGlobalSig();

    {
        // 根据主题设置样式
        if(g_settings->value("General/follow_system_theme").toBool())
        {
            if(g_gsettings->get("styleName").toString() == STYLE_UKUI_DEFAULT)
                setLightTheme();
            else
                setBlackTheme();
        }
        else
        {
            if(g_settings->value("General/theme").toInt() == 0)
                setLightTheme();
            else
                setBlackTheme();
        }
        // 更新按钮图标
        updateOrderIcon();
        updateViewIcon();
        updateAddIcon();
        updateDeleteIcon();
    }
}

PlayListWidget::~PlayListWidget()
{
    delete ui;
}

/** ************************************************************************
 * 显示菜单
 ***************************************************************************/
void PlayListWidget::showItemMenu(QString file)
{
    m_selectedFile = file;
    if (QGuiApplication::focusWindow())
        m_itemMenu->exec(QPoint(QCursor::pos(QGuiApplication::focusWindow()->screen()) + QPoint(1,1)));
}

/** ************************************************************************
 * 添加播放列表条目
 * @param:
 *      playItem : 添加到列表
 ***************************************************************************/
void PlayListWidget::addItem(PlayItem playItem)
{
    std::lock_guard<std::mutex> lg(m_itemAddMux);
    PlayListItem *itemWidget  = new PlayListItem;
    connect(itemWidget, &PlayListItem::sigExistsStateChange, this, [this](QString path, bool exist){
        if (exist)
            m_playList->setAvaliable(path);
        else
            m_playList->setNotAvaliable(path);
    });
    connect(itemWidget, &PlayListItem::sigRightBPressed, this, &PlayListWidget::showItemMenu, Qt::QueuedConnection);
    QListWidgetItem *listItem = new QListWidgetItem;
    switch (m_mode) {
    case LIST:
        listItem->setSizeHint(QSize(314, 40));
        break;
    case VIEW:
        listItem->setSizeHint(QSize(314, 74));
        break;
    default:
        break;
    }

    m_playListWidget->addItem(listItem);
    m_playListWidget->setItemWidget(listItem, itemWidget);
    m_itemMap[playItem.m_filePath] = listItem;

    itemWidget->setData(playItem.m_filePath, playItem.m_duration, playItem.m_lastStopTime, playItem.m_previewPath);

    // 样式播放列表视图改变
    connect(itemWidget, &PlayListItem::sigValChange, [this, listItem](int _val){
        listItem->setSizeHint(QSize(m_playListWidget->width(), _val+20));
    });
    itemWidget->setMode(m_mode);

    itemWidget->setObjectName(playItem.m_filePath);
    itemWidget->installEventFilter(this);
    if (ui->list_title->currentRow() == 0 && ui->stackedWidget->currentIndex() == 2) {
        ui->stackedWidget->setCurrentIndex(0);
    }
}

void PlayListWidget::deleteItem(QString _file)
{
    if(m_itemMap.find(_file) != m_itemMap.end())
    {
        m_playListWidget->itemWidget(m_itemMap[_file])->removeEventFilter(this);
        delete m_playListWidget->itemWidget(m_itemMap[_file]);
        m_playListWidget->removeItemWidget(m_itemMap[_file]);
        if(m_itemMap[_file])
            delete m_itemMap[_file];
        m_itemMap.remove(_file);
    }
    if (m_itemMap.size() == 0 && ui->stackedWidget->currentIndex() == 0 && ui->list_title->currentRow() == 0) {
        ui->stackedWidget->setCurrentIndex(2);
    }
}

void PlayListWidget::clearList()
{
    // 如果列表为空就不要弹出对话框了
    if(m_playList->getSize() == 0)
        return;
    MessageBox box(tr("Video Player"), tr("Are you sure you want to clear the list?"), nullptr, KylinUI::QUESTION);
    int res = box.exec();
    if (res == QDialog::Accepted ) {
        if(m_playList->getPlayState() > 0) {
            MessageBox box1(tr("Video Player"), tr("The file being played will be stopped."), nullptr, KylinUI::QUESTION);
            res = box1.exec();
        }
        if (res == QDialog::Accepted) {
            m_playList->clearList();
            if (ui->list_title->currentRow() == 0) {
                ui->stackedWidget->setCurrentIndex(2);
            }
        }
    }
}

void PlayListWidget::updateMarks(QVector<MarkItem> markvec)
{
    clearMark();
    for (MarkItem mark : markvec) {
        MarkListItem *item = new MarkListItem;
        connect(item, &MarkListItem::sigDeleteMark, this, &PlayListWidget::deleteMark);
        connect(item, &MarkListItem::sigPlayAndSeek, [this](QString file_path, int pos) {
            if (file_path == m_currentPlayingFile) {
                g_user_signal->seek(pos);
            }
            else {
                g_user_signal->stop();
                g_user_signal->play();
                g_user_signal->open(file_path, pos);
            }
        });
        item->setData(mark.m_filePath, mark.m_duration, mark.m_markPos, mark.m_describe, mark.m_previewPath);
        item->setMode(m_mode);
        if (!mark.m_fileExit) {
            item->setNotExit(mark.m_filePath);
        }

        QListWidgetItem *widgetItem = new QListWidgetItem;
        switch (m_mode) {
        case LIST:
            widgetItem->setSizeHint(QSize(m_markListWidget->width(), 56));
            break;
        case VIEW:
            widgetItem->setSizeHint(QSize(m_markListWidget->width(), 74));
            break;
        default:
            break;
        }

        m_markListWidget->addItem(widgetItem);
        m_markListWidget->setItemWidget(widgetItem, item);
        if (!mark.m_fileExit) {
            item->setNotExit(mark.m_filePath);
        }
    }
}

void PlayListWidget::deleteMark(QString filepath, int pos)
{
    for (int i=0; i<m_markListWidget->count(); i++) {
        QListWidgetItem *item = m_markListWidget->item(i);
        if (((MarkListItem*)m_markListWidget->itemWidget(item))->getPos() == pos &&
                ((MarkListItem*)m_markListWidget->itemWidget(item))->getFilePath() == filepath) {
            // 删除数据库数据，应该交给playlist处理，不要在界面处理
            m_playList->deleteMark(((MarkListItem*)m_markListWidget->itemWidget(item))->getFilePath(), pos);
            // 删除界面
            delete m_markListWidget->itemWidget(item);
            // 删除 item
            m_markListWidget->removeItemWidget(item);
            delete item;
        }
    }
}

void PlayListWidget::clearMark()
{
    while (m_markListWidget->count()) {
        QListWidgetItem *item = m_markListWidget->item(0);
        // 隐藏就不会出发 leaveEvent 了，不然可能会导致崩溃
        m_markListWidget->itemWidget(item)->hide();
        delete m_markListWidget->itemWidget(item);
        m_markListWidget->removeItemWidget(item);
        delete item;
    }
}

// 重新加载缩略图
void PlayListWidget::reloadView(QString file)
{
    std::lock_guard<std::mutex> lg(m_itemAddMux);
    QMap<QString, QListWidgetItem*> tmp_map(m_itemMap);
    if(tmp_map.find(file) != tmp_map.end()) {
        ((PlayListItem*)m_playListWidget->itemWidget(tmp_map[file]))->reloadView();
    }
}

void PlayListWidget::resetDuration(QString file, int duration)
{
    std::lock_guard<std::mutex> lg(m_itemAddMux);
    QMap<QString, QListWidgetItem*> tmp_map(m_itemMap);
    if(tmp_map.find(file) != tmp_map.end()) {
        ((PlayListItem*)m_playListWidget->itemWidget(tmp_map[file]))->setDuration(duration);
    }
}

void PlayListWidget::slotShow()
{
    if (ui->list_title->currentRow() == 0)
        ui->stackedWidget->setCurrentIndex(m_itemMap.size() == 0 ? 2 : 0);

    if(pos().x() == ((QWidget*)parent())->width() - width())
        return;
    raise();

    m_hideAnm->stop();
    m_showAnm->setStartValue(geometry());
    m_showAnm->setEndValue(QRect(((QWidget*)parent())->width() - width(), 0, width(), height()));
    m_showAnm->start();
}

void PlayListWidget::slotHide()
{
    if(pos().x() == ((QWidget*)parent())->width() - 16)
        return;
    m_showAnm->stop();
    m_hideAnm->setStartValue(geometry());
    m_hideAnm->setEndValue(QRect(((QWidget*)parent())->width() - 16, 0, width(), height()));
    m_hideAnm->start();
    // 隐藏的时候把所有 item 中 x 都隐藏了
    for(QListWidgetItem* t_item : m_itemMap)
        ((PlayListItem*)m_playListWidget->itemWidget(t_item))->setLeave();
}

void PlayListWidget::setShowButton(bool show)
{
    if (show) {
        ui->btn_left->show();
    }
    else {
        ui->btn_left->hide();
    }
}

void PlayListWidget::updateShowIcon()
{
    m_showAnm->stop();
    m_hideAnm->stop();

    m_isShow = true;
    QString icoDir;
    if(g_settings->value("General/follow_system_theme").toBool())
    {
        if(g_gsettings->get("styleName").toString() == STYLE_UKUI_DEFAULT)
            icoDir = "ico_light";
        else
            icoDir = "ico";
    }
    else
    {
        if(g_settings->value("General/theme").toInt() == 0)
            icoDir = "ico_light";
        else
            icoDir = "ico";
    }
    ui->btn_left->setStyleSheet(QString("QPushButton:!hover{border-image: url(:/%1/icon-cbl2-d.png);}"
                                "QPushButton:hover{border-image: url(:/%1/icon-cbl2-h.png);}"
                                "QPushButton:pressed{border-image: url(:/%1/icon-cbl2-h.png);}")
                                .arg(icoDir));
    ui->btn_left->show();
}

void PlayListWidget::updateHideIcon()
{
    m_showAnm->stop();
    m_hideAnm->stop();

    m_isShow = false;
    QString icoDir;
    if(g_settings->value("General/follow_system_theme").toBool())
    {
        if(g_gsettings->get("styleName").toString() == STYLE_UKUI_DEFAULT)
            icoDir = "ico_light";
        else
            icoDir = "ico";
    }
    else
    {
        if(g_settings->value("General/theme").toInt() == 0)
            icoDir = "ico_light";
        else
            icoDir = "ico";
    }
    ui->btn_left->setStyleSheet(QString("QPushButton:!hover{border-image: url(:/%1/icon-cbl1-d.png);}"
                                "QPushButton:hover{border-image: url(:/%1/icon-cbl1-h.png);}"
                                "QPushButton:pressed{border-image: url(:/%1/icon-cbl1-h.png);}")
                                .arg(icoDir));
    // 列表隐藏之后需要显示标题栏和控制栏
    g_user_signal->hideBar(false);
}

/** **********************************************
 * 删除可用索引
 * 描述：当播放器打开情况下，播放列表中文件从硬盘中删除
 * @param: _file 要删除的文件名
 *************************************************/
void PlayListWidget::delAvailableIndex(QString _file)
{
    m_playList->setNotAvaliable(_file);
    // 不存在的话播放下一首
    g_user_signal->playNext(false);
}

/** **********************************************
 * 修改视图模式
 *************************************************/
void PlayListWidget::changeListViewMode()
{
    if(m_mode == LIST)
    {
        m_mode = VIEW;
        ui->btn_view->setToolTip(tr("Preview view"));
        int count = m_playListWidget->count();
        for(int i=0; i<count; i++)
            ((PlayListItem*)m_playListWidget->itemWidget(m_playListWidget->item(i)))->toBig();
        count = m_markListWidget->count();
        for (int i=0; i<count; i++) {
            ((MarkListItem*)m_markListWidget->itemWidget(m_markListWidget->item(i)))->setMode(VIEW);
            m_markListWidget->item(i)->setSizeHint(QSize(m_markListWidget->width(), 74));
        }
    }
    else
    {
        m_mode = LIST;
        ui->btn_view->setToolTip(tr("List view"));
        int count = m_playListWidget->count();
        for(int i=0; i<count; i++)
            ((PlayListItem*)m_playListWidget->itemWidget(m_playListWidget->item(i)))->toSmall();
        count = m_markListWidget->count();
        for (int i=0; i<count; i++) {
            ((MarkListItem*)m_markListWidget->itemWidget(m_markListWidget->item(i)))->setMode(LIST);
            m_markListWidget->item(i)->setSizeHint(QSize(m_markListWidget->width(), 56));
        }
    }
    g_settings->setValue("General/list_view", (int)m_mode);
    updateViewIcon();
}

/** **********************************************
 * 设置当前索引
 * @param: _index 索引
 *************************************************/
void PlayListWidget::setPlayIndex(int _index)
{
    // 其他都设置为非选中状态
    selectNone();
    if (_index >= 0 && _index < m_itemMap.size())
        ((PlayListItem*)m_playListWidget->itemWidget(m_playListWidget->item(_index)))->setSelected(true);

}

void PlayListWidget::selectNone()
{
    for (auto item:m_itemMap)
        ((PlayListItem*)m_playListWidget->itemWidget(item))->setSelected(false);
}

void PlayListWidget::setBlackTheme()
{
    m_theme = STYLE_UKUI_BLACK;
    ui->right->setStyleSheet("#right{background-color: rgba(13, 13, 14, 220);"
                             "border-top-left-radius:12px;"
                             "border-bottom-left-radius:12px;}");
    if(m_isShow)
        ui->btn_left->setStyleSheet("QPushButton:!hover{border-image: url(:/ico/icon-cbl2-d.png);}"
                                    "QPushButton:hover{border-image: url(:/ico/icon-cbl2-h.png);}"
                                    "QPushButton:pressed{border-image: url(:/ico/icon-cbl2-h.png);}");
    else
        ui->btn_left->setStyleSheet("QPushButton:!hover{border-image: url(:/ico/icon-cbl1-d.png);}"
                                    "QPushButton:hover{border-image: url(:/ico/icon-cbl1-h.png);}"
                                    "QPushButton:pressed{border-image: url(:/ico/icon-cbl1-h.png);}");
}

void PlayListWidget::setLightTheme()
{
    m_theme = STYLE_UKUI_DEFAULT;
    ui->right->setStyleSheet("#right{background-color: rgba(249, 249, 249, 220);"
                             "border-top-left-radius:12px;"
                             "border-bottom-left-radius:12px;}");
    if(m_isShow)
        ui->btn_left->setStyleSheet("QPushButton:!hover{border-image: url(:/ico_light/icon-cbl2-d.png);}"
                                    "QPushButton:hover{border-image: url(:/ico_light/icon-cbl2-h.png);}"
                                    "QPushButton:pressed{border-image: url(:/ico_light/icon-cbl2-h.png);}");
    else
        ui->btn_left->setStyleSheet("QPushButton:!hover{border-image: url(:/ico_light/icon-cbl1-d.png);}"
                                    "QPushButton:hover{border-image: url(:/ico_light/icon-cbl1-h.png);}"
                                    "QPushButton:pressed{border-image: url(:/ico_light/icon-cbl1-h.png);}");
}

void PlayListWidget::gSettingChanged(QString key)
{
    // 如果不是跟随主题的话直接返回
    if (key == "styleName") {
        if(g_settings->value("General/follow_system_theme").toBool())
        {
            if(g_gsettings->get("styleName").toString() == STYLE_UKUI_DEFAULT)
                setLightTheme();
            else
                setBlackTheme();
            updateOrderIcon();
            updateViewIcon();
            updateAddIcon();
            updateDeleteIcon();
        }
    }
    else if (key == "systemFontSize" || key == "systemFont") {
        // 字体改变
        QString fontFamily = g_gsettings->get("systemFont").toString();
        int fontSize = g_gsettings->get("systemFontSize").toInt();
        QFont f(fontFamily);
        f.setPointSize(fontSize);
        for (auto item : m_itemMap) {
            ((PlayListItem*)m_playListWidget->itemWidget(item))->setWidgetFont(f);
        }
        for (int i=0; i<m_markListWidget->count(); i++) {
            ((MarkListItem*)m_markListWidget->itemWidget(m_markListWidget->item(i)))->setWidgetFont(f);
        }
    }
}

void PlayListWidget::initMenu()
{
    m_itemMenu = new PlayListItemMenu(nullptr);

    connect(m_itemMenu, &PlayListItemMenu::sigClearList, [this](){
        clearList();
    });

    connect(m_itemMenu, &PlayListItemMenu::sigRemoveSelect, [this](){
        m_playList->deleteFile(m_selectedFile);
    });

    connect(m_itemMenu, &PlayListItemMenu::sigRemoveInvalid, [this](){
        // 删除不可用文件
        m_playList->deleteInvalidItems();
    });

    connect(m_itemMenu, &PlayListItemMenu::sigOpenFolder, [this](){
        QProcess p;
        p.start("peony -i \"" + m_selectedFile + "\"");
        p.waitForFinished();

#if 0
        QFileInfo fi(m_selectedFile);

        QString path = fi.absolutePath();
        if(!QDesktopServices::openUrl(QUrl::fromLocalFile(path)))
        {
            // 文件夹打开失败
            log_e("openfile %s error!", path.toStdString().c_str());
        }
#endif
    });
}

void PlayListWidget::initStackedWidget()
{
    m_playListWidget = new QListWidget;
    m_markListWidget = new QListWidget;
    m_playListWidget->setFixedWidth(width() - 16);
    m_markListWidget->setFixedWidth(width() - 16);

    ui->stackedWidget->addWidget(m_playListWidget);
    ui->stackedWidget->addWidget(m_markListWidget);
    initDefaultWidget();
}

void PlayListWidget::initPlayList()
{
    m_playList = new PlayList;

    connect(m_playList, &PlayList::itemAdded,       this, &PlayListWidget::addItem);
    connect(m_playList, &PlayList::sigIndexChange,  this, &PlayListWidget::setPlayIndex);
    connect(m_playList, &PlayList::itemDelete,      this, &PlayListWidget::deleteItem);
    connect(m_playList, &PlayList::sigReloadView,   this, &PlayListWidget::reloadView);
    connect(m_playList, &PlayList::sigResetDuration,this, &PlayListWidget::resetDuration);
    connect(m_playList, &PlayList::sigMarkUpdate,   this, &PlayListWidget::updateMarks);

    m_playList->initData();
    ui->stackedWidget->setCurrentIndex(2);
}

/** **********************************************
 * 初始化全局信号
 *************************************************/
void PlayListWidget::initGlobalSig()
{
    connect(g_user_signal, &GlobalUserSignal::sigShowPlayList, [&](){
        if(m_isShow)
            slotHide();
        else
            slotShow();
    });

    connect(g_user_signal, &GlobalUserSignal::sigHideBar, [&](bool _isHide){
        if(_isHide)
            if(m_isMouseEnter)
                setCursor(QCursor(Qt::ArrowCursor));
    });

    connect(g_user_signal, &GlobalUserSignal::sigPlayOrder, [&](PlayOrder _order){
        m_playOrder = _order;
        updateOrderIcon();
    });

    connect(g_user_signal, &GlobalUserSignal::sigTheme, [&](int _theme){
        switch (_theme) {
        case 0:
            if(g_gsettings->get("styleName").toString() == STYLE_UKUI_DEFAULT)
                setLightTheme();
            else
                setBlackTheme();
            break;
        case 1:
            setLightTheme();
            break;
        case 2:
            setBlackTheme();
            break;
        default:
            break;
        }

        updateOrderIcon();
        updateViewIcon();
        updateAddIcon();
        updateDeleteIcon();
    });

    connect(g_core_signal, &GlobalCoreSignal::sigFileNotExist, this, &PlayListWidget::delAvailableIndex, Qt::QueuedConnection);
    connect(g_core_signal, &GlobalCoreSignal::sigFileInfoChange, this, [this](Mpv::FileInfo fi){
        m_currentPlayingFile = fi.file_path;
    });
    connect(g_core_signal, &GlobalCoreSignal::sigFileLoadedError, this, [this](QString file){
        m_playList->setNotAvaliable(file);
        if (m_isShow)
            TipWidget::showTip(tr("Load file error!"), 1000, QSize(150, 40), m_playListWidget, TipWidget::WARNING);
        else
            TipWidget::showTip(tr("Load file error!"), 1000, QSize(150, 40), parentWidget(), TipWidget::WARNING);
    });
    connect(g_core_signal, &GlobalCoreSignal::sigStateChange, this, [this](Mpv::PlayState state){
        if (state == Mpv::Stopped) {
            selectNone();
        }
    });
}

/** **********************************************
 * 初始化显示隐藏动画
 *************************************************/
void PlayListWidget::initAnimation()
{
    m_showAnm = new QPropertyAnimation(this, "geometry");
    m_showAnm->setDuration(300);
    m_showAnm->setEasingCurve(QEasingCurve::OutCubic);
    connect(m_showAnm, &QPropertyAnimation::finished, this, &PlayListWidget::updateShowIcon);

    m_hideAnm = new QPropertyAnimation(this, "geometry");
    m_hideAnm->setDuration(300);
    m_hideAnm->setEasingCurve(QEasingCurve::OutCubic);
    connect(m_hideAnm, &QPropertyAnimation::finished, this, &PlayListWidget::updateHideIcon);
}

void PlayListWidget::initConnection()
{
    connect(ui->btn_add, &QPushButton::clicked, [](){
        g_user_signal->selectFile();
    });

    connect(ui->btn_view, &QPushButton::clicked, this, &PlayListWidget::changeListViewMode);

    connect(g_gsettings, &QGSettings::changed, this, &PlayListWidget::gSettingChanged);

    connect(ui->btn_left, &QPushButton::clicked, [&](){g_user_signal->showPlayList();});

    connect(ui->btn_order, &QPushButton::clicked, [&](){
        // 点击之后直接切换播放模式
        switch (m_playOrder) {
        case ONE_LOOP:
            m_playOrder = LIST_LOOP;
            break;
        case LIST_LOOP:
            m_playOrder = RANDOM;
            break;
        case RANDOM:
            m_playOrder = ONE_LOOP;
            break;
        default:
            break;
        }
        g_user_signal->setPlayOrder(m_playOrder);
    });

    connect(ui->btn_delete, &QPushButton::clicked, [&](){
        clearList();
    });
}

void PlayListWidget::initDefaultWidget()
{
    // 默认占位符
    QWidget *defaultWidget = new QWidget;
    QVBoxLayout *ly = new QVBoxLayout(defaultWidget);
    ly->addStretch(2);

    QHBoxLayout *hb = new QHBoxLayout;
    QWidget *pic = new QWidget;
    pic->setFixedSize(120, 120);
    pic->setStyleSheet("border-image:url(:/ico/list-home.png);");

    hb->addStretch();
    hb->addWidget(pic);
    hb->addStretch();
    ly->addLayout(hb);

    QLabel *text = new QLabel;
    text->setStyleSheet("color:#8C8C8C;");
    ly->addWidget(text);
    text->setAlignment(Qt::AlignCenter);
    text->setText(tr("Please add file to list ~"));

    ly->addStretch(3);

//    defaultWidget->show();
    ui->stackedWidget->addWidget(defaultWidget);
}

/** **********************************************
 * 更新播放顺序按钮图标
 *************************************************/
void PlayListWidget::updateOrderIcon()
{
    QString icon_file = "";
    switch(m_playOrder)
    {
    case ONE_LOOP:
        icon_file = "media-playlist-repeat-one";
        ui->btn_order->setToolTip(tr("One loop"));
        break;
    case SEQUENCE:
        icon_file = "media-playlist-repeat-list";
        ui->btn_order->setToolTip(tr("Sequential"));
        break;
    case LIST_LOOP:
        icon_file = "media-playlist-repeat-loop";
        ui->btn_order->setToolTip(tr("List loop"));
        break;
    case RANDOM:
        icon_file = "media-playlist-repeat-radom";
        ui->btn_order->setToolTip(tr("Random"));
        break;
    }
    if(m_theme == STYLE_UKUI_DEFAULT)
        ui->btn_order->setStyleSheet(QString("QPushButton:!hover{border-image: url(:/ico_light/%1-b.png);}"
                                     "QPushButton:hover{border-image: url(:/ico_light/%1-h.png);}"
                                     "QPushButton:pressed{border-image: url(:/ico_light/%1-h.png);}")
                                     .arg(icon_file));
    else
        ui->btn_order->setStyleSheet(QString("QPushButton:!hover{border-image: url(:/ico/%1-b.png);}"
                                     "QPushButton:hover{border-image: url(:/ico/%1-h.png);}"
                                     "QPushButton:pressed{border-image: url(:/ico/%1-h.png);}")
                                     .arg(icon_file));
}

void PlayListWidget::updateViewIcon()
{
    QString ico_name;
    if(m_mode == LIST)
        ico_name = "icon-list-symbolic";
    else
        ico_name = "icon-grid-symbolic";

    if(m_theme == STYLE_UKUI_DEFAULT)
        ui->btn_view->setStyleSheet(QString("QPushButton:!hover{border-image: url(:/ico_light/%1-b.png);}"
                                    "QPushButton:hover{border-image: url(:/ico_light/%1-h.png);}"
                                    "QPushButton:pressed{border-image: url(:/ico_light/%1-h.png);}").arg(ico_name));
    else
        ui->btn_view->setStyleSheet(QString("QPushButton:!hover{border-image: url(:/ico/%1-b.png);}"
                                    "QPushButton:hover{border-image: url(:/ico/%1-h.png);}"
                                    "QPushButton:pressed{border-image: url(:/ico/%1-h.png);}").arg(ico_name));
}

void PlayListWidget::updateAddIcon()
{
    if(m_theme == STYLE_UKUI_DEFAULT)
        ui->btn_add->setStyleSheet("QPushButton:!hover{border-image: url(:/ico_light/list-add-symbolic-b.png);}"
                                    "QPushButton:hover{border-image: url(:/ico_light/list-add-symbolic-h.png);}"
                                    "QPushButton:pressed{border-image: url(:/ico_light/list-add-symbolic-h.png);}");
    else
        ui->btn_add->setStyleSheet("QPushButton:!hover{border-image: url(:/ico/list-add-symbolic-b.png);}"
                                    "QPushButton:hover{border-image: url(:/ico/list-add-symbolic-h.png);}"
                                    "QPushButton:pressed{border-image: url(:/ico/list-add-symbolic-h.png);}");
}

void PlayListWidget::updateDeleteIcon()
{
    if(m_theme == STYLE_UKUI_DEFAULT)
        ui->btn_delete->setStyleSheet("QPushButton:!hover{border-image: url(:/ico_light/icon-delect-d.png);}"
                                     "QPushButton:hover{border-image: url(:/ico_light/icon-delect-h.png);}"
                                     "QPushButton:pressed{border-image: url(:/ico_light/icon-delect-h.png);}");
    else
        ui->btn_delete->setStyleSheet("QPushButton:!hover{border-image: url(:/ico/icon-delect-d.png);}"
                                     "QPushButton:hover{border-image: url(:/ico/icon-delect-h.png);}"
                                     "QPushButton:pressed{border-image: url(:/ico/icon-delect-h.png);}");
}

bool PlayListWidget::eventFilter(QObject *watched, QEvent *event)
{
    if(m_itemMap.find(watched->objectName()) != m_itemMap.end() && m_isShow)
    {
#if 0
        if(event->type() == QEvent::MouseButtonDblClick)
        {
            // 双击之后播放该条目 需要判断文件是否存在
            if(!((PlayListItem*)watched)->getExist())
            {
                // 文件不存在就不要播放了 弹窗告诉文件不存在
                if (isWayland) {
                    MessageBox box(tr("Video Player"), tr("File not exist!"), nullptr);
                    box.exec();
                }
                else {
                    TipWidget::showTip(tr("File not exist!"), 1000, QSize(150, 40), m_playListWidget, TipWidget::WARNING);
                }
                return false;
            }
            // 再次判断文件是否存在
            QFileInfo fi(watched->objectName());
            if (!fi.exists()) {
                if (isWayland) {
                    MessageBox box(tr("Video Player"), tr("File not exist!"), nullptr);
                    box.exec();
                }
                else {
                    TipWidget::showTip(tr("File not exist!"), 1000, QSize(150, 40), m_playListWidget, TipWidget::WARNING);
                }
                // 借用一下 core 的信号
                m_playList->setNotAvaliable(watched->objectName());
                return false;
            }
            // 双击播放要先停止不然已知播放下一首   双击处理处理  ））））））））））））））））））
            g_user_signal->stop();
            g_user_signal->play();
            g_user_signal->open(watched->objectName());
        }
#endif
        // 进入显示删除按钮，离开隐藏删除按钮
        PlayListItem* t_item = (PlayListItem*)m_playListWidget->itemWidget(m_itemMap[watched->objectName()]);
        if(event->type() == QEvent::Enter)
        {
            if(t_item != nullptr)
                t_item->setEnter();
        }
        else if(event->type() == QEvent::Leave)
        {
            if(t_item != nullptr)
                t_item->setLeave();
        }
    }
    return QWidget::eventFilter(watched, event);
}

void PlayListWidget::enterEvent(QEvent *e)
{
    m_isMouseEnter = true;
    setCursor(Qt::ArrowCursor);
}

void PlayListWidget::leaveEvent(QEvent *e)
{
    m_isMouseEnter = false;
}

void PlayListWidget::moveEvent(QMoveEvent *event)
{
    emit sigMove(parentWidget()->width() - 16 - x());
}

PlayListItem::PlayListItem(QWidget *parent) :
    QWidget(parent)
{
    m_isSelected = false;
    m_isExist = true;
    setStyleSheet("background-color:rgba(1,1,1,0);");
    m_labIcon = new QLabel;
    m_labIcon->setFixedSize(16, 16);
    m_labIcon->setPixmap(QPixmap(":/ico/play1_h_3x.png").scaled(m_labIcon->size()));

    // 播放列表预览框
    m_labPreview = new ImageLabel;
    m_labPreview->setFixedSize(0,0);

    // 占位用
    m_labSpacing = new QLabel;
    m_labSpacing->setFixedWidth(10);
    m_labSpacing->setStyleSheet("background-color:rgba(1,1,1,0);");

    m_labName = new QLabel;
//    m_labName->setMaximumWidth(190);
//    QFont f_name("Noto Sans CJK SC Regular");
//    f_name.setPixelSize(14);
//    m_labName->setFont(f_name);

    m_labDuration = new QLabel;
    m_labDuration->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
//    QFont f_duration("Noto Sans CJK SC Regular");
//    f_duration.setPixelSize(14);
//    m_labDuration->setFont(f_duration);

    initDeleteButton();

    QHBoxLayout *lay = new QHBoxLayout(this);
    lay->setContentsMargins(16, 5, 25, 5);
    lay->setSpacing(0);
    lay->addWidget(m_labIcon);
    lay->addWidget(m_labPreview);
    lay->addWidget(m_labSpacing);
    lay->addWidget(m_labName);
    lay->addStretch();
    lay->addWidget(m_labDuration);
    lay->addWidget(m_btnDelete);


    if(g_settings->value("General/follow_system_theme").toBool())
    {
        if(g_gsettings->get("styleName").toString() == STYLE_UKUI_DEFAULT)
            setLightTheme();
        else
            setBlackTheme();
    }
    else
    {
        if(g_settings->value("General/theme").toInt() == 0)
            setLightTheme();
        else
            setBlackTheme();
    }

    connect(g_gsettings, &QGSettings::changed, [&](QString key){
        // 如果不是跟随主题的话直接返回
        if(key == "styleName")
            if(g_settings->value("General/follow_system_theme").toBool())
            {
                if(g_gsettings->get("styleName").toString() == STYLE_UKUI_DEFAULT)
                    setLightTheme();
                else
                    setBlackTheme();
            }
    });

    connect(g_user_signal, &GlobalUserSignal::sigTheme, [&](int _theme){
        switch (_theme) {
        case 0:
            if(g_gsettings->get("styleName").toString() == STYLE_UKUI_DEFAULT)
                setLightTheme();
            else
                setBlackTheme();
            break;
        case 1:
            setLightTheme();
            break;
        case 2:
            setBlackTheme();
            break;
        default:
            break;
        }
    });

    m_labIcon->hide();
    m_btnDelete->hide();

    initAnimation();
}

PlayListItem::~PlayListItem()
{
    delete m_labIcon;
    delete m_labName;
    delete m_labPreview;
    delete m_labSpacing;
    delete m_labDuration;
    delete m_btnDelete;
    delete m_pixmapPreview;
    delete layout();
}


/** **********************************************
 * 设置选中状态
 * 说明：选状状态改变主要为图标显示和字体颜色改变
 * @param：s 选中状态
 *************************************************/
void PlayListItem::setSelected(bool s)
{
    m_isSelected = s;
    if (m_isSelected)
    {
        // 如果设置为选中说明文件存在
        m_isExist = true;
        // 如果是预览模式的话不需要显示三角形图标
        if(m_mode == LIST)
            m_labIcon->show();
        setFontColor(FONT_COLOR_SELECTED);
    }
    else
    {
        m_labIcon->hide();

        if(g_settings->value("General/follow_system_theme").toBool())
            if(g_gsettings->get("styleName").toString() == STYLE_UKUI_DEFAULT)
                setLightTheme();
            else
                setBlackTheme();
        else
            if(g_settings->value("General/theme").toInt() == 0)
                setLightTheme();
            else
                setBlackTheme();
    }
}

/** **********************************************
 * 设置内容
 * @param：_file     文件名称（非全路径）
 * @param：_duration 媒体时长
 * @param：_lastTime 上次停止时间
 * @param：_viewPath 预览文件路径
 *************************************************/
void PlayListItem::setData(QString _file, int _duration, int _lastTime, QString _viewPath)
{
    m_tip = _file;
    // 判断文件是否存在
    QFileInfo t_fi(_file);
    if(!t_fi.exists())
        slotNotExit(_file);

    // 判断预览文件是否存在，不存在设置默认
    m_viewPath = _viewPath;
    QFileInfo t_fi_view(_viewPath);
    if(t_fi_view.exists() && t_fi_view.size() != 0)
        m_pixmapPreview = new QPixmap(_viewPath);
    else
        m_pixmapPreview = new QPixmap(":/ico/no-preview.png");
    m_showName = _file.split("/").last();
    QFontMetrics fontWidth(m_labName->font());//得到每个字符的宽度
    QString show_name = fontWidth.elidedText(m_showName, Qt::ElideRight, m_labName->width());//最大宽度150像素
    m_labName->setText(show_name);
    m_labDuration->setText(Functions::timeToStr((double)_duration));
    m_labPreview->setTime(Functions::timeToStr((double)_duration));

    connect(g_core_signal, &GlobalCoreSignal::sigFileNotExist, this, &PlayListItem::slotNotExit, Qt::QueuedConnection);
    setToolTip(QString("<b style=\"color:#ffffff;width:200px;\">%1</b>").arg(_file));
}

void PlayListItem::setDuration(int duration)
{
    m_labDuration->setText(Functions::timeToStr((double)duration));
    m_labPreview->setTime(Functions::timeToStr((double)duration));
}

void PlayListItem::setEnter()
{
    m_btnDelete->show();
    m_labDuration->hide();
}

void PlayListItem::setLeave()
{
    m_btnDelete->hide();
    if (m_mode == LIST)
        m_labDuration->show();
}

void PlayListItem::toBig()
{
    if(m_mode == VIEW)
        return;
    m_mode = VIEW;
    m_labSpacing->show();

#if 0
    m_anmToSmall->stop();
    m_anmToBig->start();
#else
    setMode(VIEW);
#endif

    m_labIcon->hide();
}

void PlayListItem::toSmall()
{
    if(m_mode == LIST)
        return;
    m_mode = LIST;
    m_labSpacing->hide();
#if 0
    m_anmToBig->stop();
    m_anmToSmall->start();
#else
    setMode(LIST);
    if(m_isSelected)
        m_labIcon->show();
#endif
}

void PlayListItem::setMode(ListViewMode _mode)
{
    m_mode = _mode;
    switch (m_mode) {
    case LIST:
        m_labName->setMaximumWidth(190);
        m_labPreview->setFixedSize(0, 0);
//        m_labDuration->setFixedSize(66, 20);
        m_labDuration->show();
        m_labSpacing->hide();
        break;
    case VIEW:
        m_labName->setMaximumWidth(146);
        m_labPreview->setFixedSize(80, 54);
//        m_labDuration->setFixedSize(0, 20);
        m_labDuration->hide();
        m_labSpacing->show();
        break;
    default:
        break;
    }
    updateNameShow();
    m_labPreview->setPixmap((*m_pixmapPreview).scaled(80, 54));
    emit sigValChange(m_labPreview->height() < 20 ? 20 : m_labPreview->height());
}

void PlayListItem::setBlackTheme()
{
    if(m_isSelected)
        return;
    m_btnDelete->setStyleSheet("QPushButton:!hover{background-color:rgba(255,255,255,0);border-image:url(:/ico/cha-h.png);}"
                               "QPushButton:hover{background-color:rgba(255,255,255,0);border-image:url(:/ico/cha-w.png);}"
                               "QPushButton:pressed{background-color:rgba(255,255,255,0);border-image:url(:/ico/cha-w.png);}");
    if(m_isExist)
    {
        m_labName->setStyleSheet("color:#d9d9d9;");
        m_labDuration->setStyleSheet("color:#d9d9d9;");
    }
}

void PlayListItem::setLightTheme()
{
    if(m_isSelected)
        return;
    m_btnDelete->setStyleSheet("QPushButton:!hover{background-color:rgba(255,255,255,0);border-image:url(:/ico_light/cha-h.png);}"
                               "QPushButton:hover{background-color:rgba(255,255,255,0);border-image:url(:/ico_light/cha-w.png);}"
                               "QPushButton:pressed{background-color:rgba(255,255,255,0);border-image:url(:/ico_light/cha-w.png);}");
    if(m_isExist)
    {
        if(m_labDuration)
            m_labDuration->setStyleSheet("color:#262626;");
        if(m_labName)
            m_labName->setStyleSheet("color:#262626;");
    }
}

void PlayListItem::setWidgetFont(const QFont &f)
{
    m_labName->setFont(f);
    m_labDuration->setFont(f);

    updateNameShow();
}

void PlayListItem::slotNotExit(QString file)
{
    if(file != m_tip)
        return;
    // 打开的文件不存在 文件名置灰
    m_isExist = false;
    setFontColor("#A6A6A6");
}

/**
 * 重新加载预览图
 ********/
void PlayListItem::reloadView()
{
    QFileInfo t_fi_view(m_viewPath);
    if(t_fi_view.exists() && t_fi_view.size() != 0)
        m_pixmapPreview = new QPixmap(m_viewPath);
    else
        m_pixmapPreview = new QPixmap(":/ico/no-preview.png");
    m_labPreview->setPixmap((*m_pixmapPreview).scaled(80, 54));
}

/** **********************************************
 * 初始化删除按钮
 *************************************************/
void PlayListItem::initDeleteButton()
{
    m_btnDelete = new QPushButton;
    m_btnDelete->setFixedSize(16, 16);
    m_btnDelete->setCursor(Qt::PointingHandCursor);

    connect(m_btnDelete, &QPushButton::clicked, this, &PlayListItem::deleteItem);
}

/** **********************************************
 * 初始化列表视图变化动画
 *************************************************/
void PlayListItem::initAnimation()
{
    m_anmToBig = new QVariantAnimation(this);
    m_anmToBig->setDuration(AnmationDuration);
    m_anmToBig->setStartValue(0);
    m_anmToBig->setEndValue(300);
    connect(m_anmToBig, &QVariantAnimation::valueChanged, [&](QVariant _value){
        double val = _value.toDouble();

        m_labName->setMaximumWidth(190-0.147*val);
        m_labPreview->setFixedSize(val*0.26667, val*0.18);
        m_labDuration->setFixedWidth(66 - val*0.22);
        updateNameShow();
        emit sigValChange(m_labPreview->height());
    });

    m_anmToSmall = new QVariantAnimation(this);
    m_anmToSmall->setDuration(AnmationDuration);
    m_anmToSmall->setStartValue(0);
    m_anmToSmall->setEndValue(300);
    connect(m_anmToSmall, &QVariantAnimation::valueChanged, [&](QVariant _value){
        double val = _value.toDouble();

        m_labName->setMaximumWidth(146+0.147*val);
        m_labPreview->setFixedSize(80-val*0.26667, 54-val*0.18);
        m_labDuration->setFixedWidth(val*0.22);
        updateNameShow();
        if(m_labPreview->height() < 20)
            emit sigValChange(20);
        else
            emit sigValChange(m_labPreview->height());
    });
    connect(m_anmToSmall, &QVariantAnimation::finished, [&](){
        // 如果是选中状态的话显示播放按钮
        if(m_isSelected)
            m_labIcon->show();
    });
}

void PlayListItem::updateNameShow()
{
    QFontMetrics fontWidth(m_labName->font());//得到每个字符的宽度
    QString show_name = fontWidth.elidedText(m_showName, Qt::ElideRight, m_labName->maximumWidth());//最大宽度150像素
    m_labName->setText(show_name);
}

/** **********************************************
 * 设置字体（主要为颜色）
 * @param: color 字体颜色
 *         格式:"rgb(1,1,1)"
 *************************************************/
void PlayListItem::setFontColor(QString color)
{
    if(color == "")
    {
        m_labName->setStyleSheet("");
        m_labDuration->setStyleSheet("");
    }
    else
    {
        m_labName->setStyleSheet(QString("color:").append(color));
        m_labDuration->setStyleSheet(QString("color:").append(color));
    }
}

/** **********************************************
 * 点击 x 按钮
 *************************************************/
void PlayListItem::deleteItem()
{
    if(m_isSelected)
    {
        // 正在播放的是本条 需要关闭
        g_user_signal->play();
        g_user_signal->stop();
    }
    // 删除条目 告诉别人删除的绝对路径就行
    g_user_signal->deleteListItem(m_tip);
}

void PlayListItem::mousePressEvent(QMouseEvent *e)
{
    if(e->button() == Qt::RightButton)
    {
        // 右击之后需要弹出菜单，并且告诉谁被点击的
        emit sigRightBPressed(m_tip);
    }
}

void PlayListItem::mouseDoubleClickEvent(QMouseEvent *e)
{
    // 判断文件是否存在，每次点击都去判断一下，这样更准确，只有在双击的时候才会去刷新状态，不会主动刷新
    QFileInfo fi(m_tip);
    if (!fi.exists()) {
        TipWidget::showTip(tr("File not exist!"), 1000, QSize(150, 40), parentWidget(), TipWidget::WARNING);
        emit sigExistsStateChange(m_tip, false);
        m_isExist = false;
        setFontColor("#A6A6A6");
        return;
    }
    emit sigExistsStateChange(m_tip, true);
    m_isExist = true;
    g_user_signal->stop();
    g_user_signal->play();
    g_user_signal->open(m_tip, 0);
}

MarkListItem::MarkListItem(QWidget *parent) :
    QWidget(parent)
{
    initStyle();
    m_needSeekToPos = false;
    m_fileExit = true;

    if (g_settings->value("General/follow_system_theme").toBool()) {
        if(g_gsettings->get("styleName").toString() == STYLE_UKUI_DEFAULT)
            setLightTheme();
        else
            setBlackTheme();
    }
    else {
        if(g_settings->value("General/theme").toInt() == 0)
            setLightTheme();
        else
            setBlackTheme();
    }

    connect(g_gsettings, &QGSettings::changed, this, [&](QString key){
        // 如果不是跟随主题的话直接返回
        if (key == "styleName") {
            if (g_settings->value("General/follow_system_theme").toBool()) {
                if(g_gsettings->get("styleName").toString() == STYLE_UKUI_DEFAULT)
                    setLightTheme();
                else
                    setBlackTheme();
            }
        }
    });

    connect(g_user_signal, &GlobalUserSignal::sigTheme, this, [&](int _theme){
        switch (_theme) {
        case 0:
            if (g_gsettings->get("styleName").toString() == STYLE_UKUI_DEFAULT)
                setLightTheme();
            else
                setBlackTheme();
            break;
        case 1:
            setLightTheme();
            break;
        case 2:
            setBlackTheme();
            break;
        default:
            break;
        }
    });

    connect(g_core_signal, &GlobalCoreSignal::sigFileInfoChange, this, [this](Mpv::FileInfo info) {
        m_currentPlayingFile = info.file_path;
        // 是否双击书签打开的文件，如果是双击书签打开的需要跳转到书签位置
        if (m_needSeekToPos) {
            g_user_signal->seek(m_markPos);
            m_needSeekToPos = false;
        }
    }, Qt::QueuedConnection);

    connect(g_core_signal, &GlobalCoreSignal::sigFileNotExist, this, &MarkListItem::setNotExit, Qt::QueuedConnection);
}

MarkListItem::~MarkListItem()
{
    if (m_pixmapPreview)
        delete m_pixmapPreview;
    if (m_labPreview)
        delete m_labPreview;
    if (m_labFilePath)
        delete m_labFilePath;
    if (m_labDuration)
        delete m_labDuration;
    if (m_labMarkPos)
        delete m_labMarkPos;
    if (m_vlay)
        delete m_vlay;
    if (m_hlay)
        delete m_hlay;
    if (m_dp)
        delete m_dp;
    if (m_btnDelete)
        delete m_btnDelete;

    m_pixmapPreview = nullptr;
    m_labPreview = nullptr;
    m_labFilePath = nullptr;
    m_labDuration = nullptr;
    m_labMarkPos = nullptr;
    m_vlay = nullptr;
    m_hlay = nullptr;
    m_dp = nullptr;
    m_btnDelete = nullptr;
}

void MarkListItem::setData(QString path, int duration, int pos, QString desc, QString preview)
{
    m_tooltip = path;
    m_fileName = path.split("/").last();
    m_labDuration->setText(Functions::timeToStr((double)duration));
    m_labPreview->setTime(Functions::timeToStr((double)duration));
    m_labMarkPos->setText(Functions::timeToStr((double)pos));
    m_labFilePath->setText(m_fileName);
    m_markPos = pos;
    m_describe = desc;

    // 加载预览图
    QFile file_view(preview);
    if(file_view.exists())
        m_pixmapPreview = new QPixmap(preview);
    else
        m_pixmapPreview = new QPixmap(":/ico/no-preview.png");
}

void MarkListItem::setMode(ListViewMode mode)
{
    m_mode = mode;
    switch (m_mode) {
    case LIST:
        m_labFilePath->setMaximumWidth(190);
        m_labPreview->setFixedSize(0, 54);
//        m_labDuration->setFixedWidth(66);
        m_labDuration->show();
        m_hlay->setContentsMargins(8, 1, 20, 1);
        break;
    case VIEW:
        m_labFilePath->setMaximumWidth(150);
        m_labPreview->setFixedSize(80, 54);
//        m_labDuration->setFixedWidth(0);
        m_labDuration->hide();
        m_hlay->setContentsMargins(16, 10, 20, 10);
        break;
    default:
        break;
    }
    updateNameShow();
    m_labPreview->setPixmap((*m_pixmapPreview).scaled(80, 54));
}

void MarkListItem::setEnter()
{
    m_labDuration->hide();
    m_btnDelete->show();
}

void MarkListItem::setLeave()
{
    m_btnDelete->hide();
    if (m_mode == LIST)
        m_labDuration->show();
}

void MarkListItem::setWidgetFont(QFont f)
{
    m_labDuration->setFont(f);
    m_labFilePath->setFont(f);
    m_labMarkPos->setFont(f);

    updateNameShow();
}

void MarkListItem::setNotExit(QString file)
{
    if (file != m_tooltip) {
        return;
    }
    m_fileExit = false;
    setFontColor("#A6A6A6");
}

void MarkListItem::setFontColor(QString color)
{
    if(color == "")
    {
        m_labFilePath->setStyleSheet("");
        m_labDuration->setStyleSheet("");
        m_labMarkPos->setStyleSheet("");
    }
    else
    {
        m_labFilePath->setStyleSheet(QString("color:").append(color));
        m_labDuration->setStyleSheet(QString("color:").append(color));
        m_labMarkPos->setStyleSheet(QString("color:").append(color));
    }
}

void MarkListItem::setBlackTheme()
{
    m_btnDelete->setStyleSheet("QPushButton:!hover{background-color:rgba(255,255,255,0);border-image:url(:/ico/cha-h.png);}"
                               "QPushButton:hover{background-color:rgba(255,255,255,0);border-image:url(:/ico/cha-w.png);}"
                               "QPushButton:pressed{background-color:rgba(255,255,255,0);border-image:url(:/ico/cha-w.png);}");
}

void MarkListItem::setLightTheme()
{
    m_btnDelete->setStyleSheet("QPushButton:!hover{background-color:rgba(255,255,255,0);border-image:url(:/ico_light/cha-h.png);}"
                               "QPushButton:hover{background-color:rgba(255,255,255,0);border-image:url(:/ico_light/cha-w.png);}"
                               "QPushButton:pressed{background-color:rgba(255,255,255,0);border-image:url(:/ico_light/cha-w.png);}");
}

void MarkListItem::initStyle()
{
    m_labFilePath   = new QLabel;
    m_labMarkPos    = new QLabel;
    m_labDuration   = new QLabel;
    m_labPreview    = new ImageLabel;
    m_btnDelete     = new QPushButton;

    m_dp = new QWidget;

    connect(m_btnDelete, &QPushButton::clicked, [this](){
        emit sigDeleteMark(m_tooltip, m_markPos);
    });

    m_btnDelete->setFixedSize(16, 16);
    m_btnDelete->setCursor(Qt::PointingHandCursor);

    m_vlay = new QVBoxLayout(m_dp);
    m_vlay->setSpacing(4);
    m_vlay->setContentsMargins(0, 0, 0, 0);
    m_vlay->addStretch();
    m_vlay->addWidget(m_labFilePath);
    m_vlay->addWidget(m_labMarkPos);
    m_vlay->addStretch();

    m_hlay = new QHBoxLayout(this);
    m_hlay->setContentsMargins(16, 10, 20, 10);

    m_hlay->addWidget(m_labPreview);
    m_hlay->addWidget(m_dp);
    m_hlay->addStretch();
    m_hlay->addWidget(m_labDuration);
    m_hlay->addWidget(m_btnDelete);
    m_btnDelete->hide();
}

void MarkListItem::updateNameShow()
{
    QFontMetrics fontWidth(m_labFilePath->font());//得到每个字符的宽度
    QString show_name = fontWidth.elidedText(m_fileName, Qt::ElideRight, m_labFilePath->maximumWidth());//最大宽度150像素
    m_labFilePath->setText(show_name);
}


void MarkListItem::mousePressEvent(QMouseEvent *e)
{
    if(e->button() == Qt::RightButton)
    {
        // 右击之后需要弹出菜单，并且告诉谁被点击的
        emit sigRightBtnPressed(m_markPos);
    }
}

void MarkListItem::mouseDoubleClickEvent(QMouseEvent *e)
{
    if (e->button() == Qt::LeftButton) {
        if (!m_fileExit) {
            if (isWayland) {
                MessageBox box(tr("Video Player"), tr("File not exist!"), nullptr);
                box.exec();
            }
            else {
                TipWidget::showTip(tr("File not exist!"), 1000, QSize(150, 40), parentWidget(), TipWidget::WARNING);
            }
            return;
        }

        // 播放并跳转
        emit sigPlayAndSeek(m_tooltip, m_markPos);
        m_needSeekToPos = true;
    }
}

void MarkListItem::leaveEvent(QEvent *e)
{
    if (m_labDuration && m_mode == LIST)
        m_labDuration->show();
    if (m_btnDelete)
        m_btnDelete->hide();
    return QWidget::leaveEvent(e);
}

void MarkListItem::enterEvent(QEvent *e)
{
    if (m_labDuration)
        m_labDuration->hide();
    if (m_btnDelete)
        m_btnDelete->show();
    return QWidget::enterEvent(e);
}
