/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "paintedwindow.h"

#include <QGuiApplication>
#include <QOpenGLContext>
#include <QOpenGLPaintDevice>
#include <QPainter>
#include <QScreen>
#include <QTimer>

#include <qmath.h>

PaintedWindow::PaintedWindow()
{
    QSurfaceFormat format;
    format.setStencilBufferSize(8);
    format.setSamples(4);

    setSurfaceType(QWindow::OpenGLSurface);
    setFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
    setFormat(format);

    create();

    m_context = new QOpenGLContext(this);
    m_context->setFormat(format);
    m_context->create();

    m_animation = new QPropertyAnimation(this, "rotation");
    m_animation->setStartValue(qreal(0));
    m_animation->setEndValue(qreal(1));
    m_animation->setDuration(500);

    QRect screenGeometry = screen()->availableGeometry();

    QPoint center = screenGeometry.center();
    QRect windowRect = screen()->isLandscape(screen()->orientation()) ? QRect(0, 0, 640, 480) : QRect(0, 0, 480, 640);
    setGeometry(QRect(center - windowRect.center(), windowRect.size()));

    m_rotation = 0;

    reportContentOrientationChange(screen()->orientation());

    m_targetOrientation = contentOrientation();
    m_nextTargetOrientation = Qt::PrimaryOrientation;

    connect(screen(), &QScreen::orientationChanged, this, &PaintedWindow::orientationChanged);
    connect(m_animation, &QAbstractAnimation::finished, this, &PaintedWindow::rotationDone);
    connect(this, &PaintedWindow::rotationChanged, this, QOverload<>::of(&PaintedWindow::paint));
}

void PaintedWindow::exposeEvent(QExposeEvent *)
{
    if (isExposed())
        paint();
}

void PaintedWindow::mousePressEvent(QMouseEvent *)
{
    Qt::ScreenOrientation o = contentOrientation();
    switch (o) {
    case Qt::LandscapeOrientation:
        orientationChanged(Qt::PortraitOrientation);
        break;
    case Qt::PortraitOrientation:
        orientationChanged(Qt::InvertedLandscapeOrientation);
        break;
    case Qt::InvertedLandscapeOrientation:
        orientationChanged(Qt::InvertedPortraitOrientation);
        break;
    case Qt::InvertedPortraitOrientation:
        orientationChanged(Qt::LandscapeOrientation);
        break;
    default:
        Q_ASSERT(false);
    }

    paint();
}

void PaintedWindow::orientationChanged(Qt::ScreenOrientation newOrientation)
{
    if (contentOrientation() == newOrientation)
        return;

    if (m_animation->state() == QAbstractAnimation::Running) {
        m_nextTargetOrientation = newOrientation;
        return;
    }

    QRect rect(0, 0, width(), height());

    m_prevImage = QImage(width(), height(), QImage::Format_ARGB32_Premultiplied);
    m_nextImage = QImage(width(), height(), QImage::Format_ARGB32_Premultiplied);
    m_prevImage.fill(0);
    m_nextImage.fill(0);

    QPainter p;
    p.begin(&m_prevImage);
    p.setTransform(screen()->transformBetween(contentOrientation(), screen()->orientation(), rect));
    paint(&p, screen()->mapBetween(contentOrientation(), screen()->orientation(), rect));
    p.end();

    p.begin(&m_nextImage);
    p.setTransform(screen()->transformBetween(newOrientation, screen()->orientation(), rect));
    paint(&p, screen()->mapBetween(newOrientation, screen()->orientation(), rect));
    p.end();

    m_deltaRotation = screen()->angleBetween(newOrientation, contentOrientation());
    if (m_deltaRotation > 180)
        m_deltaRotation = 180 - m_deltaRotation;

    m_targetOrientation = newOrientation;
    m_animation->start();
}

void PaintedWindow::rotationDone()
{
    reportContentOrientationChange(m_targetOrientation);
    if (m_nextTargetOrientation != Qt::PrimaryOrientation) {
        Q_ASSERT(m_animation->state() != QAbstractAnimation::Running);
        orientationChanged(m_nextTargetOrientation);
        m_nextTargetOrientation = Qt::PrimaryOrientation;
    }
}

void PaintedWindow::setRotation(qreal r)
{
    if (r != m_rotation) {
        m_rotation = r;
        emit rotationChanged(r);
    }
}

void PaintedWindow::paint()
{
    m_context->makeCurrent(this);

    QRect rect(0, 0, width() * devicePixelRatio(), height() * devicePixelRatio());

    QOpenGLPaintDevice device(size() * devicePixelRatio());
    QPainter painter(&device);

    QPainterPath path;
    path.addEllipse(rect);
    painter.setCompositionMode(QPainter::CompositionMode_Source);
    painter.fillRect(rect, Qt::transparent);
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.fillPath(path, Qt::blue);

    if (contentOrientation() != m_targetOrientation) {
        painter.setRenderHint(QPainter::SmoothPixmapTransform);
        painter.save();
        painter.translate(width() / 2, height() / 2);
        painter.rotate(m_deltaRotation * m_rotation);
        painter.translate(-width() / 2, -height() / 2);
        painter.drawImage(0, 0, m_prevImage);
        painter.restore();
        painter.translate(width() / 2, height() / 2);
        painter.rotate(m_deltaRotation * m_rotation - m_deltaRotation);
        painter.translate(-width() / 2, -height() / 2);
        painter.setOpacity(m_rotation);
        painter.drawImage(0, 0, m_nextImage);
    } else {
        QRect mapped = screen()->mapBetween(contentOrientation(), screen()->orientation(), rect);

        painter.setTransform(screen()->transformBetween(contentOrientation(), screen()->orientation(), rect));
        paint(&painter, mapped);
        painter.end();
    }

    m_context->swapBuffers(this);
}

void PaintedWindow::paint(QPainter *painter, const QRect &rect)
{
    painter->setRenderHint(QPainter::Antialiasing);
    QFont font;
    font.setPixelSize(64);
    painter->setFont(font);
    painter->drawText(rect, Qt::AlignCenter, "Hello");
}
