/****************************************************************************
**
** 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(optimizeOnFirstUsageOptionCheckBox, &QCheckBox::toggled, this, &RegularExpressionDialog::refresh);
    connect(dontAutomaticallyOptimizeOptionCheckBox, &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 = matchTypeComboBox->currentData().value<QRegularExpression::MatchType>();
    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;
    if (optimizeOnFirstUsageOptionCheckBox->isChecked())
        patternOptions |= QRegularExpression::OptimizeOnFirstUsageOption;
    if (dontAutomaticallyOptimizeOptionCheckBox->isChecked())
        patternOptions |= QRegularExpression::DontAutomaticallyOptimizeOption;

    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)"));
    optimizeOnFirstUsageOptionCheckBox = new QCheckBox(tr("Optimize on first usage"));
    dontAutomaticallyOptimizeOptionCheckBox = new QCheckBox(tr("Don't automatically optimize"));

    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);
    patternOptionsCheckBoxLayout->addWidget(optimizeOnFirstUsageOptionCheckBox, gridRow, 2);
    ++gridRow;
    patternOptionsCheckBoxLayout->addWidget(dontAutomaticallyOptimizeOptionCheckBox, 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"
