/*
Copyright (c) 2006-2009, Tom Thielicke IT Solutions
Copyright (c) 2021, André Apitzsch

SPDX-License-Identifier: GPL-2.0-only
*/

#include "settings.h"
#include "ui_settings.h"

#include <QColorDialog>
#include <QFontDialog>
#include <QMessageBox>
#include <QSettings>

#include "def/defines.h"
#include "errormessage.h"
#include "helpbrowser.h"
#include "regexpdialog.h"
#include "sql/connection.h"
#include "sql/startsql.h"

Settings::Settings(QWidget* parent)
    : QDialog(parent)
    , ui(new Ui::Settings)
{
    ui->setupUi(this);

    // Default ticker font if there is no saved ticker font
    tickerFont = QFont(t10::font_standard, t10::font_size_ticker);

    StartSql* startSql = new StartSql();
    startSql->fillLanguage(
        ui->comboBoxKeyboardLayout, "language_layouts", "layout");
    startSql->fillLanguage(
        ui->comboBoxTrainingLessons, "language_lessons", "lesson");

    connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &Settings::save);
    connect(ui->buttonBox, &QDialogButtonBox::helpRequested, this,
        &Settings::showHelp);

#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
    connect(ui->checkMetronome, &QCheckBox::checkStateChanged,
        ui->spinBoxMetronome, &QSpinBox::setEnabled);
#else
    connect(ui->checkMetronome, &QCheckBox::stateChanged, ui->spinBoxMetronome,
        &QSpinBox::setEnabled);
#endif

    readSettings();

    connect(ui->comboBoxKeyboardLayout, &QComboBox::currentIndexChanged, this,
        &Settings::checkLessonToLayout);
    connect(ui->comboBoxKeyboardLayout, &QComboBox::currentIndexChanged, this,
        &Settings::clearLayoutSetting);
    connect(ui->comboBoxTrainingLessons, &QComboBox::currentIndexChanged, this,
        &Settings::checkLessonToLayout);
}

Settings::~Settings() { delete ui; }

void Settings::showHelp()
{
    auto helpBrowser = new HelpBrowser("settings.html", this);
    helpBrowser->show();
}

void Settings::save()
{
    bool requireRestart = writeSettings();

    if (requireRestart) {
        QMessageBox::information(this, t10::app_name,
            tr("Some of your settings require a restart of the software to "
               "take effect.\n"));
    }
    if (createConnection()) {
        this->accept();
    }
}

void Settings::readSettings()
{
#if APP_PORTABLE
    QSettings settings(
        QCoreApplication::applicationDirPath() + "/portable/settings.ini",
        QSettings::IniFormat);
#else
    QSettings settings;
#endif
    settings.beginGroup("settings");
    ui->tabWidget->setCurrentIndex(
        settings.value("current_settings_item", 0).toInt());

    ui->buttonFontColor->setPalette(QPalette(
        QColor(settings.value("ticker_font_color", t10::ticker_color_font)
                   .toString())));
    ui->buttonBackground->setPalette(QPalette(QColor(
        settings.value("ticker_bg_color", t10::ticker_color_bg).toString())));
    ui->buttonCursor->setPalette(QPalette(
        QColor(settings.value("ticker_cursor_color", t10::ticker_color_cursor)
                   .toString())));
    tickerFont.fromString(
        settings.value("ticker_font", tickerFont.toString()).toString());
    ui->tickerSpeed->setValue(
        settings.value("ticker_speed", t10::tickerspeed_standard).toInt());
    settings.endGroup();

    settings.beginGroup("sound");
    ui->checkMetronome->setChecked(
        settings.value("check_metronome", false).toBool());
    ui->spinBoxMetronome->setValue(
        settings.value("spin_metronome", t10::metronom_standard).toInt());
    settings.endGroup();
    setFontButtonLabel();

    settings.beginGroup("main");
    int tempIndex = ui->comboBoxKeyboardLayout->findData(
        settings.value("language_layout", t10::app_std_language_layout)
            .toString());
    if (!tempIndex) {
        tempIndex = 0;
    }
    ui->comboBoxKeyboardLayout->setCurrentIndex(tempIndex);
    tempIndex = ui->comboBoxTrainingLessons->findData(
        settings.value("language_lesson", t10::app_std_language_lesson)
            .toString());
    if (!tempIndex) {
        tempIndex = 0;
    }
    ui->comboBoxTrainingLessons->setCurrentIndex(tempIndex);
    checkLessonToLayout();

    ui->checkWelcome->setChecked(
        settings.value("check_illustration", true).toBool());
    ui->checkIntelligence->setChecked(
        settings.value("check_toggle_intelligence", true).toBool());
    ui->checkLimitLesson->setChecked(
        settings.value("check_limit_lesson", true).toBool());
    settings.endGroup();
}

bool Settings::writeSettings()
{
    bool requireRestart = false;

#if APP_PORTABLE
    QSettings settings(
        QCoreApplication::applicationDirPath() + "/portable/settings.ini",
        QSettings::IniFormat);
#else
    QSettings settings;
#endif
    settings.beginGroup("settings");
    settings.setValue("current_settings_item", ui->tabWidget->currentIndex());

    settings.setValue("ticker_font_color",
        ui->buttonFontColor->palette().window().color().name());
    settings.setValue("ticker_bg_color",
        ui->buttonBackground->palette().window().color().name());
    settings.setValue("ticker_cursor_color",
        ui->buttonCursor->palette().window().color().name());
    settings.setValue("ticker_font", tickerFont.toString());
    settings.setValue("ticker_speed", ui->tickerSpeed->value());
    settings.endGroup();

    settings.beginGroup("sound");
    settings.setValue("check_metronome", ui->checkMetronome->isChecked());
    settings.setValue("spin_metronome", ui->spinBoxMetronome->value());
    settings.endGroup();

    settings.beginGroup("main");
    /*if (comboLessons->itemData(comboLessons->currentIndex()) !=
                settings.value("language_lesson",
    t10::app_std_language_lesson).toString()) {

                requireRestart = true;
    }*/
    settings.setValue("language_layout",
        ui->comboBoxKeyboardLayout->itemData(
            ui->comboBoxKeyboardLayout->currentIndex()));
    settings.setValue("language_lesson",
        ui->comboBoxTrainingLessons->itemData(
            ui->comboBoxTrainingLessons->currentIndex()));

    settings.setValue("check_illustration", ui->checkWelcome->isChecked());
    settings.setValue(
        "check_toggle_intelligence", ui->checkIntelligence->isChecked());
    settings.setValue("check_limit_lesson", ui->checkLimitLesson->isChecked());
    settings.endGroup();

    return requireRestart;
}

/* Training page */
void Settings::on_buttonFont_clicked()
{
    bool ok;
    QFont font = QFontDialog::getFont(&ok, tickerFont, this);
    if (ok) {
        tickerFont = font;
        setFontButtonLabel();
    }
}

void Settings::on_buttonFontColor_clicked()
{
    QColor color = QColorDialog::getColor(
        ui->buttonFontColor->palette().window().color(), this);
    if (color.isValid()) {
        ui->buttonFontColor->setPalette(QPalette(color));
    }
}

void Settings::on_buttonBackground_clicked()
{
    QColor color = QColorDialog::getColor(
        ui->buttonBackground->palette().window().color(), this);
    if (color.isValid()) {
        ui->buttonBackground->setPalette(QPalette(color));
    }
}

void Settings::on_buttonCursor_clicked()
{
    QColor color = QColorDialog::getColor(
        ui->buttonCursor->palette().window().color(), this);
    if (color.isValid()) {
        ui->buttonCursor->setPalette(QPalette(color));
    }
}

void Settings::setFontButtonLabel()
{
    ui->buttonFont->setText(
        (tickerFont.family().length() > 10 ? tickerFont.family().left(8) + "…"
                                           : tickerFont.family())
        + ", " + QString::number(tickerFont.pointSize()));
}

/* Language page */

void Settings::checkLessonToLayout()
{
    QString layout = ui->comboBoxKeyboardLayout
                         ->itemData(ui->comboBoxKeyboardLayout->currentIndex())
                         .toString();
    QString lessons
        = ui->comboBoxTrainingLessons
              ->itemData(ui->comboBoxTrainingLessons->currentIndex())
              .toString();

    if (layout.contains(lessons.mid(3))
        || (lessons.mid(3) == "de_qwertz" && layout.contains("ch_qwertz"))) {
        ui->labelLessonNotice->setVisible(false);
    } else {
        ui->labelLessonNotice->setVisible(true);
    }
}

void Settings::clearLayoutSetting()
{
#if APP_PORTABLE
    QSettings settings(
        QCoreApplication::applicationDirPath() + "/portable/settings.ini",
        QSettings::IniFormat);
#else
    QSettings settings;
#endif
    settings.beginGroup("main");
    settings.setValue("layout_replace", "NULL");
    settings.setValue("layout_regexp", "NULL");
    settings.endGroup();
}

void Settings::on_buttonLayoutAdvanced_clicked()
{
    RegExpDialog regExpDialog(
        ui->comboBoxKeyboardLayout
            ->itemData(ui->comboBoxKeyboardLayout->currentIndex())
            .toString(),
        this);
    regExpDialog.exec();
}

/* Results page */

void Settings::on_buttonResetLessons_clicked()
{
    switch (QMessageBox::question(this, t10::app_name,
        tr("All data for completed lessons for the current user will be "
           "deleted\nand the lesson list will return to its original state "
           "after initial installation!\n\nDo you really want to "
           "continue?\n\n"))) {
    case QMessageBox::Yes: {
        StartSql* userSql = new StartSql();
        if (!userSql->deleteUserLessonList()) {
            // Error message
            ErrorMessage* errorMessage = new ErrorMessage(this);
            errorMessage->showMessage(Error::user_lessons_flush,
                ErrorMessage::Type::Warning, ErrorMessage::Cancel::Operation);
            return;
        }
        QMessageBox::information(this, t10::app_name,
            tr("The data for completed lessons was successfully deleted!\n"));
        break;
    }
    default:
        break;
    }
}

void Settings::on_buttonResetRecordedChars_clicked()
{
    switch (QMessageBox::question(this, t10::app_name,
        tr("All recorded characters (mistake quotas) of the current user will "
           "be deleted and the character list will return to its original "
           "state after initial installation!\n\nDo you really want to "
           "continue?"))) {
    case QMessageBox::Yes: {
        StartSql* userSql = new StartSql();
        if (!userSql->deleteUserChars()) {
            // Error message
            ErrorMessage* errorMessage = new ErrorMessage(this);
            errorMessage->showMessage(Error::user_errors_flush,
                ErrorMessage::Type::Warning, ErrorMessage::Cancel::Operation);
            return;
        }
        QMessageBox::information(this, t10::app_name,
            tr("The recorded characters were successfully deleted!\n"));
        break;
    }
    default:
        break;
    }
}
