/*
 * 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 "playglwidget.h"
#include <QOpenGLContext>
#include <QMouseEvent>
#include <QGSettings>
#include <QDateTime>
#include <QDebug>
#include <QTimer>

#include "global/globalsignal.h"
#include "global/global.h"

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

using namespace Global;

static void *get_proc_address(void *ctx, const char *name) {
    Q_UNUSED(ctx);
    QOpenGLContext *glctx = QOpenGLContext::currentContext();
    if (!glctx)
        return NULL;
    return (void *)glctx->getProcAddress(QByteArray(name));
}

PlayGLWidget::PlayGLWidget(QWidget *parent, Qt::WindowFlags f)
    : QWidget(parent, f)/*,
      m_scale(1.0),
      m_mouseUsed(true),
      m_isMouseEnter(false),
      hasVideo(false)*/
{
//    setlocale(LC_NUMERIC, "C");

//    setMouseTracking(true);
//    initGlobalSig();
//    m_checkMouseTimer = new QTimer;
//    m_checkMouseTimer->setInterval(2000);
//    connect(m_checkMouseTimer, &QTimer::timeout, [&](){
//        if(!hasVideo)
//            return;
//        if(m_isMouseEnter) {
//            if (m_mouseUsed)
//                setCursor(QCursor(Qt::BlankCursor));
//        }
//        g_user_signal->hideBar(true);

//        m_checkMouseTimer->stop();
//        return;
//    });

//    m_lMouseClickTimer = new QTimer;
//    m_lMouseClickTimer->setInterval(300);
//    connect(m_lMouseClickTimer, &QTimer::timeout, [&](){
//        g_user_signal->playWidgetClick();
//        m_lMouseClickTimer->stop();
//    });
//    mpv_gl = nullptr;

//    m_fpsTimer = new QTimer;
//    m_fpsTimer->setInterval(500);
}

PlayGLWidget::~PlayGLWidget()
{
//    makeCurrent();
//    if (mpv_gl)
//        mpv_opengl_cb_set_update_callback(mpv_gl, NULL, NULL);
//    mpv_opengl_cb_uninit_gl(mpv_gl);
}

#if 0
void PlayGLWidget::setMouseUsed(bool used)
{
    m_mouseUsed = used;
    if (!m_mouseUsed) {
        setCursor(QCursor(Qt::ArrowCursor));
        m_checkMouseTimer->stop();
    }
}

void PlayGLWidget::on_update(void *ctx)
{
    QMetaObject::invokeMethod((PlayGLWidget*)ctx, "update");
}

void PlayGLWidget::initMpvGL()
{
    return;
    if(mpv_h)
    {
        mpv_gl = (mpv_opengl_cb_context *)mpv_get_sub_api(mpv_h, MPV_SUB_API_OPENGL_CB);
        if (!mpv_gl)
        {
            log_e("OpenGL not compiled in!");
            qDebug("OpenGL not compiled in!");
        }
        mpv_opengl_cb_set_update_callback(mpv_gl, PlayGLWidget::on_update, (void *)this);
//        connect(this, &PlayGLWidget::frameSwapped, this, &PlayGLWidget::swapped);
    }
}

void PlayGLWidget::swapped()
{
//    mpv_opengl_cb_report_flip(mpv_gl, 0);
}

void PlayGLWidget::initGlobalSig()
{
    connect(g_core_signal, &GlobalCoreSignal::sigStateChange, [&](Mpv::PlayState state){
        m_state = state;
        if(m_state < 0) {
            m_checkMouseTimer->stop();
        }
        else {
            m_checkMouseTimer->start();
            if(!isWayland)
            {
                // wayland 下高分辨适配不生效，所以 wayland 下默认 1 倍缩放就可以，如果 wayland 下窗口适配缩放后再去掉判断
                QGSettings g("org.ukui.SettingsDaemon.plugins.xsettings");
                m_scale = g.get("scaling-factor").toDouble();
            }
        }
    });

    connect(g_core_signal, &GlobalCoreSignal::sigVideoIdChange, [&](int vid){
        if(vid < 0)
            hasVideo = false;
        else
            hasVideo = true;
    });
}

#if 0
void PlayGLWidget::initializeGL()
{
    if(mpv_gl)
    {
        int r = mpv_opengl_cb_init_gl(mpv_gl, NULL, get_proc_address, NULL);
        if (r < 0)
        {
            log_e("could not initialize OpenGL");
            qDebug("could not initialize OpenGL");
        }
    }
}
#endif

#if 0
static int f_count = 0;
static qint64 s_time = 0;
void PlayGLWidget::paintGL()
{
    /****************** fps计算 ********************/
    if(f_count == 0)
        s_time = QDateTime::currentMSecsSinceEpoch();
    f_count++;
    if(f_count > 10)
    {
        g_core_signal->notify10FrameUseTime(QDateTime::currentMSecsSinceEpoch() - s_time);
        f_count = 0;
    }

    if(mpv_gl)
    {
        if(m_state==Mpv::Playing || m_state==Mpv::Paused)
        {
//            mpv_opengl_cb_draw(mpv_gl, defaultFramebufferObject(), width()*m_scale, -height()*m_scale);
        }
    }
}
#endif

void PlayGLWidget::mousePressEvent(QMouseEvent *e)
{
    if (!m_mouseUsed)
        return;
    if(e->buttons() == Qt::RightButton)
    {
        m_isMouseEnter = false;
        g_user_signal->showRightMenu();
    }
    else if(e->buttons() == Qt::LeftButton)
        m_lMouseClickTimer->start();
}

void PlayGLWidget::mouseMoveEvent(QMouseEvent *e)
{
    m_isMouseEnter = true;
    m_checkMouseTimer->stop();
    if (cursor().shape() != Qt::ArrowCursor) {
        setCursor(QCursor(Qt::ArrowCursor));
    }
    g_user_signal->hideBar(false);
    if(m_state > 0)
        m_checkMouseTimer->start();
}

void PlayGLWidget::mouseDoubleClickEvent(QMouseEvent *e)
{
    if (!m_mouseUsed)
        return;
    if(e->buttons() == Qt::LeftButton)
    {
        g_user_signal->fullScreen();
        m_lMouseClickTimer->stop();
    }
}

void PlayGLWidget::enterEvent(QEvent *e)
{
    m_isMouseEnter = true;
}

void PlayGLWidget::leaveEvent(QEvent *e)
{
    m_isMouseEnter = false;
    if(m_state > 0)
        m_checkMouseTimer->start();
}
#endif
