/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtSCriptTools 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 "qscriptedit_p.h"
#include "qscriptsyntaxhighlighter_p.h"

#include <QtGui/qpainter.h>
#include <QtGui/qicon.h>
#include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qlabel.h>
#include <QtWidgets/qlineedit.h>
#include <QtWidgets/qmenu.h>
#include <QtWidgets/qaction.h>
#include <QtWidgets/qwidgetaction.h>
#include <QtCore/qdebug.h>

QT_BEGIN_NAMESPACE

class QScriptEditExtraArea : public QWidget
{
public:
    QScriptEditExtraArea(QScriptEdit *edit)
        : QWidget(edit)
    {
        setMouseTracking(true);
    }

    QSize sizeHint() const {
        return QSize(editor()->extraAreaWidth(), 0);
    }

protected:
    void paintEvent(QPaintEvent *event)
    {
        editor()->extraAreaPaintEvent(event);
    }
    void mousePressEvent(QMouseEvent *event)
    {
        editor()->extraAreaMouseEvent(event);
    }
    void mouseMoveEvent(QMouseEvent *event)
    {
        editor()->extraAreaMouseEvent(event);
    }
    void mouseReleaseEvent(QMouseEvent *event)
    {
        editor()->extraAreaMouseEvent(event);
    }
    bool event(QEvent *event)
    {
        if (editor()->extraAreaEvent(event))
            return true;
        return QWidget::event(event);
    }

private:
    QScriptEdit *editor() const
    {
        return qobject_cast<QScriptEdit*>(parent());
    }
};



QScriptEdit::QScriptEdit(QWidget *parent)
    : QPlainTextEdit(parent)
{
    m_baseLineNumber = 1;
    m_executionLineNumber = -1;

    m_extraArea = new QScriptEditExtraArea(this);

    QObject::connect(this, SIGNAL(blockCountChanged(int)),
                     this, SLOT(updateExtraAreaWidth()));
    QObject::connect(this, SIGNAL(updateRequest(QRect,int)),
                     this, SLOT(updateExtraArea(QRect,int)));
    QObject::connect(this, SIGNAL(cursorPositionChanged()),
                     this, SLOT(highlightCurrentLine()));

    updateExtraAreaWidth();

#ifndef QT_NO_SYNTAXHIGHLIGHTER
    (void) new QScriptSyntaxHighlighter(document());
#endif
}

QScriptEdit::~QScriptEdit()
{
}

int QScriptEdit::baseLineNumber() const
{
    return m_baseLineNumber;
}

void QScriptEdit::setBaseLineNumber(int base)
{
    m_baseLineNumber = base;
    m_extraArea->update();
}

int QScriptEdit::executionLineNumber() const
{
    return m_executionLineNumber;
}

void QScriptEdit::setExecutionLineNumber(int lineNumber, bool error)
{
    m_executionLineNumber = lineNumber;
    m_executionLineNumberHasError = error;
    m_extraArea->update();
    updateExtraSelections();
    gotoLine(lineNumber);
}

void QScriptEdit::setExecutableLineNumbers(const QSet<int> &lineNumbers)
{
    m_executableLineNumbers = lineNumbers;
}

bool QScriptEdit::isExecutableLine(int lineNumber) const
{
#if 0 // ### enable me once we have information about the script again
    return m_executableLineNumbers.contains(lineNumber);
#else
    Q_UNUSED(lineNumber);
    return true;
#endif
}

int QScriptEdit::currentLineNumber() const
{
    return textCursor().blockNumber() + m_baseLineNumber;
}

void QScriptEdit::gotoLine(int lineNumber)
{
#ifndef QT_NO_SYNTAXHIGHLIGHTER
    int blockNumber = lineNumber - m_baseLineNumber;
    const QTextBlock &block = document()->findBlockByNumber(blockNumber);
    if (block.isValid()) {
        setTextCursor(QTextCursor(block));
        centerCursor();
    }
#else
    Q_UNUSED(lineNumber);
#endif
}

void QScriptEdit::setBreakpoint(int lineNumber)
{
    m_breakpoints[lineNumber] = BreakpointData();
    m_extraArea->update();
}

void QScriptEdit::setBreakpointEnabled(int lineNumber, bool enable)
{
    m_breakpoints[lineNumber].enabled = enable;
    m_extraArea->update();
}

void QScriptEdit::deleteBreakpoint(int lineNumber)
{
    m_breakpoints.remove(lineNumber);
    m_extraArea->update();
}

void QScriptEdit::paintEvent(QPaintEvent *e)
{
    QPlainTextEdit::paintEvent(e);
}

void QScriptEdit::resizeEvent(QResizeEvent *e)
{
    QPlainTextEdit::resizeEvent(e);

    QRect cr = contentsRect();
    int x = isLeftToRight() ? cr.left() : cr.left() + cr.width() - extraAreaWidth();
    m_extraArea->setGeometry(QRect(x, cr.top(), extraAreaWidth(), cr.height()));
}

void QScriptEdit::updateExtraAreaWidth()
{
    if (isLeftToRight())
        setViewportMargins(extraAreaWidth(), 0, 0, 0);
    else
        setViewportMargins(0, 0, extraAreaWidth(), 0);
}

void QScriptEdit::updateExtraArea(const QRect &rect, int dy)
{
    if (dy)
        m_extraArea->scroll(0, dy);
    else
        m_extraArea->update(0, rect.y(), m_extraArea->width(), rect.height());

    if (rect.contains(viewport()->rect()))
        updateExtraAreaWidth();
}

void QScriptEdit::highlightCurrentLine()
{
    updateExtraSelections();
}

void QScriptEdit::updateExtraSelections()
{
    QList<QTextEdit::ExtraSelection> extraSelections;

    {
        QTextEdit::ExtraSelection selection;
        QColor lineColor = QColor(Qt::yellow).lighter(160);
        selection.format.setBackground(lineColor);
        selection.format.setProperty(QTextFormat::FullWidthSelection, true);
        selection.cursor = textCursor();
        selection.cursor.clearSelection();
        extraSelections.append(selection);
    }
    if (m_executionLineNumber != -1) {
        QTextEdit::ExtraSelection selection;
        QColor lineColor;
        if (m_executionLineNumberHasError)
            lineColor = QColor(Qt::red);
        else
            lineColor = QColor(Qt::green).lighter(160);
        selection.format.setBackground(lineColor);
        selection.format.setProperty(QTextFormat::FullWidthSelection, true);
#ifndef QT_NO_SYNTAXHIGHLIGHTER
        int blockNumber = m_executionLineNumber - m_baseLineNumber;
        selection.cursor = QTextCursor(document()->findBlockByNumber(blockNumber));
#endif
        selection.cursor.clearSelection();
        extraSelections.append(selection);
    }

    setExtraSelections(extraSelections);
}

int QScriptEdit::extraAreaWidth() const
{
    int space = 0;
    const QFontMetrics fm(fontMetrics());

    int digits = 1;
    int max = qMax(1, blockCount() + m_baseLineNumber);
    while (max >= 10) {
        max /= 10;
        ++digits;
    }
    space += fm.horizontalAdvance(QLatin1Char('9')) * digits;

    int markWidth = fm.lineSpacing();
    space += markWidth;

    space += 4;

    return space;
}

void QScriptEdit::extraAreaPaintEvent(QPaintEvent *e)
{
    QRect rect = e->rect();
    QPalette pal = palette();
    pal.setCurrentColorGroup(QPalette::Active);
    QPainter painter(m_extraArea);
    painter.fillRect(rect, Qt::lightGray);
    const QFontMetrics fm(fontMetrics());

    int markWidth = fm.lineSpacing();
    int extraAreaWidth = m_extraArea->width();

    QLinearGradient gradient(QPointF(extraAreaWidth - 10, 0), QPointF(extraAreaWidth, 0));
    gradient.setColorAt(0, pal.color(QPalette::Window));
    gradient.setColorAt(1, pal.color(QPalette::Base));
    painter.fillRect(rect, gradient);

    QLinearGradient gradient2(QPointF(0, 0), QPointF(markWidth, 0));
    gradient2.setColorAt(0, pal.color(QPalette::Dark));
    gradient2.setColorAt(1, pal.color(QPalette::Window));
    painter.fillRect(rect.intersected(QRect(rect.x(), rect.y(), markWidth, rect.height())), gradient2);

    painter.setPen(QPen(pal.color(QPalette::Window), 2));
    if (isLeftToRight())
        painter.drawLine(rect.x() + extraAreaWidth-1, rect.top(), rect.x() + extraAreaWidth-1, rect.bottom());
    else
        painter.drawLine(rect.x(), rect.top(), rect.x(), rect.bottom());
    painter.setRenderHint(QPainter::Antialiasing);

#ifndef QT_NO_SYNTAXHIGHLIGHTER
    QTextBlock block = firstVisibleBlock();
    int blockNumber = block.blockNumber();
    qreal top = blockBoundingGeometry(block).translated(contentOffset()).top();
    qreal bottom = top + blockBoundingRect(block).height();

    QString imagesPath = QString::fromLatin1(":/qt/scripttools/debugging/images");
    QString imageExt;
// SVGs don't work on all platforms, even when QT_NO_SVG is not defined, so disable SVG usage for now.
// #ifndef QT_NO_SVG
#if 0
    imageExt = QString::fromLatin1("svg");
#else
    imageExt = QString::fromLatin1("png");
#endif

    while (block.isValid() && top <= rect.bottom()) {
        if (block.isVisible() && bottom >= rect.top()) {

            int lineNumber = blockNumber + m_baseLineNumber;
            if (m_breakpoints.contains(lineNumber)) {
                int radius = fm.lineSpacing() - 1;
                QRect r(rect.x(), (int)top, radius, radius);
                QIcon icon(m_breakpoints[lineNumber].enabled
                           ? QString::fromLatin1("%0/breakpoint.%1").arg(imagesPath).arg(imageExt)
                           : QString::fromLatin1("%0/d_breakpoint.%1").arg(imagesPath).arg(imageExt));
                icon.paint(&painter, r, Qt::AlignCenter);
            }
            if (m_executionLineNumber == lineNumber) {
                int radius = fm.lineSpacing() - 1;
                QRect r(rect.x(), (int)top, radius, radius);
                QIcon icon(QString::fromLatin1("%0/location.%1").arg(imagesPath).arg(imageExt));
                icon.paint(&painter, r, Qt::AlignCenter);
            }

            if (!isExecutableLine(lineNumber))
                painter.setPen(pal.color(QPalette::Mid));
            else
                painter.setPen(QColor(Qt::darkCyan));
            QString number = QString::number(lineNumber);
            painter.drawText(rect.x() + markWidth, (int)top, rect.x() + extraAreaWidth - markWidth - 4,
                             fm.height(), Qt::AlignRight, number);
        }

        block = block.next();
        top = bottom;
        bottom = top + blockBoundingRect(block).height();
        ++blockNumber;
    }
#endif
}

void QScriptEdit::extraAreaMouseEvent(QMouseEvent *e)
{
    QTextCursor cursor = cursorForPosition(QPoint(0, e->pos().y()));
#ifndef QT_NO_SYNTAXHIGHLIGHTER
    cursor.setPosition(cursor.block().position());
#endif

    QFontMetrics fm(font());
    int markWidth = fm.lineSpacing();

    if (e->type() == QEvent::MouseMove && e->buttons() == 0) { // mouse tracking
        bool hand = (e->pos().x() <= markWidth);
        int lineNumber = cursor.blockNumber() + m_baseLineNumber;
        hand = hand && isExecutableLine(lineNumber);
#ifndef QT_NO_CURSOR
        if (hand != (m_extraArea->cursor().shape() == Qt::PointingHandCursor))
            m_extraArea->setCursor(hand ? Qt::PointingHandCursor : Qt::ArrowCursor);
#endif
    }

    if (e->type() == QEvent::MouseButtonPress) {
        if (e->button() == Qt::LeftButton) {
            int lineNumber = cursor.blockNumber() + m_baseLineNumber;
            bool executable = isExecutableLine(lineNumber);
            if ((e->pos().x() <= markWidth) && executable)
                m_extraAreaToggleBlockNumber = cursor.blockNumber();
            else
                m_extraAreaToggleBlockNumber = -1;
        }
    } else if (e->type() == QEvent::MouseButtonRelease) {
        if (e->button() == Qt::LeftButton) {
            if ((m_extraAreaToggleBlockNumber != -1) && (e->pos().x() <= markWidth)) {
                int lineNumber = m_extraAreaToggleBlockNumber + m_baseLineNumber;
                bool on = !m_breakpoints.contains(lineNumber);
                emit breakpointToggleRequest(lineNumber, on);
            }
        } else if (e->button() == Qt::RightButton) {
            int lineNumber = cursor.blockNumber() + m_baseLineNumber;
            if (!isExecutableLine(lineNumber))
                return;
            bool has = m_breakpoints.contains(lineNumber);
            QMenu *popup = new QMenu();
            QAction *toggleAct = new QAction(tr("Toggle Breakpoint"), popup);
            popup->addAction(toggleAct);
            QAction *disableAct = new QAction(tr("Disable Breakpoint"), popup);
            QAction *enableAct = new QAction(tr("Enable Breakpoint"), popup);
            QWidget *conditionWidget = new QWidget();
            {
                QHBoxLayout *hbox = new QHBoxLayout(conditionWidget);
                hbox->addWidget(new QLabel(tr("Breakpoint Condition:")));
                hbox->addWidget(new QLineEdit());
            }
//            QWidgetAction *conditionAct = new QWidgetAction(popup);
//            conditionAct->setDefaultWidget(conditionWidget);
            if (has) {
                popup->addSeparator();
                popup->addAction(m_breakpoints[lineNumber].enabled ? disableAct : enableAct);
//                popup->addAction(conditionAct);
            }
            QAction *ret = popup->exec(e->globalPos());
            if (ret) {
                if (ret == toggleAct) {
                    emit breakpointToggleRequest(lineNumber, !has);
                } else if (ret == disableAct) {
                    emit breakpointEnableRequest(lineNumber, false);
                } else if (ret == enableAct) {
                    emit breakpointEnableRequest(lineNumber, true);
                }// else if (ret == conditionAct) {
                //}
            }
            popup->deleteLater();
        }
    }
}

bool QScriptEdit::extraAreaEvent(QEvent *e)
{
    if (e->type() == QEvent::ToolTip) {
        // ### show the breakpoint's condition, if any
        return true;
    }
    return false;
}

QT_END_NAMESPACE
