/****************************************************************************
**
** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
** Copyright (C) 2016 Samuel Gaist <samuel.gaist@edeltech.ch>
** 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 "regularexpressiondialog.h"

#include <QApplication>

#include <QCheckBox>
#include <QComboBox>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QSpinBox>
#include <QPlainTextEdit>
#include <QTreeWidget>

#include <QAction>
#include <QClipboard>
#include <QContextMenuEvent>

#include <QHBoxLayout>
#include <QGridLayout>
#include <QFormLayout>

#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <QRegularExpressionMatchIterator>

Q_DECLARE_METATYPE(QRegularExpression::MatchType)

static QString rawStringLiteral(QString pattern)
{
    pattern.prepend(QLatin1String("R\"RX("));
    pattern.append(QLatin1String(")RX\""));
    return pattern;
}

static QString patternToCode(QString pattern)
{
    pattern.replace(QLatin1String("\\"), QLatin1String("\\\\"));
    pattern.replace(QLatin1String("\""), QLatin1String("\\\""));
    pattern.prepend(QLatin1Char('"'));
    pattern.append(QLatin1Char('"'));
    return pattern;
}

static QString codeToPattern(QString code)
{
    for (int i = 0; i < code.size(); ++i) {
        if (code.at(i) == QLatin1Char('\\'))
            code.remove(i, 1);
    }
    if (code.startsWith(QLatin1Char('"')) && code.endsWith(QLatin1Char('"'))) {
        code.chop(1);
        code.remove(0, 1);
    }
    return code;
}

class PatternLineEdit : public QLineEdit
{
    Q_OBJECT
public:
    explicit PatternLineEdit(QWidget *parent = nullptr);

private slots:
    void copyToCode();
    void pasteFromCode();
    void escapeSelection();

protected:
    void contextMenuEvent(QContextMenuEvent *event) override;

private:
    QAction *escapeSelectionAction;
    QAction *copyToCodeAction;
    QAction *pasteFromCodeAction;
};

PatternLineEdit::PatternLineEdit(QWidget *parent) :
    QLineEdit(parent),
    escapeSelectionAction(new QAction(tr("Escape Selection"), this)),
    copyToCodeAction(new QAction(tr("Copy to Code"), this)),
    pasteFromCodeAction(new QAction(tr("Paste from Code"), this))
{
    setClearButtonEnabled(true);
    connect(escapeSelectionAction, &QAction::triggered, this, &PatternLineEdit::escapeSelection);
    connect(copyToCodeAction, &QAction::triggered, this, &PatternLineEdit::copyToCode);
    connect(pasteFromCodeAction, &QAction::triggered, this, &PatternLineEdit::pasteFromCode);
#if !QT_CONFIG(clipboard)
    copyToCodeAction->setEnabled(false);
    pasteFromCodeAction->setEnabled(false);
#endif
}

void PatternLineEdit::escapeSelection()
{
    const QString selection = selectedText();
    const QString escapedSelection = QRegularExpression::escape(selection);
    if (escapedSelection != selection) {
        QString t = text();
        t.replace(selectionStart(), selection.size(), escapedSelection);
        setText(t);
    }
}

void PatternLineEdit::copyToCode()
{
#if QT_CONFIG(clipboard)
    QGuiApplication::clipboard()->setText(patternToCode(text()));
#endif
}

void PatternLineEdit::pasteFromCode()
{
#if QT_CONFIG(clipboard)
    setText(codeToPattern(QGuiApplication::clipboard()->text()));
#endif
}

void PatternLineEdit::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu *menu = createStandardContextMenu();
    menu->setAttribute(Qt::WA_DeleteOnClose);
    menu->addSeparator();
    escapeSelectionAction->setEnabled(hasSelectedText());
    menu->addAction(escapeSelectionAction);
    menu->addSeparator();
    menu->addAction(copyToCodeAction);
    menu->addAction(pasteFromCodeAction);
    menu->popup(event->globalPos());
}

class DisplayLineEdit : public QLineEdit
{
public:
    explicit DisplayLineEdit(QWidget *parent = nullptr);
};

DisplayLineEdit::DisplayLineEdit(QWidget *parent) : QLineEdit(parent)
{
    setReadOnly(true);
    QPalette disabledPalette = palette();
    disabledPalette.setBrush(QPalette::Base, disabledPalette.brush(QPalette::Disabled, QPalette::Base));
    setPalette(disabledPalette);

#if QT_CONFIG(clipboard)
    QAction *copyAction = new QAction(this);
    copyAction->setText(RegularExpressionDialog::tr("Copy to clipboard"));
    copyAction->setIcon(QIcon(QStringLiteral(":/images/copy.png")));
    connect(copyAction, &QAction::triggered, this,
            [this] () { QGuiApplication::clipboard()->setText(text()); });
    addAction(copyAction, QLineEdit::TrailingPosition);
#endif
}

RegularExpressionDialog::RegularExpressionDialog(QWidget *parent)
    : QDialog(parent)
{
    setupUi();
    setWindowTitle(tr("QRegularExpression Example"));

    connect(patternLineEdit, &QLineEdit::textChanged, this, &RegularExpressionDialog::refresh);
    connect(subjectTextEdit, &QPlainTextEdit::textChanged, this, &RegularExpressionDialog::refresh);

    connect(caseInsensitiveOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh);
    connect(dotMatchesEverythingOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh);
    connect(multilineOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh);
    connect(extendedPatternSyntaxOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh);
    connect(invertedGreedinessOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh);
    connect(dontCaptureOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh);
    connect(useUnicodePropertiesOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh);

    connect(offsetSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
            this, &RegularExpressionDialog::refresh);

    connect(matchTypeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &RegularExpressionDialog::refresh);

    connect(anchoredMatchOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh);
    connect(dontCheckSubjectStringMatchOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh);

    patternLineEdit->setText(tr("(\\+?\\d+)-(?<prefix>\\d+)-(?<number>\\w+)"));
    subjectTextEdit->setPlainText(tr("My office number is +43-152-0123456, my mobile is 001-41-255512 instead."));

    refresh();
}

void RegularExpressionDialog::setResultUiEnabled(bool enabled)
{
    matchDetailsTreeWidget->setEnabled(enabled);
    namedGroupsTreeWidget->setEnabled(enabled);
}

static void setTextColor(QWidget *widget, const QColor &color)
{
    QPalette palette = widget->palette();
    palette.setColor(QPalette::Text, color);
    widget->setPalette(palette);
}

void RegularExpressionDialog::refresh()
{
    setUpdatesEnabled(false);

    const QString pattern = patternLineEdit->text();
    const QString text = subjectTextEdit->toPlainText();

    offsetSpinBox->setMaximum(qMax(0, text.length() - 1));

    escapedPatternLineEdit->setText(patternToCode(pattern));
    rawStringLiteralLineEdit->setText(rawStringLiteral(pattern));

    setTextColor(patternLineEdit, subjectTextEdit->palette().color(QPalette::Text));
    matchDetailsTreeWidget->clear();
    namedGroupsTreeWidget->clear();
    regexpStatusLabel->setText(QString());

    if (pattern.isEmpty()) {
        setResultUiEnabled(false);
        setUpdatesEnabled(true);
        return;
    }

    QRegularExpression rx(pattern);
    if (!rx.isValid()) {
        setTextColor(patternLineEdit, Qt::red);
        regexpStatusLabel->setText(tr("Invalid: syntax error at position %1 (%2)")
                                   .arg(rx.patternErrorOffset())
                                   .arg(rx.errorString()));
        setResultUiEnabled(false);
        setUpdatesEnabled(true);
        return;
    }

    setResultUiEnabled(true);

    QRegularExpression::MatchType matchType = qvariant_cast<QRegularExpression::MatchType>(matchTypeComboBox->currentData());
    QRegularExpression::PatternOptions patternOptions = QRegularExpression::NoPatternOption;
    QRegularExpression::MatchOptions matchOptions = QRegularExpression::NoMatchOption;

    if (anchoredMatchOptionCheckBox->isChecked())
        matchOptions |= QRegularExpression::AnchoredMatchOption;
    if (dontCheckSubjectStringMatchOptionCheckBox->isChecked())
        matchOptions |= QRegularExpression::DontCheckSubjectStringMatchOption;

    if (caseInsensitiveOptionCheckBox->isChecked())
        patternOptions |= QRegularExpression::CaseInsensitiveOption;
    if (dotMatchesEverythingOptionCheckBox->isChecked())
        patternOptions |= QRegularExpression::DotMatchesEverythingOption;
    if (multilineOptionCheckBox->isChecked())
        patternOptions |= QRegularExpression::MultilineOption;
    if (extendedPatternSyntaxOptionCheckBox->isChecked())
        patternOptions |= QRegularExpression::ExtendedPatternSyntaxOption;
    if (invertedGreedinessOptionCheckBox->isChecked())
        patternOptions |= QRegularExpression::InvertedGreedinessOption;
    if (dontCaptureOptionCheckBox->isChecked())
        patternOptions |= QRegularExpression::DontCaptureOption;
    if (useUnicodePropertiesOptionCheckBox->isChecked())
        patternOptions |= QRegularExpression::UseUnicodePropertiesOption;

    rx.setPatternOptions(patternOptions);

    const int capturingGroupsCount = rx.captureCount() + 1;

    QRegularExpressionMatchIterator iterator = rx.globalMatch(text, offsetSpinBox->value(), matchType, matchOptions);
    int i = 0;

    while (iterator.hasNext()) {
        QRegularExpressionMatch match = iterator.next();

        QTreeWidgetItem *matchDetailTopItem = new QTreeWidgetItem(matchDetailsTreeWidget);
        matchDetailTopItem->setText(0, QString::number(i));

        for (int captureGroupIndex = 0; captureGroupIndex < capturingGroupsCount; ++captureGroupIndex) {
            QTreeWidgetItem *matchDetailItem = new QTreeWidgetItem(matchDetailTopItem);
            matchDetailItem->setText(1, QString::number(captureGroupIndex));
            matchDetailItem->setText(2, match.captured(captureGroupIndex));
        }

        ++i;
    }

    matchDetailsTreeWidget->expandAll();

    regexpStatusLabel->setText(tr("Valid"));

    const QStringList namedCaptureGroups = rx.namedCaptureGroups();
    for (int i = 0; i < namedCaptureGroups.size(); ++i) {
        const QString currentNamedCaptureGroup = namedCaptureGroups.at(i);

        QTreeWidgetItem *namedGroupItem = new QTreeWidgetItem(namedGroupsTreeWidget);
        namedGroupItem->setText(0, QString::number(i));
        namedGroupItem->setText(1, currentNamedCaptureGroup.isNull() ? tr("<no name>") : currentNamedCaptureGroup);
    }


    setUpdatesEnabled(true);
}

void RegularExpressionDialog::setupUi()
{
    QWidget *leftHalfContainer = setupLeftUi();

    QFrame *verticalSeparator = new QFrame;
    verticalSeparator->setFrameStyle(QFrame::VLine | QFrame::Sunken);

    QWidget *rightHalfContainer = setupRightUi();

    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addWidget(leftHalfContainer);
    mainLayout->addWidget(verticalSeparator);
    mainLayout->addWidget(rightHalfContainer);

    setLayout(mainLayout);
}

QWidget *RegularExpressionDialog::setupLeftUi()
{
    QWidget *container = new QWidget;

    QFormLayout *layout = new QFormLayout(container);
    layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
    layout->setContentsMargins(QMargins());

    QLabel *regexpAndSubjectLabel = new QLabel(tr("<h3>Regular expression and text input</h3>"));
    layout->addRow(regexpAndSubjectLabel);

    patternLineEdit = new PatternLineEdit;
    patternLineEdit->setClearButtonEnabled(true);
    layout->addRow(tr("&Pattern:"), patternLineEdit);

    rawStringLiteralLineEdit = new DisplayLineEdit;
    layout->addRow(tr("&Raw string literal:"), rawStringLiteralLineEdit);
    escapedPatternLineEdit = new DisplayLineEdit;
    layout->addRow(tr("&Escaped pattern:"), escapedPatternLineEdit);

    subjectTextEdit = new QPlainTextEdit;
    layout->addRow(tr("&Subject text:"), subjectTextEdit);

    caseInsensitiveOptionCheckBox = new QCheckBox(tr("Case insensitive (/i)"));
    dotMatchesEverythingOptionCheckBox = new QCheckBox(tr("Dot matches everything (/s)"));
    multilineOptionCheckBox = new QCheckBox(tr("Multiline (/m)"));
    extendedPatternSyntaxOptionCheckBox = new QCheckBox(tr("Extended pattern (/x)"));
    invertedGreedinessOptionCheckBox = new QCheckBox(tr("Inverted greediness"));
    dontCaptureOptionCheckBox = new QCheckBox(tr("Don't capture"));
    useUnicodePropertiesOptionCheckBox = new QCheckBox(tr("Use unicode properties (/u)"));

    QGridLayout *patternOptionsCheckBoxLayout = new QGridLayout;
    int gridRow = 0;
    patternOptionsCheckBoxLayout->addWidget(caseInsensitiveOptionCheckBox, gridRow, 1);
    patternOptionsCheckBoxLayout->addWidget(dotMatchesEverythingOptionCheckBox, gridRow, 2);
    ++gridRow;
    patternOptionsCheckBoxLayout->addWidget(multilineOptionCheckBox, gridRow, 1);
    patternOptionsCheckBoxLayout->addWidget(extendedPatternSyntaxOptionCheckBox, gridRow, 2);
    ++gridRow;
    patternOptionsCheckBoxLayout->addWidget(invertedGreedinessOptionCheckBox, gridRow, 1);
    patternOptionsCheckBoxLayout->addWidget(dontCaptureOptionCheckBox, gridRow, 2);
    ++gridRow;
    patternOptionsCheckBoxLayout->addWidget(useUnicodePropertiesOptionCheckBox, gridRow, 1);

    layout->addRow(tr("Pattern options:"), patternOptionsCheckBoxLayout);

    offsetSpinBox = new QSpinBox;
    layout->addRow(tr("Match &offset:"), offsetSpinBox);

    matchTypeComboBox = new QComboBox;
    matchTypeComboBox->addItem(tr("Normal"), QVariant::fromValue(QRegularExpression::NormalMatch));
    matchTypeComboBox->addItem(tr("Partial prefer complete"), QVariant::fromValue(QRegularExpression::PartialPreferCompleteMatch));
    matchTypeComboBox->addItem(tr("Partial prefer first"), QVariant::fromValue(QRegularExpression::PartialPreferFirstMatch));
    matchTypeComboBox->addItem(tr("No match"), QVariant::fromValue(QRegularExpression::NoMatch));
    layout->addRow(tr("Match &type:"), matchTypeComboBox);

    dontCheckSubjectStringMatchOptionCheckBox = new QCheckBox(tr("Don't check subject string"));
    anchoredMatchOptionCheckBox = new QCheckBox(tr("Anchored match"));

    QGridLayout *matchOptionsCheckBoxLayout = new QGridLayout;
    matchOptionsCheckBoxLayout->addWidget(dontCheckSubjectStringMatchOptionCheckBox, 0, 0);
    matchOptionsCheckBoxLayout->addWidget(anchoredMatchOptionCheckBox, 0, 1);
    layout->addRow(tr("Match options:"), matchOptionsCheckBoxLayout);

    return container;
}

QWidget *RegularExpressionDialog::setupRightUi()
{
    QWidget *container = new QWidget;

    QFormLayout *layout = new QFormLayout(container);
    layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
    layout->setContentsMargins(QMargins());

    QLabel *matchInfoLabel = new QLabel(tr("<h3>Match information</h3>"));
    layout->addRow(matchInfoLabel);

    matchDetailsTreeWidget = new QTreeWidget;
    matchDetailsTreeWidget->setHeaderLabels(QStringList() << tr("Match index") << tr("Group index") << tr("Captured string"));
    matchDetailsTreeWidget->setSizeAdjustPolicy(QTreeWidget::AdjustToContents);
    layout->addRow(tr("Match details:"), matchDetailsTreeWidget);

    QFrame *horizontalSeparator = new QFrame;
    horizontalSeparator->setFrameStyle(QFrame::HLine | QFrame::Sunken);
    layout->addRow(horizontalSeparator);

    QLabel *regexpInfoLabel = new QLabel(tr("<h3>Regular expression information</h3>"));
    layout->addRow(regexpInfoLabel);

    regexpStatusLabel = new QLabel(tr("Valid"));
    regexpStatusLabel->setWordWrap(true);
    layout->addRow(tr("Pattern status:"), regexpStatusLabel);

    namedGroupsTreeWidget = new QTreeWidget;
    namedGroupsTreeWidget->setHeaderLabels(QStringList() << tr("Index") << tr("Named group"));
    namedGroupsTreeWidget->setSizeAdjustPolicy(QTreeWidget::AdjustToContents);
    namedGroupsTreeWidget->setRootIsDecorated(false);
    layout->addRow(tr("Named groups:"), namedGroupsTreeWidget);

    return container;
}

#include "regularexpressiondialog.moc"
