/****************************************************************************
**
** Copyright (C) 2017 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 "context2d.h"

#include <QVariant>
#include <qmath.h>

#define qClamp(val, min, max) qMin(qMax(val, min), max)
static QList<qreal> parseNumbersList(QString::const_iterator &itr)
{
    QList<qreal> points;
    QString temp;
    while ((*itr).isSpace())
        ++itr;
    while ((*itr).isNumber() ||
           (*itr) == '-' || (*itr) == '+' || (*itr) == '.') {
        temp = QString();

        if ((*itr) == '-')
            temp += *itr++;
        else if ((*itr) == '+')
            temp += *itr++;
        while ((*itr).isDigit())
            temp += *itr++;
        if ((*itr) == '.')
            temp += *itr++;
        while ((*itr).isDigit())
            temp += *itr++;
        while ((*itr).isSpace())
            ++itr;
        if ((*itr) == ',')
            ++itr;
        points.append(temp.toDouble());
        //eat spaces
        while ((*itr).isSpace())
            ++itr;
    }

    return points;
}

QColor colorFromString(const QString &name)
{
    QString::const_iterator itr = name.constBegin();
    QList<qreal> compo;
    if (name.startsWith("rgba(")) {
        ++itr; ++itr; ++itr; ++itr; ++itr;
        compo = parseNumbersList(itr);
        if (compo.size() != 4) {
            return QColor();
        }
        //alpha seems to be always between 0-1
        compo[3] *= 255;
        return QColor((int)compo[0], (int)compo[1],
                      (int)compo[2], (int)compo[3]);
    } else if (name.startsWith("rgb(")) {
        ++itr; ++itr; ++itr; ++itr;
        compo = parseNumbersList(itr);
        if (compo.size() != 3) {
            return QColor();
        }
        return QColor((int)qClamp(compo[0], qreal(0), qreal(255)),
                      (int)qClamp(compo[1], qreal(0), qreal(255)),
                      (int)qClamp(compo[2], qreal(0), qreal(255)));
    } else {
        //QRgb color;
        //CSSParser::parseColor(name, color);
        return QColor(name);
    }
}


static QPainter::CompositionMode compositeOperatorFromString(const QString &compositeOperator)
{
    if ( compositeOperator == "source-over" ) {
        return QPainter::CompositionMode_SourceOver;
    } else if ( compositeOperator == "source-out" ) {
        return QPainter::CompositionMode_SourceOut;
    } else if ( compositeOperator == "source-in" ) {
        return QPainter::CompositionMode_SourceIn;
    } else if ( compositeOperator == "source-atop" ) {
        return QPainter::CompositionMode_SourceAtop;
    } else if ( compositeOperator == "destination-atop" ) {
        return QPainter::CompositionMode_DestinationAtop;
    } else if ( compositeOperator == "destination-in" ) {
        return QPainter::CompositionMode_DestinationIn;
    } else if ( compositeOperator == "destination-out" ) {
        return QPainter::CompositionMode_DestinationOut;
    } else if ( compositeOperator == "destination-over" ) {
        return QPainter::CompositionMode_DestinationOver;
    } else if ( compositeOperator == "darker" ) {
        return QPainter::CompositionMode_SourceOver;
    } else if ( compositeOperator == "lighter" ) {
        return QPainter::CompositionMode_SourceOver;
    } else if ( compositeOperator == "copy" ) {
        return QPainter::CompositionMode_Source;
    } else if ( compositeOperator == "xor" ) {
        return QPainter::CompositionMode_Xor;
    }

    return QPainter::CompositionMode_SourceOver;
}

static QString compositeOperatorToString(QPainter::CompositionMode op)
{
    switch (op) {
    case QPainter::CompositionMode_SourceOver:
        return "source-over";
    case QPainter::CompositionMode_DestinationOver:
        return "destination-over";
    case QPainter::CompositionMode_Clear:
        return "clear";
    case QPainter::CompositionMode_Source:
        return "source";
    case QPainter::CompositionMode_Destination:
        return "destination";
    case QPainter::CompositionMode_SourceIn:
        return "source-in";
    case QPainter::CompositionMode_DestinationIn:
        return "destination-in";
    case QPainter::CompositionMode_SourceOut:
        return "source-out";
    case QPainter::CompositionMode_DestinationOut:
        return "destination-out";
    case QPainter::CompositionMode_SourceAtop:
        return "source-atop";
    case QPainter::CompositionMode_DestinationAtop:
        return "destination-atop";
    case QPainter::CompositionMode_Xor:
        return "xor";
    case QPainter::CompositionMode_Plus:
        return "plus";
    case QPainter::CompositionMode_Multiply:
        return "multiply";
    case QPainter::CompositionMode_Screen:
        return "screen";
    case QPainter::CompositionMode_Overlay:
        return "overlay";
    case QPainter::CompositionMode_Darken:
        return "darken";
    case QPainter::CompositionMode_Lighten:
        return "lighten";
    case QPainter::CompositionMode_ColorDodge:
        return "color-dodge";
    case QPainter::CompositionMode_ColorBurn:
        return "color-burn";
    case QPainter::CompositionMode_HardLight:
        return "hard-light";
    case QPainter::CompositionMode_SoftLight:
        return "soft-light";
    case QPainter::CompositionMode_Difference:
        return "difference";
    case QPainter::CompositionMode_Exclusion:
        return "exclusion";
    default:
        break;
    }
    return QString();
}

void Context2D::save()
{
    m_stateStack.push(m_state);
}


void Context2D::restore()
{
    if (!m_stateStack.isEmpty()) {
        m_state = m_stateStack.pop();
        m_state.flags = AllIsFullOfDirt;
    }
}


void Context2D::scale(qreal x, qreal y)
{
    m_state.matrix.scale(x, y);
    m_state.flags |= DirtyTransformationMatrix;
}


void Context2D::rotate(qreal angle)
{
    m_state.matrix.rotate(qRadiansToDegrees(angle));
    m_state.flags |= DirtyTransformationMatrix;
}


void Context2D::translate(qreal x, qreal y)
{
    m_state.matrix.translate(x, y);
    m_state.flags |= DirtyTransformationMatrix;
}


void Context2D::transform(qreal m11, qreal m12, qreal m21, qreal m22,
                          qreal dx, qreal dy)
{
    QTransform mat(m11, m12,
                m21, m22,
                dx, dy);
    m_state.matrix *= mat;
    m_state.flags |= DirtyTransformationMatrix;
}


void Context2D::setTransform(qreal m11, qreal m12, qreal m21, qreal m22,
                             qreal dx, qreal dy)
{
    QTransform mat(m11, m12,
                m21, m22,
                dx, dy);
    m_state.matrix = mat;
    m_state.flags |= DirtyTransformationMatrix;
}


QString Context2D::globalCompositeOperation() const
{
    return compositeOperatorToString(m_state.globalCompositeOperation);
}

void Context2D::setGlobalCompositeOperation(const QString &op)
{
    QPainter::CompositionMode mode =
        compositeOperatorFromString(op);
    m_state.globalCompositeOperation = mode;
    m_state.flags |= DirtyGlobalCompositeOperation;
}

QVariant Context2D::strokeStyle() const
{
    return m_state.strokeStyle;
}

void Context2D::setStrokeStyle(const QVariant &style)
{
    if (style.canConvert<CanvasGradient>()) {
        CanvasGradient cg = qvariant_cast<CanvasGradient>(style);
        m_state.strokeStyle = cg.value;
    } else {
        QColor color = colorFromString(style.toString());
        m_state.strokeStyle = color;
    }
    m_state.flags |= DirtyStrokeStyle;
}

QVariant Context2D::fillStyle() const
{
    return m_state.fillStyle;
}

//! [3]
void Context2D::setFillStyle(const QVariant &style)
{
    if (style.canConvert<CanvasGradient>()) {
        CanvasGradient cg = qvariant_cast<CanvasGradient>(style);
        m_state.fillStyle = cg.value;
    } else {
        QColor color = colorFromString(style.toString());
        m_state.fillStyle = color;
    }
    m_state.flags |= DirtyFillStyle;
}
//! [3]

qreal Context2D::globalAlpha() const
{
    return m_state.globalAlpha;
}

void Context2D::setGlobalAlpha(qreal alpha)
{
    m_state.globalAlpha = alpha;
    m_state.flags |= DirtyGlobalAlpha;
}


CanvasGradient Context2D::createLinearGradient(qreal x0, qreal y0,
                                               qreal x1, qreal y1)
{
    QLinearGradient g(x0, y0, x1, y1);
    return CanvasGradient(g);
}


CanvasGradient Context2D::createRadialGradient(qreal x0, qreal y0,
                                               qreal r0, qreal x1,
                                               qreal y1, qreal r1)
{
    QRadialGradient g(QPointF(x1, y1), r0+r1, QPointF(x0, y0));
    return CanvasGradient(g);
}

qreal Context2D::lineWidth() const
{
    return m_state.lineWidth;
}

void Context2D::setLineWidth(qreal w)
{
    m_state.lineWidth = w;
    m_state.flags |= DirtyLineWidth;
}

//! [0]
QString Context2D::lineCap() const
{
    switch (m_state.lineCap) {
    case Qt::FlatCap:
        return "butt";
    case Qt::SquareCap:
        return "square";
    case Qt::RoundCap:
        return "round";
    default: ;
    }
    return QString();
}

void Context2D::setLineCap(const QString &capString)
{
    Qt::PenCapStyle style;
    if (capString == "round")
        style = Qt::RoundCap;
    else if (capString == "square")
        style = Qt::SquareCap;
    else //if (capString == "butt")
        style = Qt::FlatCap;
    m_state.lineCap = style;
    m_state.flags |= DirtyLineCap;
}
//! [0]

QString Context2D::lineJoin() const
{
    switch (m_state.lineJoin) {
    case Qt::RoundJoin:
        return "round";
    case Qt::BevelJoin:
        return "bevel";
    case Qt::MiterJoin:
        return "miter";
    default: ;
    }
    return QString();
}

void Context2D::setLineJoin(const QString &joinString)
{
    Qt::PenJoinStyle style;
    if (joinString == "round")
        style = Qt::RoundJoin;
    else if (joinString == "bevel")
        style = Qt::BevelJoin;
    else //if (joinString == "miter")
        style = Qt::MiterJoin;
    m_state.lineJoin = style;
    m_state.flags |= DirtyLineJoin;
}

qreal Context2D::miterLimit() const
{
    return m_state.miterLimit;
}

void Context2D::setMiterLimit(qreal m)
{
    m_state.miterLimit = m;
    m_state.flags |= DirtyMiterLimit;
}

void Context2D::setShadowOffsetX(qreal x)
{
    m_state.shadowOffsetX = x;
    m_state.flags |= DirtyShadowOffsetX;
}

void Context2D::setShadowOffsetY(qreal y)
{
    m_state.shadowOffsetY = y;
    m_state.flags |= DirtyShadowOffsetY;
}

void Context2D::setShadowBlur(qreal b)
{
    m_state.shadowBlur = b;
    m_state.flags |= DirtyShadowBlur;
}

void Context2D::setShadowColor(const QString &str)
{
    m_state.shadowColor = colorFromString(str);
    m_state.flags |= DirtyShadowColor;
}

qreal Context2D::shadowOffsetX() const
{
    return m_state.shadowOffsetX;
}

qreal Context2D::shadowOffsetY() const
{
    return m_state.shadowOffsetY;
}


qreal Context2D::shadowBlur() const
{
    return m_state.shadowBlur;
}


QString Context2D::shadowColor() const
{
    return m_state.shadowColor.name();
}


void Context2D::clearRect(qreal x, qreal y, qreal w, qreal h)
{
    beginPainting();
    m_painter.save();
    m_painter.setTransform(QTransform(m_state.matrix), false);
    m_painter.setCompositionMode(QPainter::CompositionMode_Source);
    m_painter.fillRect(QRectF(x, y, w, h), QColor(0, 0, 0, 0));
    m_painter.restore();
    scheduleChange();
}


//! [1]
void Context2D::fillRect(qreal x, qreal y, qreal w, qreal h)
{
    beginPainting();
    m_painter.save();
    m_painter.setTransform(QTransform(m_state.matrix), false);
    m_painter.fillRect(QRectF(x, y, w, h), m_painter.brush());
    m_painter.restore();
    scheduleChange();
}
//! [1]


void Context2D::strokeRect(qreal x, qreal y, qreal w, qreal h)
{
    QPainterPath path;
    path.addRect(x, y, w, h);
    beginPainting();
    m_painter.save();
    m_painter.setTransform(QTransform(m_state.matrix), false);
    m_painter.strokePath(path, m_painter.pen());
    m_painter.restore();
    scheduleChange();
}


void Context2D::beginPath()
{
    m_path = QPainterPath();
}


void Context2D::closePath()
{
    m_path.closeSubpath();
}


void Context2D::moveTo(qreal x, qreal y)
{
    QPointF pt = m_state.matrix.map(QPointF(x, y));
    m_path.moveTo(pt);
}


void Context2D::lineTo(qreal x, qreal y)
{
    QPointF pt = m_state.matrix.map(QPointF(x, y));
    m_path.lineTo(pt);
}


void Context2D::quadraticCurveTo(qreal cpx, qreal cpy, qreal x, qreal y)
{
    QPointF cp = m_state.matrix.map(QPointF(cpx, cpy));
    QPointF xy = m_state.matrix.map(QPointF(x, y));
    m_path.quadTo(cp, xy);
}


void Context2D::bezierCurveTo(qreal cp1x, qreal cp1y,
                              qreal cp2x, qreal cp2y, qreal x, qreal y)
{
    QPointF cp1 = m_state.matrix.map(QPointF(cp1x, cp1y));
    QPointF cp2 = m_state.matrix.map(QPointF(cp2x, cp2y));
    QPointF end = m_state.matrix.map(QPointF(x, y));
    m_path.cubicTo(cp1, cp2, end);
}


void Context2D::arcTo(qreal x1, qreal y1, qreal x2, qreal y2, qreal radius)
{
    //FIXME: this is surely busted
    QPointF st  = m_state.matrix.map(QPointF(x1, y1));
    QPointF end = m_state.matrix.map(QPointF(x2, y2));
    m_path.arcTo(st.x(), st.y(),
                 end.x()-st.x(), end.y()-st.y(),
                 radius, 90);
}


void Context2D::rect(qreal x, qreal y, qreal w, qreal h)
{
    QPainterPath path; path.addRect(x, y, w, h);
    path = m_state.matrix.map(path);
    m_path.addPath(path);
}

void Context2D::arc(qreal xc, qreal yc, qreal radius,
                    qreal sar, qreal ear,
                    bool anticlockwise)
{
    //### HACK
    // In Qt we don't switch the coordinate system for degrees
    // and still use the 0,0 as bottom left for degrees so we need
    // to switch
    sar = -sar;
    ear = -ear;
    anticlockwise = !anticlockwise;
    //end hack

    float sa = qRadiansToDegrees(sar);
    float ea = qRadiansToDegrees(ear);

    double span = 0;

    double xs     = xc - radius;
    double ys     = yc - radius;
    double width  = radius*2;
    double height = radius*2;

    if (!anticlockwise && (ea < sa)) {
        span += 360;
    } else if (anticlockwise && (sa < ea)) {
        span -= 360;
    }

    //### this is also due to switched coordinate system
    // we would end up with a 0 span instead of 360
    if (!(qFuzzyCompare(span + (ea - sa) + 1, 1) &&
          qFuzzyCompare(qAbs(span), 360))) {
        span   += ea - sa;
    }

    QPainterPath path;
    path.moveTo(QPointF(xc + radius  * cos(sar),
                                yc - radius  * sin(sar)));

    path.arcTo(xs, ys, width, height, sa, span);
    path = m_state.matrix.map(path);
    m_path.addPath(path);
}


void Context2D::fill()
{
    beginPainting();
    m_painter.fillPath(m_path, m_painter.brush());
    scheduleChange();
}


void Context2D::stroke()
{
    beginPainting();
    m_painter.save();
    m_painter.setTransform(QTransform(m_state.matrix), false);
    QPainterPath tmp = m_state.matrix.inverted().map(m_path);
    m_painter.strokePath(tmp, m_painter.pen());
    m_painter.restore();
    scheduleChange();
}


void Context2D::clip()
{
    m_state.clipPath = m_path;
    m_state.flags |= DirtyClippingRegion;
}


bool Context2D::isPointInPath(qreal x, qreal y) const
{
    return m_path.contains(QPointF(x, y));
}


ImageData Context2D::getImageData(qreal sx, qreal sy, qreal sw, qreal sh)
{
    Q_UNUSED(sx);
    Q_UNUSED(sy);
    Q_UNUSED(sw);
    Q_UNUSED(sh);
    return ImageData();
}


void Context2D::putImageData(ImageData image, qreal dx, qreal dy)
{
    Q_UNUSED(image);
    Q_UNUSED(dx);
    Q_UNUSED(dy);
}

Context2D::Context2D(QObject *parent)
    : QObject(parent), m_changeTimerId(-1)
{
    reset();
}

const QImage &Context2D::endPainting()
{
    if (m_painter.isActive())
        m_painter.end();
    return m_image;
}

void Context2D::beginPainting()
{
    if (!m_painter.isActive()) {
        m_painter.begin(&m_image);
        m_painter.setRenderHint(QPainter::Antialiasing);
        if (!m_state.clipPath.isEmpty())
            m_painter.setClipPath(m_state.clipPath);
        m_painter.setBrush(m_state.fillStyle);
        m_painter.setOpacity(m_state.globalAlpha);
        QPen pen;
        pen.setBrush(m_state.strokeStyle);
        if (pen.style() == Qt::NoPen)
            pen.setStyle(Qt::SolidLine);
        pen.setCapStyle(m_state.lineCap);
        pen.setJoinStyle(m_state.lineJoin);
        pen.setWidthF(m_state.lineWidth);
        pen.setMiterLimit(m_state.miterLimit);
        m_painter.setPen(pen);
    } else {
        if ((m_state.flags & DirtyClippingRegion) && !m_state.clipPath.isEmpty())
            m_painter.setClipPath(m_state.clipPath);
        if (m_state.flags & DirtyFillStyle)
            m_painter.setBrush(m_state.fillStyle);
        if (m_state.flags & DirtyGlobalAlpha)
            m_painter.setOpacity(m_state.globalAlpha);
        if (m_state.flags & DirtyGlobalCompositeOperation)
            m_painter.setCompositionMode(m_state.globalCompositeOperation);
        if (m_state.flags & MDirtyPen) {
            QPen pen = m_painter.pen();
            if (m_state.flags & DirtyStrokeStyle)
                pen.setBrush(m_state.strokeStyle);
            if (m_state.flags & DirtyLineWidth)
                pen.setWidthF(m_state.lineWidth);
            if (m_state.flags & DirtyLineCap)
                pen.setCapStyle(m_state.lineCap);
            if (m_state.flags & DirtyLineJoin)
                pen.setJoinStyle(m_state.lineJoin);
            if (m_state.flags & DirtyMiterLimit)
                pen.setMiterLimit(m_state.miterLimit);
            m_painter.setPen(pen);
        }
        m_state.flags = 0;
    }
}

void Context2D::clear()
{
    endPainting();
    m_image.fill(qRgba(0,0,0,0));
    scheduleChange();
}

void Context2D::reset()
{
    m_stateStack.clear();
    m_state.matrix = QTransform();
    m_state.clipPath = QPainterPath();
    m_state.globalAlpha = 1.0;
    m_state.globalCompositeOperation = QPainter::CompositionMode_SourceOver;
    m_state.strokeStyle = Qt::black;
    m_state.fillStyle = Qt::black;
    m_state.lineWidth = 1;
    m_state.lineCap = Qt::FlatCap;
    m_state.lineJoin = Qt::MiterJoin;
    m_state.miterLimit = 10;
    m_state.shadowOffsetX = 0;
    m_state.shadowOffsetY = 0;
    m_state.shadowBlur = 0;
    m_state.shadowColor = qRgba(0, 0, 0, 0);
    m_state.flags = AllIsFullOfDirt;
    clear();
}

void Context2D::setSize(int width, int height)
{
    endPainting();
    QImage newi(width, height, QImage::Format_ARGB32_Premultiplied);
    newi.fill(qRgba(0,0,0,0));
    QPainter p(&newi);
    p.drawImage(0, 0, m_image);
    p.end();
    m_image = newi;
    scheduleChange();
}

void Context2D::setSize(const QSize &size)
{
    setSize(size.width(), size.height());
}

QSize Context2D::size() const
{
    return m_image.size();
}

void Context2D::drawImage(DomImage *image, qreal dx, qreal dy)
{
    if (!image)
        return;
    if (dx < 0) {
        qreal sx = qAbs(dx);
        qreal sy = qAbs(dy);
        qreal sw = image->width() - sx;
        qreal sh = image->height() - sy;

        drawImage(image, sx, sy, sw, sh, 0, 0, sw, sh);
    } else {
        beginPainting();
        m_painter.drawImage(QPointF(dx, dy), image->image());
        scheduleChange();
    }
}

void Context2D::drawImage(DomImage *image, qreal dx, qreal dy,
                          qreal dw, qreal dh)
{
    if (!image)
        return;
    beginPainting();
    m_painter.drawImage(QRectF(dx, dy, dw, dh).toRect(), image->image());
    scheduleChange();
}

void Context2D::drawImage(DomImage *image, qreal sx, qreal sy,
                          qreal sw, qreal sh, qreal dx, qreal dy,
                          qreal dw, qreal dh)
{
    if (!image)
        return;
    beginPainting();
    m_painter.drawImage(QRectF(dx, dy, dw, dh), image->image(),
                        QRectF(sx, sy, sw, sh));
    scheduleChange();
}

//! [2]
void Context2D::scheduleChange()
{
    if (m_changeTimerId == -1)
        m_changeTimerId = startTimer(0);
}

void Context2D::timerEvent(QTimerEvent *e)
{
    if (e->timerId() == m_changeTimerId) {
        killTimer(m_changeTimerId);
        m_changeTimerId = -1;
        emit changed(endPainting());
    } else {
        QObject::timerEvent(e);
    }
}
//! [2]
