/*
    This file is part of Photoflare.

    Photoflare is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Photoflare is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Photoflare.  If not, see <https://www.gnu.org/licenses/>.
*/

// EraserTool - Erase pixels while dragging the mouse.

#include "EraserTool.h"
#include "PaintWidget.h"

class EraserToolPrivate
{
public:
    EraserToolPrivate ()
    {
        primaryPen.setColor(Qt::white);
    }
    QPen primaryPen;
    QPen secondaryPen;
    QPoint lastPos;
    Qt::MouseButton mouseButton;
};

EraserTool::EraserTool(QObject *parent)
    : Tool(parent)
    , d(new EraserToolPrivate){}

EraserTool::~EraserTool()
{
    delete d;
}

QCursor EraserTool::getCursor()
{
    int width = d->primaryPen.width()*m_scale;
    if(width < 5)
        width = 5;
    QPixmap pixmap(QSize(width,width));
    pixmap.fill(Qt::transparent);
    QPainter painter(&pixmap);
    if(d->primaryPen.capStyle() == Qt::SquareCap)
    {
        QPen pen = QPen(QBrush(), 1.5, Qt::DashLine);
        pen.setColor(Qt::gray);
        painter.setPen(pen);
        painter.drawRect(pixmap.rect());
    }
    else
    {
        QPen pen = QPen(QBrush(), 1, Qt::DashLine);
        pen.setColor(Qt::gray);
        painter.setPen(pen);
        painter.drawEllipse(pixmap.rect());
    }
    pixmap.setDevicePixelRatio(qApp->devicePixelRatio());
    return QCursor(pixmap);
}

int EraserTool::width() const
{
    return d->primaryPen.width();
}

void EraserTool::setWidth(int width)
{
    d->primaryPen.setWidth(width);
    emit cursorChanged(getCursor());
}

void EraserTool::setSecondaryColor(const QColor &color)
{
    d->secondaryPen.setColor(color);
}

void EraserTool::onMousePress(const QPoint &pos, Qt::MouseButton button)
{
    if (button != Qt::LeftButton)
        return;

    d->mouseButton = button;
    d->lastPos = pos;

    QPen pen = d->primaryPen;
    pen.setWidth(d->primaryPen.width());

    QPainter painter(m_paintDevice);
    if (static_cast<QImage*>(m_paintDevice)->hasAlphaChannel())
        painter.setCompositionMode(QPainter::CompositionMode_Clear);
    painter.setPen(pen);
    painter.drawPoint(pos.x(), pos.y());
    painter.end();
    {
        int half = pen.width() / 2 + 1;
        emit painted(m_paintDevice, QRect(pos, pos).adjusted(-half, -half, half, half));
    }
}

void EraserTool::onMouseMove(const QPoint &pos)
{
    if (m_paintDevice && d->mouseButton == Qt::LeftButton) {
        QPainter painter(m_paintDevice);

        QPen pen = d->primaryPen;
        pen.setWidth(d->primaryPen.width());

        if (static_cast<QImage*>(m_paintDevice)->hasAlphaChannel())
            painter.setCompositionMode(QPainter::CompositionMode_Clear);

        int w = pen.width();
        if(pen.capStyle() == Qt::SquareCap && w > 1)
        {
            painter.setPen(QPen(pen.color()));
            QBrush brush(pen.color());
            painter.setBrush(brush);

            int x1 = d->lastPos.x();
            int x2 = pos.x();
            int y1 = d->lastPos.y();
            int y2 = pos.y();

            if(x1 > x2) {
                int temp = x1; x1 = x2; x2 = temp;
                temp = y1; y1 = y2; y2 = temp;
            }

            for(int y, x = x1; x < x2; x += w/2) {
                y = (x - x1)*(y2 - y1)/(x2 - x1) + y1;
                painter.drawRect(QRect(x - w/2, y - w/2, w, w));
            }

            if(y1 > y2) {
                int temp = x1; x1 = x2; x2 = temp;
                temp = y1; y1 = y2; y2 = temp;
            }

            for(int x, y = y1; y < y2; y += w/2) {
                x = (y - y1)*(x2 - x1)/(y2 - y1) + x1;
                painter.drawRect(QRect(x - w/2, y - w/2, w, w));
            }

        }
        else
        {
            painter.setPen(pen);
            painter.drawLine(d->lastPos, pos);
        }
        int half = pen.width() / 2 + 1;
        QPoint prevPos = d->lastPos;
        d->lastPos = pos;
        emit painted(m_paintDevice, QRect(prevPos, pos).normalized().adjusted(-half, -half, half, half));
    }
}
