/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module 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 <qtprintsupportglobal.h>

#ifndef QT_NO_PRINTER
#include <qdebug.h>
#include "private/qpaintengine_alpha_p.h"

#include "private/qpainter_p.h"
#include "private/qpicture_p.h"
#include "private/qfont_p.h"
#include "QtGui/qpicture.h"

QT_BEGIN_NAMESPACE

QAlphaPaintEngine::QAlphaPaintEngine(QAlphaPaintEnginePrivate &data, PaintEngineFeatures devcaps)
    : QPaintEngine(data, devcaps)
{

}

QAlphaPaintEngine::~QAlphaPaintEngine()
{

}

bool QAlphaPaintEngine::begin(QPaintDevice *pdev)
{
    Q_D(QAlphaPaintEngine);

    d->m_continueCall = true;
    if (d->m_pass != 0) {
        return true;
    }

    d->m_savedcaps = gccaps;
    d->m_pdev = pdev;

    d->m_alphaPen = false;
    d->m_alphaBrush = false;
    d->m_alphaOpacity = false;
    d->m_hasalpha = false;
    d->m_advancedPen = false;
    d->m_advancedBrush = false;
    d->m_complexTransform = false;
    d->m_emulateProjectiveTransforms = false;

    // clear alpha region
    d->m_alphargn = QRegion();
    d->m_cliprgn = QRegion();
    d->m_pen = QPen();
    d->m_transform = QTransform();

    flushAndInit();

    return true;
}

bool QAlphaPaintEngine::end()
{
    Q_D(QAlphaPaintEngine);

    d->m_continueCall = true;
    if (d->m_pass != 0) {
        return true;
    }

    flushAndInit(false);
    return true;
}

void QAlphaPaintEngine::updateState(const QPaintEngineState &state)
{
    Q_D(QAlphaPaintEngine);

    DirtyFlags flags = state.state();
    if (flags & QPaintEngine::DirtyTransform) {
        d->m_transform = state.transform();
        d->m_complexTransform = (d->m_transform.type() > QTransform::TxScale);
        d->m_emulateProjectiveTransforms = !(d->m_savedcaps & QPaintEngine::PerspectiveTransform)
                                           && !(d->m_savedcaps & QPaintEngine::AlphaBlend)
                                           && (d->m_transform.type() >= QTransform::TxProject);
    }
    if (flags & QPaintEngine::DirtyPen) {
        d->m_pen = state.pen();
        if (d->m_pen.style() == Qt::NoPen) {
            d->m_advancedPen = false;
            d->m_alphaPen = false;
        } else {
            d->m_advancedPen = (d->m_pen.brush().style() != Qt::SolidPattern);
            d->m_alphaPen = !d->m_pen.brush().isOpaque();
        }
    }

    if (d->m_pass != 0) {
        d->m_continueCall = true;
        return;
    }
    d->m_continueCall = false;

    if (flags & QPaintEngine::DirtyOpacity) {
        d->m_alphaOpacity = (state.opacity() != 1.0f);
    }

    if (flags & QPaintEngine::DirtyBrush) {
        if (state.brush().style() == Qt::NoBrush) {
            d->m_advancedBrush = false;
            d->m_alphaBrush = false;
        } else {
            d->m_advancedBrush = (state.brush().style() != Qt::SolidPattern);
            d->m_alphaBrush = !state.brush().isOpaque();
        }
    }


    d->m_hasalpha = d->m_alphaOpacity || d->m_alphaBrush || d->m_alphaPen;

    if (d->m_picengine) {
        const QPainter *p = painter();
        d->m_picpainter->setPen(p->pen());
        d->m_picpainter->setBrush(p->brush());
        d->m_picpainter->setBrushOrigin(p->brushOrigin());
        d->m_picpainter->setFont(p->font());
        d->m_picpainter->setOpacity(p->opacity());
        d->m_picpainter->setTransform(p->combinedTransform());
        d->m_picengine->updateState(state);
    }
}

void QAlphaPaintEngine::drawPath(const QPainterPath &path)
{
    Q_D(QAlphaPaintEngine);

    QRectF tr = d->addPenWidth(path);

    if (d->m_pass == 0) {
        d->m_continueCall = false;
        if (d->canSeeTroughBackground(d->m_hasalpha, tr) || d->m_advancedPen || d->m_advancedBrush
            || d->m_emulateProjectiveTransforms)
        {
            d->addAlphaRect(tr);
        }

        d->addDirtyRect(tr);

        if (d->m_picengine)
            d->m_picengine->drawPath(path);
    } else {
        d->m_continueCall = !d->fullyContained(tr);
    }
}

void QAlphaPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
{
    Q_D(QAlphaPaintEngine);

    QPolygonF poly;
    poly.reserve(pointCount);
    for (int i = 0; i < pointCount; ++i)
        poly.append(points[i]);

    QPainterPath path;
    path.addPolygon(poly);
    QRectF tr = d->addPenWidth(path);

    if (d->m_pass == 0) {
        d->m_continueCall = false;
        if (d->canSeeTroughBackground(d->m_hasalpha, tr) || d->m_advancedPen || d->m_advancedBrush
            || d->m_emulateProjectiveTransforms)
        {
            d->addAlphaRect(tr);
        }

        d->addDirtyRect(tr);

        if (d->m_picengine)
            d->m_picengine->drawPolygon(points, pointCount, mode);
    } else {
        d->m_continueCall = !d->fullyContained(tr);
    }
}

void QAlphaPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
{
    Q_D(QAlphaPaintEngine);

    QRectF tr = d->m_transform.mapRect(r);
    if (d->m_pass == 0) {
        d->m_continueCall = false;
        if (d->canSeeTroughBackground(pm.hasAlpha() || d->m_alphaOpacity, tr) || d->m_complexTransform || pm.isQBitmap()) {
            d->addAlphaRect(tr);
        }

        d->addDirtyRect(tr);

        if (d->m_picengine)
            d->m_picengine->drawPixmap(r, pm, sr);

    } else {
        d->m_continueCall = !d->fullyContained(tr);
    }
}

void QAlphaPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
{
    Q_D(QAlphaPaintEngine);

    QRectF tr(p.x(), p.y() - textItem.ascent(), textItem.width() + 5, textItem.ascent() + textItem.descent() + 5);
    tr = d->m_transform.mapRect(tr);

    if (d->m_pass == 0) {
        d->m_continueCall = false;
        if (d->canSeeTroughBackground(d->m_alphaPen || d->m_alphaOpacity, tr) || d->m_advancedPen) {
            d->addAlphaRect(tr);
        }

        d->addDirtyRect(tr);

        if (d->m_picengine) {
            d->m_picengine->drawTextItem(p, textItem);
        }
    } else {
        d->m_continueCall = !d->fullyContained(tr);
    }
}

void QAlphaPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s)
{
    Q_D(QAlphaPaintEngine);

    QRectF brect = d->m_transform.mapRect(r);

    if (d->m_pass == 0) {
        d->m_continueCall = false;
        if (d->canSeeTroughBackground(pixmap.hasAlpha() || d->m_alphaOpacity, brect) || d->m_complexTransform || pixmap.isQBitmap()) {
            d->addAlphaRect(brect);
        }

        d->addDirtyRect(brect);

        if (d->m_picengine)
            d->m_picengine->drawTiledPixmap(r, pixmap, s);
    } else {
        d->m_continueCall = !d->fullyContained(brect);
    }
}

QRegion QAlphaPaintEngine::alphaClipping() const
{
    Q_D(const QAlphaPaintEngine);
    return d->m_cliprgn;
}

bool QAlphaPaintEngine::continueCall() const
{
    Q_D(const QAlphaPaintEngine);
    return d->m_continueCall;
}

void QAlphaPaintEngine::flushAndInit(bool init)
{
    Q_D(QAlphaPaintEngine);
    Q_ASSERT(d->m_pass == 0);

    if (d->m_pic) {
        d->m_picpainter->end();

        // set clip region
        d->m_alphargn = d->m_alphargn.intersected(QRect(0, 0, d->m_pdev->width(), d->m_pdev->height()));

        // just use the bounding rect if it's a complex region..
        if (d->m_alphargn.rectCount() > 10) {
            QRect br = d->m_alphargn.boundingRect();
            d->m_alphargn = QRegion(br);
        }

        const auto oldAlphaRegion = d->m_cliprgn = d->m_alphargn;

        // now replay the QPicture
        ++d->m_pass; // we are now doing pass #2

        // reset states
        gccaps = d->m_savedcaps;

        painter()->save();
        d->resetState(painter());

        // make sure the output from QPicture is unscaled
        QTransform mtx;
        mtx.scale(1.0f / (qreal(d->m_pdev->logicalDpiX()) / qreal(qt_defaultDpiX())),
                  1.0f / (qreal(d->m_pdev->logicalDpiY()) / qreal(qt_defaultDpiY())));
        painter()->setTransform(mtx);
        painter()->drawPicture(0, 0, *d->m_pic);

        d->m_cliprgn = QRegion();
        d->resetState(painter());

        // fill in the alpha images
        for (const auto &rect : oldAlphaRegion)
            d->drawAlphaImage(rect);

        d->m_alphargn = QRegion();

        painter()->restore();

        --d->m_pass; // pass #2 finished

        cleanUp();
    }

    if (init) {
        gccaps = PaintEngineFeatures(AllFeatures & ~QPaintEngine::ObjectBoundingModeGradients);

        d->m_pic = new QPicture();
        d->m_pic->d_ptr->in_memory_only = true;
        d->m_picpainter = new QPainter(d->m_pic);
        d->m_picengine = d->m_picpainter->paintEngine();

        // When newPage() is called and the m_picpainter is recreated
        // we have to copy the current state of the original printer
        // painter back to the m_picpainter
        d->m_picpainter->setPen(painter()->pen());
        d->m_picpainter->setBrush(painter()->brush());
        d->m_picpainter->setBrushOrigin(painter()->brushOrigin());
        d->m_picpainter->setFont(painter()->font());
        d->m_picpainter->setOpacity(painter()->opacity());
        d->m_picpainter->setTransform(painter()->combinedTransform());
        d->m_picengine->syncState();
        QPainterState &state = *d->m_picpainter->d_func()->state;
        QPainter *oldPainter = state.painter;
        state = *painter()->d_func()->state;
        state.painter = oldPainter;
    }
}

void QAlphaPaintEngine::cleanUp()
{
    Q_D(QAlphaPaintEngine);

    delete d->m_picpainter;
    delete d->m_pic;

    d->m_picpainter = nullptr;
    d->m_pic = nullptr;
    d->m_picengine = nullptr;
}

QAlphaPaintEnginePrivate::QAlphaPaintEnginePrivate()
    :   m_pass(0),
        m_pic(nullptr),
        m_picengine(nullptr),
        m_picpainter(nullptr),
        m_numberOfCachedRects(0),
        m_hasalpha(false),
        m_alphaPen(false),
        m_alphaBrush(false),
        m_alphaOpacity(false),
        m_advancedPen(false),
        m_advancedBrush(false),
        m_complexTransform(false)
{

}

QAlphaPaintEnginePrivate::~QAlphaPaintEnginePrivate()
{
    delete m_picpainter;
    delete m_pic;
}

QRectF QAlphaPaintEnginePrivate::addPenWidth(const QPainterPath &path)
{
    Q_Q(QAlphaPaintEngine);

    QPainterPath tmp = path;

    if (m_pen.style() == Qt::NoPen)
        return (path.controlPointRect() * m_transform).boundingRect();
    bool cosmetic = qt_pen_is_cosmetic(m_pen, q->state->renderHints());
    if (cosmetic)
        tmp = path * m_transform;

    QPainterPathStroker stroker;
    if (m_pen.widthF() == 0.0f)
        stroker.setWidth(1.0);
    else
        stroker.setWidth(m_pen.widthF());
    stroker.setJoinStyle(m_pen.joinStyle());
    stroker.setCapStyle(m_pen.capStyle());
    tmp = stroker.createStroke(tmp);
    if (cosmetic)
        return tmp.controlPointRect();

    return (tmp.controlPointRect() * m_transform).boundingRect();
}

void QAlphaPaintEnginePrivate::addAlphaRect(const QRectF &rect)
{
    m_alphargn |= rect.toAlignedRect();
}

bool QAlphaPaintEnginePrivate::canSeeTroughBackground(bool somethingInRectHasAlpha, const QRectF &rect) const
{
    if (somethingInRectHasAlpha) {
        if (m_dirtyRects.count() != m_numberOfCachedRects) {
            m_cachedDirtyRgn.setRects(m_dirtyRects.constData(), m_dirtyRects.count());
            m_numberOfCachedRects = m_dirtyRects.count();
        }
        return m_cachedDirtyRgn.intersects(rect.toAlignedRect());
    }
    return false;
}

void QAlphaPaintEnginePrivate::drawAlphaImage(const QRectF &rect)
{
    Q_Q(QAlphaPaintEngine);

    qreal dpiX = qMax(m_pdev->logicalDpiX(), 300);
    qreal dpiY = qMax(m_pdev->logicalDpiY(), 300);
    qreal xscale = (dpiX / m_pdev->logicalDpiX());
    qreal yscale = (dpiY / m_pdev->logicalDpiY());

    QTransform picscale;
    picscale.scale(xscale, yscale);

    const int tileSize = 2048;
    QSize size((int(rect.width() * xscale)), int(rect.height() * yscale));
    int divw = (size.width() / tileSize);
    int divh = (size.height() / tileSize);
    divw += 1;
    divh += 1;

    int incx = int(rect.width() / divw);
    int incy = int(rect.height() / divh);

    for (int y=0; y<divh; ++y) {
        int ypos = int((incy * y) + rect.y());
        int height = int((y == (divh - 1)) ? (rect.height() - (incy * y)) : incy) + 1;

        for (int x=0; x<divw; ++x) {
            int xpos = int((incx * x) + rect.x());
            int width = int((x == (divw - 1)) ? (rect.width() - (incx * x)) : incx) + 1;

            QSize imgsize((int)(width * xscale), (int)(height * yscale));
            QImage img(imgsize, QImage::Format_RGB32);
            img.fill(0xffffffff);

            QPainter imgpainter(&img);
            imgpainter.setTransform(picscale);
            QPointF picpos(qreal(-xpos), qreal(-ypos));
            imgpainter.drawPicture(picpos, *m_pic);
            imgpainter.end();

            q->painter()->setTransform(QTransform());
            QRect r(xpos, ypos, width, height);
            q->painter()->drawImage(r, img);
        }
    }
}

bool QAlphaPaintEnginePrivate::fullyContained(const QRectF &rect) const
{
    QRegion r(rect.toAlignedRect());
    return (m_cliprgn.intersected(r) == r);
}

void QAlphaPaintEnginePrivate::resetState(QPainter *p)
{
    p->setPen(QPen());
    p->setBrush(QBrush());
    p->setBrushOrigin(0,0);
    p->setBackground(QBrush());
    p->setFont(QFont());
    p->setTransform(QTransform());
    // The view transform is already recorded and included in the
    // picture we're about to replay. If we don't turn if off,
    // the view matrix will be applied twice.
    p->setViewTransformEnabled(false);
    p->setClipRegion(QRegion(), Qt::NoClip);
    p->setClipPath(QPainterPath(), Qt::NoClip);
    p->setClipping(false);
    p->setOpacity(1.0f);
}


QT_END_NAMESPACE

#endif // QT_NO_PRINTER
