#include "PlayerWidget.h"

#include <algorithm>
#include <QResizeEvent>
#include <QPainter>


PlayerWidget::PlayerWidget(QWidget *parent)
{
    m_windowSize = QSize(0, 0);
}

PlayerWidget::~PlayerWidget()
{

}

/* 刷新一帧 */
void PlayerWidget::updateFrame(Image_YUV420& yuvData)
{
    YUV420ToQImage(yuvData, m_image);
    if(m_windowSize.width() == 0 || m_windowSize.height() == 0)
    {
        m_imageWidth = yuvData.width;
        m_imageHeight = yuvData.height;
    }
    update();
}

void PlayerWidget::updateFrame(Image_QImage& imageData)
{
    if(m_windowSize.width() == 0 || m_windowSize.height() == 0)
    {
        m_imageWidth = imageData.width;
        m_imageHeight = imageData.height;
    }
    m_image = std::move(imageData.image);
    update();
}


/* 绘画事件 */
void PlayerWidget::paintEvent(QPaintEvent *event)
{

    // SPDLOG_TRACE("开始绘制画面...");
    /* 对图像进行缩放 */
    if(m_windowSize.width() != m_imageWidth || m_windowSize.height() != m_imageHeight)
    {
        m_image = m_image.scaled(m_windowSize.width(), m_windowSize.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
    }
    QPainter painter(this);
    painter.drawImage(0, 0, m_image);
}

/* 重新设置大小事件 */
void PlayerWidget::resizeEvent(QResizeEvent *event)
{
    m_windowSize.setWidth(event->size().width());
    m_windowSize.setHeight(event->size().height());

    QWidget::resizeEvent(event);
}

/* YUV420转QImage */
void PlayerWidget::YUV420ToQImage(Image_YUV420& yuvData, QImage& image)
{
    int width = yuvData.width;
    int height = yuvData.height;
    int frameSize = yuvData.width * yuvData.height;
    int chromaSize = frameSize / 4;

    QImage image_rgb(width, height, QImage::Format_RGB888);

    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            int yIndex = y * width + x;
            int uIndex = (y / 2) * (width / 2) + (x / 2);
            int vIndex = uIndex;

            uint8_t Y = yuvData.yData.at(yIndex);
            uint8_t U = yuvData.uData[uIndex];
            uint8_t V = yuvData.vData[vIndex];

            int C = Y - 16;
            int D = U - 128;
            int E = V - 128;

            int R = (298 * C + 409 * E + 128) >> 8;
            int G = (298 * C - 100 * D - 208 * E + 128) >> 8;
            int B = (298 * C + 516 * D + 128) >> 8;

            R = std::clamp(R, 0, 255);
            G = std::clamp(G, 0, 255);
            B = std::clamp(B, 0, 255);

            image_rgb.setPixel(x, y, qRgb(R, G, B));
        }
    }

    image = image_rgb;
}

