/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "evrvideowindowcontrol.h"

#ifndef QT_NO_WIDGETS
#include <qwidget.h>
#endif

EvrVideoWindowControl::EvrVideoWindowControl(QObject *parent)
    : QVideoWindowControl(parent)
    , m_windowId(0)
    , m_windowColor(RGB(0, 0, 0))
    , m_dirtyValues(0)
    , m_aspectRatioMode(Qt::KeepAspectRatio)
    , m_brightness(0)
    , m_contrast(0)
    , m_hue(0)
    , m_saturation(0)
    , m_fullScreen(false)
    , m_displayControl(0)
    , m_processor(0)
{
}

EvrVideoWindowControl::~EvrVideoWindowControl()
{
   clear();
}

bool EvrVideoWindowControl::setEvr(IUnknown *evr)
{
    clear();

    if (!evr)
        return true;

    IMFGetService *service = NULL;

    if (SUCCEEDED(evr->QueryInterface(IID_PPV_ARGS(&service)))
            && SUCCEEDED(service->GetService(mr_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_displayControl)))) {

        service->GetService(mr_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_processor));

        setWinId(m_windowId);
        setDisplayRect(m_displayRect);
        setAspectRatioMode(m_aspectRatioMode);
        m_dirtyValues = DXVA2_ProcAmp_Brightness | DXVA2_ProcAmp_Contrast | DXVA2_ProcAmp_Hue | DXVA2_ProcAmp_Saturation;
        applyImageControls();
    }

    if (service)
        service->Release();

    return m_displayControl != NULL;
}

void EvrVideoWindowControl::clear()
{
    if (m_displayControl)
        m_displayControl->Release();
    m_displayControl = NULL;

    if (m_processor)
        m_processor->Release();
    m_processor = NULL;
}

WId EvrVideoWindowControl::winId() const
{
    return m_windowId;
}

void EvrVideoWindowControl::setWinId(WId id)
{
    m_windowId = id;

#ifndef QT_NO_WIDGETS
    if (QWidget *widget = QWidget::find(m_windowId)) {
        const QColor color = widget->palette().color(QPalette::Window);

        m_windowColor = RGB(color.red(), color.green(), color.blue());
    }
#endif

    if (m_displayControl)
        m_displayControl->SetVideoWindow(HWND(m_windowId));
}

QRect EvrVideoWindowControl::displayRect() const
{
    return m_displayRect;
}

void EvrVideoWindowControl::setDisplayRect(const QRect &rect)
{
    m_displayRect = rect;

    if (m_displayControl) {
        RECT displayRect = { rect.left(), rect.top(), rect.right() + 1, rect.bottom() + 1 };
        QSize sourceSize = nativeSize();

        RECT sourceRect = { 0, 0, sourceSize.width(), sourceSize.height() };

        if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
            QSize clippedSize = rect.size();
            clippedSize.scale(sourceRect.right, sourceRect.bottom, Qt::KeepAspectRatio);

            sourceRect.left = (sourceRect.right - clippedSize.width()) / 2;
            sourceRect.top = (sourceRect.bottom - clippedSize.height()) / 2;
            sourceRect.right = sourceRect.left + clippedSize.width();
            sourceRect.bottom = sourceRect.top + clippedSize.height();
        }

        if (sourceSize.width() > 0 && sourceSize.height() > 0) {
            MFVideoNormalizedRect sourceNormRect;
            sourceNormRect.left = float(sourceRect.left) / float(sourceRect.right);
            sourceNormRect.top = float(sourceRect.top) / float(sourceRect.bottom);
            sourceNormRect.right = float(sourceRect.right) / float(sourceRect.right);
            sourceNormRect.bottom = float(sourceRect.bottom) / float(sourceRect.bottom);
            m_displayControl->SetVideoPosition(&sourceNormRect, &displayRect);
        } else {
            m_displayControl->SetVideoPosition(NULL, &displayRect);
        }

        // To refresh content immediately.
        repaint();
    }
}

bool EvrVideoWindowControl::isFullScreen() const
{
    return m_fullScreen;
}

void EvrVideoWindowControl::setFullScreen(bool fullScreen)
{
    if (m_fullScreen == fullScreen)
        return;
    emit fullScreenChanged(m_fullScreen = fullScreen);
}

void EvrVideoWindowControl::repaint()
{
    QSize size = nativeSize();
    if (size.width() > 0 && size.height() > 0
        && m_displayControl
        && SUCCEEDED(m_displayControl->RepaintVideo())) {
        return;
    }

    PAINTSTRUCT paint;
    if (HDC dc = ::BeginPaint(HWND(m_windowId), &paint)) {
        HPEN pen = ::CreatePen(PS_SOLID, 1, m_windowColor);
        HBRUSH brush = ::CreateSolidBrush(m_windowColor);
        ::SelectObject(dc, pen);
        ::SelectObject(dc, brush);

        ::Rectangle(
                dc,
                m_displayRect.left(),
                m_displayRect.top(),
                m_displayRect.right() + 1,
                m_displayRect.bottom() + 1);

        ::DeleteObject(pen);
        ::DeleteObject(brush);
        ::EndPaint(HWND(m_windowId), &paint);
    }
}

QSize EvrVideoWindowControl::nativeSize() const
{
    QSize size;
    if (m_displayControl) {
        SIZE sourceSize;
        if (SUCCEEDED(m_displayControl->GetNativeVideoSize(&sourceSize, 0)))
            size = QSize(sourceSize.cx, sourceSize.cy);
    }
    return size;
}

Qt::AspectRatioMode EvrVideoWindowControl::aspectRatioMode() const
{
    return m_aspectRatioMode;
}

void EvrVideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode)
{
    m_aspectRatioMode = mode;

    if (m_displayControl) {
        switch (mode) {
        case Qt::IgnoreAspectRatio:
            //comment from MSDN: Do not maintain the aspect ratio of the video. Stretch the video to fit the output rectangle.
            m_displayControl->SetAspectRatioMode(MFVideoARMode_None);
            break;
        case Qt::KeepAspectRatio:
            //comment from MSDN: Preserve the aspect ratio of the video by letterboxing or within the output rectangle.
            m_displayControl->SetAspectRatioMode(MFVideoARMode_PreservePicture);
            break;
        case Qt::KeepAspectRatioByExpanding:
            //for this mode, more adjustment will be done in setDisplayRect
            m_displayControl->SetAspectRatioMode(MFVideoARMode_PreservePicture);
            break;
        default:
            break;
        }
        setDisplayRect(m_displayRect);
    }
}

int EvrVideoWindowControl::brightness() const
{
    return m_brightness;
}

void EvrVideoWindowControl::setBrightness(int brightness)
{
    if (m_brightness == brightness)
        return;

    m_brightness = brightness;

    m_dirtyValues |= DXVA2_ProcAmp_Brightness;

    applyImageControls();

    emit brightnessChanged(brightness);
}

int EvrVideoWindowControl::contrast() const
{
    return m_contrast;
}

void EvrVideoWindowControl::setContrast(int contrast)
{
    if (m_contrast == contrast)
        return;

    m_contrast = contrast;

    m_dirtyValues |= DXVA2_ProcAmp_Contrast;

    applyImageControls();

    emit contrastChanged(contrast);
}

int EvrVideoWindowControl::hue() const
{
    return m_hue;
}

void EvrVideoWindowControl::setHue(int hue)
{
    if (m_hue == hue)
        return;

    m_hue = hue;

    m_dirtyValues |= DXVA2_ProcAmp_Hue;

    applyImageControls();

    emit hueChanged(hue);
}

int EvrVideoWindowControl::saturation() const
{
    return m_saturation;
}

void EvrVideoWindowControl::setSaturation(int saturation)
{
    if (m_saturation == saturation)
        return;

    m_saturation = saturation;

    m_dirtyValues |= DXVA2_ProcAmp_Saturation;

    applyImageControls();

    emit saturationChanged(saturation);
}

void EvrVideoWindowControl::applyImageControls()
{
    if (m_processor) {
        DXVA2_ProcAmpValues values;
        if (m_dirtyValues & DXVA2_ProcAmp_Brightness) {
            values.Brightness = scaleProcAmpValue(DXVA2_ProcAmp_Brightness, m_brightness);
        }
        if (m_dirtyValues & DXVA2_ProcAmp_Contrast) {
            values.Contrast = scaleProcAmpValue(DXVA2_ProcAmp_Contrast, m_contrast);
        }
        if (m_dirtyValues & DXVA2_ProcAmp_Hue) {
            values.Hue = scaleProcAmpValue(DXVA2_ProcAmp_Hue, m_hue);
        }
        if (m_dirtyValues & DXVA2_ProcAmp_Saturation) {
            values.Saturation = scaleProcAmpValue(DXVA2_ProcAmp_Saturation, m_saturation);
        }

        if (SUCCEEDED(m_processor->SetProcAmpValues(m_dirtyValues, &values))) {
            m_dirtyValues = 0;
        }
    }
}

DXVA2_Fixed32 EvrVideoWindowControl::scaleProcAmpValue(DWORD prop, int value) const
{
    float scaledValue = 0.0;

    DXVA2_ValueRange  range;
    if (SUCCEEDED(m_processor->GetProcAmpRange(prop, &range))) {
        scaledValue = DXVA2FixedToFloat(range.DefaultValue);
        if (value > 0)
            scaledValue += float(value) * (DXVA2FixedToFloat(range.MaxValue) - DXVA2FixedToFloat(range.DefaultValue)) / 100;
        else if (value < 0)
            scaledValue -= float(value) * (DXVA2FixedToFloat(range.MinValue) - DXVA2FixedToFloat(range.DefaultValue)) / 100;
    }

    return DXVA2FloatToFixed(scaledValue);
}
