/*
    Copyright (c) 2008-12 Qtrac Ltd. All rights reserved.
    This program or module is free software: you can redistribute it
    and/or modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation, either version 2 of
    the License, or version 3 of the License, or (at your option) any
    later version. This program is distributed in the hope that it will
    be useful, but WITHOUT ANY WARRANTY; without even the implied
    warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    See the GNU General Public License for more details.
*/

#include "alt_key.hpp"
#include "optionsdlg.hpp"
#include "syntaxhighlighter.hpp"
#include <QChar>
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QLabel>
#include <QLineEdit>
#include <QSet>
#include <QTextEdit>
#include <QVBoxLayout>


OptionsDlg::OptionsDlg(const QString &alphabet,
        bool prompt_to_save_on_exit, bool restore_workspace_at_startup,
        bool load_last_file_at_startup,
        const QStringList &predefined_accelerators,
        QWidget *parent)
    : QDialog(parent)
{
    QLabel *alphabetLabel = new QLabel(tr("Alphabet:"));
    alphabetEdit = new QLineEdit(alphabet);
    alphabetEdit->setToolTip(tr("The characters that can be used as "
                                "accelerators, usually A-Z or 01-9A-Z"));
    alphabetEdit->setMinimumWidth(QFontMetrics(font())
                                  .width(alphabet + "W"));
    alphabetLabel->setBuddy(alphabetEdit);
    QLabel *label = new QLabel(tr("Predefined Accelerators:"));
    predefinedAcceleratorsText = new QTextEdit;
    label->setBuddy(predefinedAcceleratorsText);
    (void) new SyntaxHighlighter(predefinedAcceleratorsText);
    predefinedAcceleratorsText->setAcceptRichText(false);
    predefinedAcceleratorsText->setTabChangesFocus(true);
    foreach (const QString &string, predefined_accelerators)
        predefinedAcceleratorsText->append(string);
    predefinedAcceleratorsText->setToolTip(tr("<p>Add strings with "
                "accelerators (e.g., Cu&amp;t, &amp;Copy, &amp;Paste, "
                "E&amp;xit, &amp;Quit) to improve consistency"));
    promptToSaveCheckBox = new QCheckBox(tr("Prompt to Save Unsaved "
                                            "Changes on Exit"));
    promptToSaveCheckBox->setChecked(prompt_to_save_on_exit);
    restoreWorkspaceCheckBox = new QCheckBox(
            tr("Restore Workspace at Startup"));
    restoreWorkspaceCheckBox->setChecked(restore_workspace_at_startup);
    loadLastFileCheckBox = new QCheckBox(
            tr("Load Last File at Startup"));
    loadLastFileCheckBox->setChecked(load_last_file_at_startup);
    QDialogButtonBox *buttonBox = new QDialogButtonBox(
                            QDialogButtonBox::Ok|QDialogButtonBox::Cancel);

    QGridLayout *grid = new QGridLayout;
    grid->addWidget(alphabetLabel, 0, 0);
    grid->addWidget(alphabetEdit, 0, 1);
    grid->addWidget(label, 1, 0, 1, 2);
    grid->addWidget(predefinedAcceleratorsText, 2, 0, 1, 2);
    QGridLayout *innerGrid = new QGridLayout;
    innerGrid->addWidget(promptToSaveCheckBox, 0, 0);
    innerGrid->addWidget(restoreWorkspaceCheckBox, 1, 0);
    innerGrid->addWidget(loadLastFileCheckBox, 1, 1);
    grid->addLayout(innerGrid, 4, 0, 1, 2);
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addLayout(grid);
    layout->addStretch();
    layout->addWidget(buttonBox);
    setLayout(layout);

    connect(alphabetEdit, SIGNAL(textEdited(const QString&)),
            this, SLOT(fixAlphabet(const QString&)));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
    connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));

    AQP::accelerateWidget(this);
    setWindowTitle(tr("Alt_Key - Options"));
}


void OptionsDlg::accept()
{
    alphabet_ = alphabetEdit->text().simplified();
    predefined_accelerators_ = QStringList();
    for (QTextBlock block
                = predefinedAcceleratorsText->document()->begin();
                block.isValid(); block = block.next()) {
        QString string = block.text().simplified();
        if (!string.isEmpty())
            predefined_accelerators_ << string;
    }
    prompt_to_save_on_exit_ = promptToSaveCheckBox->isChecked();
    restore_workspace_at_startup_ = restoreWorkspaceCheckBox->isChecked();
    load_last_file_at_startup_ = loadLastFileCheckBox->isChecked();
    QDialog::accept();
}


void OptionsDlg::fixAlphabet(const QString &text)
{
    int i = alphabetEdit->cursorPosition();
    QSet<QChar> seen;
    QString temp;
    foreach (const QChar c, text.toUpper()) {
        if (seen.contains(c))
            continue;
        seen += c;
        temp += c;
    }
    alphabetEdit->setText(temp);
    alphabetEdit->setCursorPosition(i);
}

