/****************************************************************************
**
** 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 "vmr9videowindowcontrol.h"

#include "directshowglobal.h"

#ifndef QT_NO_WIDGETS
#include <QtGui/QPalette>
#include <QtWidgets/QWidget>
#endif

Vmr9VideoWindowControl::Vmr9VideoWindowControl(QObject *parent)
    : QVideoWindowControl(parent)
    , m_filter(com_new<IBaseFilter>(CLSID_VideoMixingRenderer9))
{
    if (IVMRFilterConfig9 *config = com_cast<IVMRFilterConfig9>(m_filter, IID_IVMRFilterConfig9)) {
        config->SetRenderingMode(VMR9Mode_Windowless);
        config->SetNumberOfStreams(1);
        config->Release();
    }
}

Vmr9VideoWindowControl::~Vmr9VideoWindowControl()
{
    if (m_filter)
        m_filter->Release();
}


WId Vmr9VideoWindowControl::winId() const
{
    return m_windowId;

}

void Vmr9VideoWindowControl::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 (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(
            m_filter, IID_IVMRWindowlessControl9)) {
        control->SetVideoClippingWindow(reinterpret_cast<HWND>(m_windowId));
        control->SetBorderColor(m_windowColor);
        control->Release();
    }
}

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

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

    if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(
            m_filter, IID_IVMRWindowlessControl9)) {
        RECT sourceRect = { 0, 0, 0, 0 };
        RECT displayRect = { rect.left(), rect.top(), rect.right() + 1, rect.bottom() + 1 };

        control->GetNativeVideoSize(&sourceRect.right, &sourceRect.bottom, nullptr, nullptr);

        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();
        }

        control->SetVideoPosition(&sourceRect, &displayRect);
        control->Release();
    }
}

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

void Vmr9VideoWindowControl::setFullScreen(bool fullScreen)
{
    emit fullScreenChanged(m_fullScreen = fullScreen);
}

void Vmr9VideoWindowControl::repaint()
{
    PAINTSTRUCT paint;

    if (HDC dc = ::BeginPaint(reinterpret_cast<HWND>(m_windowId), &paint)) {
        HRESULT hr = E_FAIL;

        if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(
                m_filter, IID_IVMRWindowlessControl9)) {
            hr = control->RepaintVideo(reinterpret_cast<HWND>(m_windowId), dc);
            control->Release();
        }

        if (!SUCCEEDED(hr)) {
            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(reinterpret_cast<HWND>(m_windowId), &paint);
    }
}

QSize Vmr9VideoWindowControl::nativeSize() const
{
    QSize size;

    if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(
            m_filter, IID_IVMRWindowlessControl9)) {
        LONG width;
        LONG height;

        if (control->GetNativeVideoSize(&width, &height, nullptr, nullptr) == S_OK)
            size = QSize(width, height);
        control->Release();
    }
    return size;
}

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

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

    if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>(
            m_filter, IID_IVMRWindowlessControl9)) {
        switch (mode) {
        case Qt::IgnoreAspectRatio:
            control->SetAspectRatioMode(VMR9ARMode_None);
            break;
        case Qt::KeepAspectRatio:
            control->SetAspectRatioMode(VMR9ARMode_LetterBox);
            break;
        case Qt::KeepAspectRatioByExpanding:
            control->SetAspectRatioMode(VMR9ARMode_LetterBox);
            setDisplayRect(m_displayRect);
            break;
        default:
            break;
        }
        control->Release();
    }
}

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

void Vmr9VideoWindowControl::setBrightness(int brightness)
{
    m_brightness = brightness;

    m_dirtyValues |= ProcAmpControl9_Brightness;

    setProcAmpValues();

    emit brightnessChanged(brightness);
}

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

void Vmr9VideoWindowControl::setContrast(int contrast)
{
    m_contrast = contrast;

    m_dirtyValues |= ProcAmpControl9_Contrast;

    setProcAmpValues();

    emit contrastChanged(contrast);
}

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

void Vmr9VideoWindowControl::setHue(int hue)
{
    m_hue = hue;

    m_dirtyValues |= ProcAmpControl9_Hue;

    setProcAmpValues();

    emit hueChanged(hue);
}

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

void Vmr9VideoWindowControl::setSaturation(int saturation)
{
    m_saturation = saturation;

    m_dirtyValues |= ProcAmpControl9_Saturation;

    setProcAmpValues();

    emit saturationChanged(saturation);
}

void Vmr9VideoWindowControl::setProcAmpValues()
{
    if (IVMRMixerControl9 *control = com_cast<IVMRMixerControl9>(m_filter, IID_IVMRMixerControl9)) {
        VMR9ProcAmpControl procAmp;
        procAmp.dwSize = sizeof(VMR9ProcAmpControl);
        procAmp.dwFlags = m_dirtyValues;

        if (m_dirtyValues & ProcAmpControl9_Brightness) {
            procAmp.Brightness = scaleProcAmpValue(
                    control, ProcAmpControl9_Brightness, m_brightness);
        }
        if (m_dirtyValues & ProcAmpControl9_Contrast) {
            procAmp.Contrast = scaleProcAmpValue(
                    control, ProcAmpControl9_Contrast, m_contrast);
        }
        if (m_dirtyValues & ProcAmpControl9_Hue) {
            procAmp.Hue = scaleProcAmpValue(
                    control, ProcAmpControl9_Hue, m_hue);
        }
        if (m_dirtyValues & ProcAmpControl9_Saturation) {
            procAmp.Saturation = scaleProcAmpValue(
                    control, ProcAmpControl9_Saturation, m_saturation);
        }

        if (SUCCEEDED(control->SetProcAmpControl(0, &procAmp))) {
            m_dirtyValues = 0;
        }

        control->Release();
    }
}

float Vmr9VideoWindowControl::scaleProcAmpValue(
        IVMRMixerControl9 *control, VMR9ProcAmpControlFlags property, int value) const
{
    float scaledValue = 0.0;

    VMR9ProcAmpControlRange range;
    range.dwSize = sizeof(VMR9ProcAmpControlRange);
    range.dwProperty = property;

    if (SUCCEEDED(control->GetProcAmpControlRange(0, &range))) {
        scaledValue = range.DefaultValue;
        if (value > 0)
            scaledValue += float(value) * (range.MaxValue - range.DefaultValue) / 100;
        else if (value < 0)
            scaledValue -= float(value) * (range.MinValue - range.DefaultValue) / 100;
    }

    return scaledValue;
}
