// SPDX-License-Identifier: LGPL-2.1-or-later
//
// SPDX-FileCopyrightText: 2014 Calin Cruceru <crucerucalincristian@gmail.com>
// SPDX-FileCopyrightText: 2015 Constantin Mihalache <mihalache.c94@gmail.com>
//

// self
#include "FormattedTextWidget.h"
#include "ui_FormattedTextWidget.h"

// Qt
#include <QColorDialog>
#include <QFileDialog>
#include <QFontComboBox>
#include <QLineEdit>
#include <QPointer>

// Marble
#include "AddLinkDialog.h"
#include "MarbleWidget.h"

namespace Marble
{

class Q_DECL_HIDDEN FormattedTextWidget::Private : public Ui::FormattedTextWidget
{
public:
    Private();
    ~Private();

    QColorDialog *m_textColorDialog;
};

FormattedTextWidget::Private::Private()
    : Ui::FormattedTextWidget()
    , m_textColorDialog(nullptr)
{
    // nothing to do
}

FormattedTextWidget::Private::~Private()
{
    delete m_textColorDialog;
}

FormattedTextWidget::FormattedTextWidget(QWidget *parent)
    : QWidget(parent)
    , d(new Private())
{
    d->setupUi(this);

    d->m_formattedTextToolBar->insertSeparator(d->m_actionAddImage);
    QPixmap textColorPixmap(20, 20);
    textColorPixmap.fill(d->m_description->textCursor().charFormat().foreground().color());
    d->m_actionColor->setIcon(textColorPixmap);
    d->m_textColorDialog = new QColorDialog(this);
    d->m_textColorDialog->setOption(QColorDialog::ShowAlphaChannel);
    d->m_textColorDialog->setCurrentColor(d->m_description->textCursor().charFormat().foreground().color());
    d->m_fontSize->setValidator(new QIntValidator(1, 9000, this));
    int index = d->m_fontSize->findText(QString::number(d->m_description->textCursor().charFormat().font().pointSize()));
    if (index != -1) {
        d->m_fontSize->setCurrentIndex(index);
    } else {
        d->m_fontSize->lineEdit()->setText(QString::number(d->m_description->textCursor().charFormat().font().pointSize()));
    }
    connect(d->m_actionColor, &QAction::triggered, d->m_textColorDialog, &QDialog::exec);
    connect(d->m_textColorDialog, &QColorDialog::colorSelected, this, &FormattedTextWidget::setTextCursorColor);
    connect(d->m_isFormattedTextMode, &QAbstractButton::toggled, this, &FormattedTextWidget::toggleDescriptionEditMode);
    connect(d->m_fontFamily, &QFontComboBox::currentFontChanged, this, &FormattedTextWidget::setTextCursorFont);
    connect(d->m_fontSize, &QComboBox::editTextChanged, this, &FormattedTextWidget::setTextCursorFontSize);
    connect(d->m_actionBold, &QAction::toggled, this, &FormattedTextWidget::setTextCursorBold);
    connect(d->m_actionItalics, &QAction::toggled, this, &FormattedTextWidget::setTextCursorItalic);
    connect(d->m_actionUnderlined, &QAction::toggled, this, &FormattedTextWidget::setTextCursorUnderlined);
    connect(d->m_actionAddImage, &QAction::triggered, this, &FormattedTextWidget::addImageToDescription);
    connect(d->m_actionAddLink, &QAction::triggered, this, &FormattedTextWidget::addLinkToDescription);
    connect(d->m_description, &QTextEdit::cursorPositionChanged, this, &FormattedTextWidget::updateDescriptionEditButtons);
}

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

void FormattedTextWidget::setText(const QString &text)
{
    d->m_description->setHtml(text);
}

const QString FormattedTextWidget::text()
{
    return d->m_description->toHtml();
}

void FormattedTextWidget::toggleDescriptionEditMode(bool isFormattedTextMode)
{
    d->m_formattedTextToolBar->setVisible(isFormattedTextMode);
    d->m_fontSize->setVisible(isFormattedTextMode);
    d->m_fontFamily->setVisible(isFormattedTextMode);
    if (isFormattedTextMode) {
        d->m_description->setHtml(d->m_description->toPlainText());
    } else {
        QTextCursor cursor = d->m_description->textCursor();
        QTextCharFormat format;
        format.setFont(QFont());
        format.setFontWeight(QFont::Normal);
        format.setFontItalic(false);
        format.setFontUnderline(false);
        format.clearForeground();
        cursor.setCharFormat(format);
        d->m_description->setTextCursor(cursor);
        d->m_description->setPlainText(d->m_description->toHtml());
    }
}

void FormattedTextWidget::setTextCursorBold(bool bold)
{
    QTextCursor cursor = d->m_description->textCursor();
    QTextCharFormat format;
    format.setFontWeight(bold ? QFont::Bold : QFont::Normal);
    cursor.mergeCharFormat(format);
    d->m_description->setTextCursor(cursor);
}

void FormattedTextWidget::setTextCursorItalic(bool italic)
{
    QTextCursor cursor = d->m_description->textCursor();
    QTextCharFormat format;
    format.setFontItalic(italic);
    cursor.mergeCharFormat(format);
    d->m_description->setTextCursor(cursor);
}

void FormattedTextWidget::setTextCursorUnderlined(bool underlined)
{
    QTextCursor cursor = d->m_description->textCursor();
    QTextCharFormat format;
    format.setFontUnderline(underlined);
    cursor.mergeCharFormat(format);
    d->m_description->setTextCursor(cursor);
}

void FormattedTextWidget::setTextCursorColor(const QColor &color)
{
    QTextCursor cursor = d->m_description->textCursor();
    QTextCharFormat format;
    QBrush brush(color);
    format.setForeground(brush);
    cursor.mergeCharFormat(format);
    d->m_description->setTextCursor(cursor);
    QPixmap textColorPixmap(22, 22);
    textColorPixmap.fill(format.foreground().color());
    d->m_actionColor->setIcon(QIcon(textColorPixmap));
    d->m_textColorDialog->setCurrentColor(format.foreground().color());
}

void FormattedTextWidget::setTextCursorFont(const QFont &font)
{
    QTextCursor cursor = d->m_description->textCursor();
    QTextCharFormat format;
    format.setFontFamily(font.family());
    cursor.mergeCharFormat(format);
    d->m_description->setTextCursor(cursor);
}

void FormattedTextWidget::setTextCursorFontSize(const QString &fontSize)
{
    bool ok = false;
    int size = fontSize.toInt(&ok);
    if (ok) {
        QTextCursor cursor = d->m_description->textCursor();
        QTextCharFormat format;
        format.setFontPointSize(size);
        cursor.mergeCharFormat(format);
        d->m_description->setTextCursor(cursor);
    }
}

void FormattedTextWidget::addImageToDescription()
{
    QString filename = QFileDialog::getOpenFileName(this, tr("Choose image"), tr("All Supported Files (*.png *.jpg *.jpeg)"));
    QImage image(filename);
    if (!image.isNull()) {
        QTextCursor cursor = d->m_description->textCursor();
        cursor.insertImage(image, filename);
    }
}

void FormattedTextWidget::addLinkToDescription()
{
    QPointer<AddLinkDialog> dialog = new AddLinkDialog(this);
    if (dialog->exec()) {
        QTextCharFormat oldFormat = d->m_description->textCursor().charFormat();
        QTextCharFormat linkFormat = oldFormat;
        linkFormat.setAnchor(true);
        linkFormat.setFontUnderline(true);
        linkFormat.setForeground(QApplication::palette().link());
        linkFormat.setAnchorHref(dialog->url());
        d->m_description->textCursor().insertText(dialog->name(), linkFormat);
        QTextCursor cursor = d->m_description->textCursor();
        cursor.setCharFormat(oldFormat);
        d->m_description->setTextCursor(cursor);
        d->m_description->textCursor().insertText(QStringLiteral(" "));
    }
}

void FormattedTextWidget::updateDescriptionEditButtons()
{
    disconnect(d->m_actionBold, SIGNAL(toggled(bool)), this, SLOT(setTextCursorBold(bool)));
    disconnect(d->m_actionItalics, SIGNAL(toggled(bool)), this, SLOT(setTextCursorItalic(bool)));
    disconnect(d->m_actionUnderlined, SIGNAL(toggled(bool)), this, SLOT(setTextCursorUnderlined(bool)));
    disconnect(d->m_fontFamily, SIGNAL(currentFontChanged(QFont)), this, SLOT(setTextCursorFont(QFont)));
    disconnect(d->m_fontSize, SIGNAL(editTextChanged(QString)), this, SLOT(setTextCursorFontSize(QString)));

    QTextCharFormat format = d->m_description->textCursor().charFormat();

    d->m_fontFamily->setCurrentFont(format.font());

    if (format.fontWeight() == QFont::Bold) {
        d->m_actionBold->setChecked(true);
    } else if (format.fontWeight() == QFont::Normal) {
        d->m_actionBold->setChecked(false);
    }
    d->m_actionItalics->setChecked(format.fontItalic());
    d->m_actionUnderlined->setChecked(format.fontUnderline());

    QPixmap textColorPixmap(22, 22);
    textColorPixmap.fill(format.foreground().color());
    d->m_actionColor->setIcon(QIcon(textColorPixmap));
    d->m_textColorDialog->setCurrentColor(format.foreground().color());

    int index = d->m_fontSize->findText(QString::number(d->m_description->textCursor().charFormat().font().pointSize()));
    if (index != -1) {
        d->m_fontSize->setCurrentIndex(index);
    } else {
        d->m_fontSize->lineEdit()->setText(QString::number(d->m_description->textCursor().charFormat().font().pointSize()));
    }
    connect(d->m_actionBold, SIGNAL(toggled(bool)), this, SLOT(setTextCursorBold(bool)));
    connect(d->m_actionItalics, SIGNAL(toggled(bool)), this, SLOT(setTextCursorItalic(bool)));
    connect(d->m_actionUnderlined, SIGNAL(toggled(bool)), this, SLOT(setTextCursorUnderlined(bool)));
    connect(d->m_fontFamily, SIGNAL(currentFontChanged(QFont)), this, SLOT(setTextCursorFont(QFont)));
    connect(d->m_fontSize, SIGNAL(editTextChanged(QString)), this, SLOT(setTextCursorFontSize(QString)));
}

void FormattedTextWidget::setReadOnly(bool state)
{
    d->m_description->setReadOnly(state);
    d->m_formattedTextToolBar->setDisabled(state);
    d->m_fontFamily->setDisabled(state);
    d->m_fontSize->setDisabled(state);
    d->m_actionColor->setDisabled(state);
}

}

#include "moc_FormattedTextWidget.cpp"
