/*
 *   This file is part of Dianara
 *   Copyright 2012-2016  JanKusanagi JRR <jancoding@gmx.com>
 *
 *   This program 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
 *   (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.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .
 */

#include "configdialog.h"

ConfigDialog::ConfigDialog(GlobalObject *globalObject,
                           QString dataDirectory, int updateInterval,
                           int tabsPosition, bool tabsMovable,
                           FDNotifications *notifier,
                           QWidget *parent) : QWidget(parent)
{
    this->globalObj = globalObject;
    this->fdNotifier = notifier;

    this->setWindowTitle(tr("Program Configuration") + " - Dianara");
    this->setWindowIcon(QIcon::fromTheme("configure",
                                         QIcon(":/images/button-configure.png")));
    this->setWindowFlags(Qt::Dialog);
    this->setWindowModality(Qt::ApplicationModal);
    this->setMinimumSize(640, 520);

    QSettings settings;
    QSize savedWindowsize = settings.value("ConfigDialog/configWindowSize").toSize();
    if (savedWindowsize.isValid())
    {
        this->resize(savedWindowsize);
    }


    settings.beginGroup("Configuration");

    // Standalone Proxy config window
    QByteArray proxyPasswd = QByteArray::fromBase64(settings.value("proxyPassword")
                                                            .toByteArray());
    proxyDialog = new ProxyDialog(settings.value("proxyType", 0).toInt(),
                                  settings.value("proxyHostname").toString(),
                                  settings.value("proxyPort").toString(),
                                  settings.value("proxyUseAuth", false).toBool(),
                                  settings.value("proxyUser").toString(),
                                  QString::fromLocal8Bit(proxyPasswd),
                                  this);


    //////////////////////////////////////////////////////////////// Upper part

    // Page 1, general options
    this->createGeneralPage(updateInterval, tabsPosition, tabsMovable);

    // Page 2, fonts
    this->createFontsPage();

    // Page 3, colors
    this->createColorsPage();

    // Page 4, timelines options
    this->createTimelinesPage();

    // Page 5, posts options
    this->createPostsPage();

    // Page 6, composer options
    this->createComposerPage();

    // Page 7, privacy options
    this->createPrivacyPage();

    // Page 8, notifications options
    this->createNotificationsPage(&settings);

    // Page 9, systray options
    this->createSystrayPage(&settings);


    settings.endGroup();


    ///////////////////////////////////// List of categories and stacked widget
    categoriesListWidget = new QListWidget(this);
    categoriesListWidget->setSizePolicy(QSizePolicy::Preferred,
                                        QSizePolicy::MinimumExpanding);
    categoriesListWidget->setMinimumWidth(140); // kinda TMP/FIXME
#if 0 // enable for large-icon-mode with text below
    categoriesListWidget->setViewMode(QListView::IconMode);
    categoriesListWidget->setFlow(QListView::TopToBottom);
    categoriesListWidget->setIconSize(QSize(48, 48));
    categoriesListWidget->setWrapping(false);
    categoriesListWidget->setMovement(QListView::Static);
#endif
    categoriesListWidget->setIconSize(QSize(32, 32));
    categoriesListWidget->setUniformItemSizes(true);
    categoriesListWidget->setWordWrap(true);
    categoriesListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    categoriesListWidget->addItem(tr("General Options"));
    categoriesListWidget->item(0)->setIcon(QIcon::fromTheme("preferences-other",
                                                            QIcon(":/images/button-configure.png")));
    categoriesListWidget->addItem(tr("Fonts"));
    categoriesListWidget->item(1)->setIcon(QIcon::fromTheme("preferences-desktop-font",
                                                            QIcon(":/images/button-configure.png")));
    categoriesListWidget->addItem(tr("Colors"));
    categoriesListWidget->item(2)->setIcon(QIcon::fromTheme("preferences-desktop-color",
                                                            QIcon(":/images/button-configure.png")));
    categoriesListWidget->addItem(tr("Timelines"));
    categoriesListWidget->item(3)->setIcon(QIcon::fromTheme("view-list-details",
                                                            QIcon(":/images/feed-inbox.png")));
    categoriesListWidget->addItem(tr("Posts"));
    categoriesListWidget->item(4)->setIcon(QIcon::fromTheme("mail-message",
                                                            QIcon(":/images/button-post.png")));
    categoriesListWidget->addItem(tr("Composer"));
    categoriesListWidget->item(5)->setIcon(QIcon::fromTheme("document-edit",
                                                            QIcon(":/images/button-edit.png")));
    categoriesListWidget->addItem(tr("Privacy"));
    categoriesListWidget->item(6)->setIcon(QIcon::fromTheme("object-locked",
                                                            QIcon(":/images/button-password.png")));
    categoriesListWidget->addItem(tr("Notifications"));
    categoriesListWidget->item(7)->setIcon(QIcon::fromTheme("preferences-desktop-notification",
                                                            QIcon(":/images/button-online.png")));
    categoriesListWidget->addItem(tr("System Tray"));     // dashboard-show ?
    categoriesListWidget->item(8)->setIcon(QIcon::fromTheme("configure-toolbars",
                                                            QIcon(":/images/button-configure.png")));

    categoriesStackedWidget = new QStackedWidget(this);
    categoriesStackedWidget->setSizePolicy(QSizePolicy::Preferred,
                                           QSizePolicy::MinimumExpanding);
    categoriesStackedWidget->addWidget(generalOptionsWidget);
    categoriesStackedWidget->addWidget(fontOptionsWidget);
    categoriesStackedWidget->addWidget(colorOptionsWidget);
    categoriesStackedWidget->addWidget(timelinesOptionsWidget);
    categoriesStackedWidget->addWidget(postsOptionsWidget);
    categoriesStackedWidget->addWidget(composerOptionsWidget);
    categoriesStackedWidget->addWidget(privacyOptionsWidget);
    categoriesStackedWidget->addWidget(notificationOptionsWidget);
    categoriesStackedWidget->addWidget(systrayOptionsWidget);

    connect(categoriesListWidget, SIGNAL(currentRowChanged(int)),
            categoriesStackedWidget, SLOT(setCurrentIndex(int)));

    topLayout = new QHBoxLayout();
    topLayout->addWidget(categoriesListWidget);
    topLayout->addWidget(categoriesStackedWidget);



    /////////////////////////////////////////////////////////////// Bottom part

    // Label to show where the data directory is
    dataDirectoryLabel = new QLabel(tr("Dianara stores data in this folder:")
                                    + QString(" <a href=\"%1\">%2</a>")
                                      .arg(dataDirectory).arg(dataDirectory),
                                    this);
    dataDirectoryLabel->setWordWrap(true);
    dataDirectoryLabel->setOpenExternalLinks(true);


    // Save / Cancel buttons
    saveConfigButton = new QPushButton(QIcon::fromTheme("document-save",
                                                        QIcon(":/images/button-save.png")),
                                       tr("&Save Configuration"),
                                       this);
    connect(saveConfigButton, SIGNAL(clicked()),
            this, SLOT(saveConfiguration()));
    cancelButton = new QPushButton(QIcon::fromTheme("dialog-cancel",
                                                    QIcon(":/images/button-cancel.png")),
                                   tr("&Cancel"),
                                   this);
    connect(cancelButton, SIGNAL(clicked()),
            this, SLOT(hide()));

    this->buttonsLayout = new QHBoxLayout();
    buttonsLayout->setAlignment(Qt::AlignRight);
    buttonsLayout->addWidget(saveConfigButton);
    buttonsLayout->addWidget(cancelButton);


    // ESC to close
    closeAction = new QAction(this);
    closeAction->setShortcut(QKeySequence(Qt::Key_Escape));
    connect(closeAction, SIGNAL(triggered()),
            this, SLOT(hide()));
    this->addAction(closeAction);



    //// Set up main layout
    mainLayout = new QVBoxLayout();
    mainLayout->addLayout(topLayout, 20);
    mainLayout->addSpacing(8);
    mainLayout->addStretch(1);
    mainLayout->addWidget(dataDirectoryLabel);
    mainLayout->addSpacing(8);
    mainLayout->addStretch(2);
    mainLayout->addLayout(buttonsLayout);
    this->setLayout(mainLayout);

    // Activate the first category (so the row already looks selected)
    this->categoriesListWidget->setCurrentRow(0);
    this->categoriesListWidget->setFocus();

    qDebug() << "Config dialog created";
}

ConfigDialog::~ConfigDialog()
{
    qDebug() << "Config dialog destroyed";
}


/*
 * Page 1, general options
 *
 */
void ConfigDialog::createGeneralPage(int updateInterval,
                                     int tabsPosition, bool tabsMovable)
{
    updateIntervalSpinbox = new QSpinBox(this);
    updateIntervalSpinbox->setRange(2, 99); // 2-99 min
    updateIntervalSpinbox->setSuffix(" "+ tr("minutes"));
    updateIntervalSpinbox->setValue(updateInterval);


    tabsPositionCombobox = new QComboBox(this);
    tabsPositionCombobox->addItem(QIcon::fromTheme("arrow-up"),
                                  tr("Top"));
    tabsPositionCombobox->addItem(QIcon::fromTheme("arrow-down"),
                                  tr("Bottom"));
    tabsPositionCombobox->addItem(QIcon::fromTheme("arrow-left"),
                                  tr("Left side",
                                     "tabs on left side/west; RTL not affected"));
    tabsPositionCombobox->addItem(QIcon::fromTheme("arrow-right"),
                                  tr("Right side",
                                     "tabs on right side/east; RTL not affected"));
    tabsPositionCombobox->setCurrentIndex(tabsPosition);

    tabsMovableCheckbox = new QCheckBox(this);
    tabsMovableCheckbox->setChecked(tabsMovable);


    proxyConfigButton = new QPushButton(QIcon::fromTheme("preferences-system-network",
                                                         QIcon(":/images/button-configure.png")),
                                        tr("Pro&xy Settings"),
                                        this);
    connect(proxyConfigButton, SIGNAL(clicked()),
            proxyDialog, SLOT(show()));

    filterEditorButton = new QPushButton(QIcon::fromTheme("view-filter",
                                                          QIcon(":/images/button-filter.png")),
                                         tr("Set Up F&ilters"),
                                         this);
    connect(filterEditorButton, SIGNAL(clicked()),
            this, SIGNAL(filterEditorRequested()));


    QFrame *lineFrame1 = new QFrame(this); // ----------------------------
    lineFrame1->setFrameStyle(QFrame::HLine);

    QFrame *lineFrame2 = new QFrame(this); // ----------------------------
    lineFrame2->setFrameStyle(QFrame::HLine);


    generalOptionsLayout = new QFormLayout();
    generalOptionsLayout->addRow(tr("Timeline &update interval"),
                                 updateIntervalSpinbox);
    generalOptionsLayout->addRow(lineFrame1);
    generalOptionsLayout->addRow(tr("&Tabs position"),
                                 tabsPositionCombobox);
    generalOptionsLayout->addRow(tr("&Movable tabs"),
                                 tabsMovableCheckbox);
    generalOptionsLayout->addRow(lineFrame2);
    generalOptionsLayout->addRow(tr("Network configuration"),
                                 proxyConfigButton);
    generalOptionsLayout->addRow(tr("Filtering rules"),
                                 filterEditorButton);

    generalOptionsWidget = new QWidget(this);
    generalOptionsWidget->setLayout(generalOptionsLayout);
}


/*
 * Page 2, fonts
 *
 */void ConfigDialog::createFontsPage()
{
    fontPicker1 = new FontPicker(tr("Post Titles"),
                                 globalObj->getPostTitleFont(),
                                 this);
    fontPicker2 = new FontPicker(tr("Post Contents"),
                                 globalObj->getPostContentsFont(),
                                 this);
    fontPicker3 = new FontPicker(tr("Comments"),
                                 globalObj->getCommentsFont(),
                                 this);
    fontPicker4 = new FontPicker(tr("Minor Feeds"),
                                 globalObj->getMinorFeedFont(),
                                 this);
    // FIXME: more for "Timestamps" or something else?
    // FIXME: add a "base font size" option


    fontOptionsLayout = new QVBoxLayout();
    fontOptionsLayout->addWidget(fontPicker1);
    fontOptionsLayout->addWidget(fontPicker2);
    fontOptionsLayout->addWidget(fontPicker3);
    fontOptionsLayout->addWidget(fontPicker4);
    fontOptionsLayout->addStretch(1);

    fontOptionsWidget = new QWidget(this);
    fontOptionsWidget->setLayout(fontOptionsLayout);
}


/*
 * Page 3, colors
 *
 */
void ConfigDialog::createColorsPage()
{
    QStringList colorList = globalObj->getColorsList();
    colorPicker1 = new ColorPicker(tr("You are among the recipients "
                                      "of the activity, such as "
                                      "a comment addressed to you.")
                                   + "\n"
                                   + tr("Used also when highlighting posts "
                                        "addressed to you in the timelines."),
                                   colorList.at(0),
                                   this);

    colorPicker2 = new ColorPicker(tr("The activity is in reply to something "
                                      "done by you, such as a comment posted "
                                      "in reply to one of your notes."),
                                   colorList.at(1),
                                   this);

    colorPicker3 = new ColorPicker(tr("You are the object of the activity, "
                                      "such as someone adding you to a list."),
                                   colorList.at(2),
                                   this);

    colorPicker4 = new ColorPicker(tr("The activity is related to one of "
                                      "your objects, such as someone "
                                      "liking one of your posts.")
                                   + "\n"
                                   + tr("Used also when highlighting your "
                                        "own posts in the timelines."),
                                   colorList.at(3),
                                   this);

    colorPicker5 = new ColorPicker(tr("Item highlighted due to filtering rules."),
                                   colorList.at(4),
                                   this);

    colorPicker6 = new ColorPicker(tr("Item is new."),
                                   colorList.at(5),
                                   this);


    colorOptionsLayout = new QVBoxLayout();
    colorOptionsLayout->addWidget(colorPicker1);
    colorOptionsLayout->addWidget(colorPicker2);
    colorOptionsLayout->addWidget(colorPicker3);
    colorOptionsLayout->addWidget(colorPicker4);
    colorOptionsLayout->addWidget(colorPicker5);
    colorOptionsLayout->addWidget(colorPicker6);

    colorOptionsWidget = new QWidget(this);
    colorOptionsWidget->setLayout(colorOptionsLayout);
}


/*
 * Page 4, timelines options
 *
 */
void ConfigDialog::createTimelinesPage()
{
    postsPerPageMainSpinbox = new QSpinBox(this);
    postsPerPageMainSpinbox->setRange(5, 50); // 5-50 ppp
    postsPerPageMainSpinbox->setSuffix(" "+ tr("posts",
                                               "Goes after a number, as: "
                                               "25 posts"));
    postsPerPageMainSpinbox->setValue(globalObj->getPostsPerPageMain());

    postsPerPageOtherSpinbox = new QSpinBox(this);
    postsPerPageOtherSpinbox->setRange(1, 30); // 1-30 ppp
    postsPerPageOtherSpinbox->setSuffix(" "+ tr("posts",
                                                "This goes after a number, "
                                                "like: 10 posts"));
    postsPerPageOtherSpinbox->setValue(globalObj->getPostsPerPageOther());

    showDeletedCheckbox = new QCheckBox(this);
    showDeletedCheckbox->setChecked(globalObj->getShowDeleted());

    hideDuplicatesCheckbox = new QCheckBox(this);
    hideDuplicatesCheckbox->setChecked(globalObj->getHideDuplicates());

    jumpToNewCheckbox = new QCheckBox(this);
    jumpToNewCheckbox->setChecked(globalObj->getJumpToNewOnUpdate());


    minorFeedSnippetsCombobox = new QComboBox(this);
    minorFeedSnippetsCombobox->addItem(tr("Highlighted activities, except mine"));
    minorFeedSnippetsCombobox->addItem(tr("Any highlighted activity"));
    minorFeedSnippetsCombobox->addItem(tr("Always"));
    minorFeedSnippetsCombobox->addItem(tr("Never"));
    minorFeedSnippetsCombobox->setCurrentIndex(globalObj->getMinorFeedSnippetsType());

    snippetLimitSpinbox = new QSpinBox(this);
    snippetLimitSpinbox->setRange(10, 10000);
    snippetLimitSpinbox->setSuffix(" " + tr("characters",
                                            "This is a suffix, after a number"));
    snippetLimitSpinbox->setValue(globalObj->getSnippetsCharLimit());

    snippetLimitHlSpinbox = new QSpinBox(this);
    snippetLimitHlSpinbox->setRange(5, 10000);
    snippetLimitHlSpinbox->setSuffix(snippetLimitSpinbox->suffix());
    snippetLimitHlSpinbox->setValue(globalObj->getSnippetsCharLimitHl());

    mfAvatarSizeCombobox = this->newAvatarComboBox();
    mfAvatarSizeCombobox->setCurrentIndex(globalObj->getMfAvatarIndex());


    // TMP/FIXME, use GroupBoxes instead of a separator
    QFrame *lineFrame = new QFrame(this); // -----------------------
    lineFrame->setFrameStyle(QFrame::HLine);

    timelinesOptionsLayout = new QFormLayout();
    timelinesOptionsLayout->addRow(tr("&Posts per page, main timeline"),
                                   postsPerPageMainSpinbox);
    timelinesOptionsLayout->addRow(tr("Posts per page, &other timelines"),
                                   postsPerPageOtherSpinbox);
    timelinesOptionsLayout->addRow(tr("Show information for deleted posts"),
                                   showDeletedCheckbox);
    timelinesOptionsLayout->addRow(tr("Hide duplicated posts"),
                                   hideDuplicatesCheckbox);
    timelinesOptionsLayout->addRow(tr("Jump to new posts line on update"),
                                   jumpToNewCheckbox);
    timelinesOptionsLayout->addRow(lineFrame);
    timelinesOptionsLayout->addRow(tr("Show snippets in minor feeds"),
                                   minorFeedSnippetsCombobox);
    timelinesOptionsLayout->addRow(tr("Snippet limit"),
                                   snippetLimitSpinbox);
    timelinesOptionsLayout->addRow(tr("Snippet limit when highlighted"),
                                   snippetLimitHlSpinbox);
    timelinesOptionsLayout->addRow(tr("Minor feed avatar sizes"),  // tmp string
                                   mfAvatarSizeCombobox);

    timelinesOptionsWidget = new QWidget(this);
    timelinesOptionsWidget->setLayout(timelinesOptionsLayout);
}


/*
 * Page 5, posts options
 *
 */
void ConfigDialog::createPostsPage()
{
    postAvatarSizeCombobox = this->newAvatarComboBox();
    postAvatarSizeCombobox->setCurrentIndex(globalObj->getPostAvatarIndex());

    commentAvatarSizeCombobox = this->newAvatarComboBox();
    commentAvatarSizeCombobox->setCurrentIndex(globalObj->getCommentAvatarIndex());

    showExtendedSharesCheckbox = new QCheckBox(this);
    showExtendedSharesCheckbox->setChecked(globalObj->getPostExtendedShares());

    showExtraInfoCheckbox = new QCheckBox(this);
    showExtraInfoCheckbox->setChecked(globalObj->getPostShowExtraInfo());

    postHLAuthorCommentsCheckbox = new QCheckBox(this);
    postHLAuthorCommentsCheckbox->setChecked(globalObj->getPostHLAuthorComments());

    postHLOwnCommentsCheckbox = new QCheckBox(this);
    postHLOwnCommentsCheckbox->setChecked(globalObj->getPostHLOwnComments());

    postIgnoreSslInImages = new QCheckBox(tr("Only for images inserted from "
                                             "web sites.")
                                          + "\n"
                                          + tr("Use with care."),
                                          this);
    postIgnoreSslInImages->setChecked(globalObj->getPostIgnoreSslInImages());

    postFullImagesCheckbox = new QCheckBox(this);
    postFullImagesCheckbox->setChecked(globalObj->getPostFullImages());


    postsOptionsLayout = new QFormLayout();
    postsOptionsLayout->addRow(tr("Avatar size"),
                               postAvatarSizeCombobox);
    postsOptionsLayout->addRow(tr("Avatar size in comments"),
                               commentAvatarSizeCombobox);
    postsOptionsLayout->addRow(tr("Show extended share information"),
                               showExtendedSharesCheckbox);
    postsOptionsLayout->addRow(tr("Show extra information"),
                               showExtraInfoCheckbox);
    postsOptionsLayout->addRow(tr("Highlight post author's comments"),
                               postHLAuthorCommentsCheckbox);
    postsOptionsLayout->addRow(tr("Highlight your own comments"),
                               postHLOwnCommentsCheckbox);
    postsOptionsLayout->addRow(tr("Ignore SSL errors in images"),
                               postIgnoreSslInImages);
    postsOptionsLayout->addRow(tr("Show full size images"),
                               postFullImagesCheckbox);

    postsOptionsWidget = new QWidget(this);
    postsOptionsWidget->setLayout(postsOptionsLayout);
}


/*
 * Page 6, composer options
 *
 */
void ConfigDialog::createComposerPage()
{
    publicPostsCheckbox = new QCheckBox(this);
    publicPostsCheckbox->setChecked(globalObj->getPublicPostsByDefault());

    useFilenameAsTitleCheckbox = new QCheckBox(this);
    useFilenameAsTitleCheckbox->setChecked(globalObj->getUseFilenameAsTitle());

    showCharacterCounterCheckbox = new QCheckBox(this);
    showCharacterCounterCheckbox->setChecked(globalObj->getShowCharacterCounter());


    composerOptionsLayout = new QFormLayout();
    composerOptionsLayout->addRow(tr("Public posts as &default"),
                                  publicPostsCheckbox);
    composerOptionsLayout->addRow(tr("Use attachment filename as initial "
                                     "post title"),
                                  useFilenameAsTitleCheckbox);
    composerOptionsLayout->addRow(tr("Show character counter"),
                                  showCharacterCounterCheckbox);

    composerOptionsWidget = new QWidget(this);
    composerOptionsWidget->setLayout(composerOptionsLayout);
}


/*
 * Page 7, privacy options
 *
 */
void ConfigDialog::createPrivacyPage()
{
    silentFollowsCheckbox = new QCheckBox(this);
    silentFollowsCheckbox->setChecked(globalObj->getSilentFollows());
    silentListsCheckbox = new QCheckBox(this);
    silentListsCheckbox->setChecked(globalObj->getSilentLists());
    silentLikesCheckbox = new QCheckBox(this);
    silentLikesCheckbox->setChecked(globalObj->getSilentLikes());


    privacyOptionsLayout = new QFormLayout();
    privacyOptionsLayout->addRow(tr("Don't inform followers when "
                                    "following someone"),
                                 silentFollowsCheckbox);
    privacyOptionsLayout->addRow(tr("Don't inform followers when "
                                    "handling lists"),
                                 silentListsCheckbox);
    privacyOptionsLayout->addRow(tr("Inform only the author when "
                                    "liking things"),
                                 silentLikesCheckbox);

    privacyOptionsWidget = new QWidget(this);
    privacyOptionsWidget->setLayout(privacyOptionsLayout);
}


/*
 * Page 8, notifications options
 *
 */
void ConfigDialog::createNotificationsPage(QSettings *settings)
{
    notificationStyleCombobox = new QComboBox(this);
    notificationStyleCombobox->addItem(QIcon::fromTheme("preferences-desktop-notification"),
                                       tr("As system notifications"));
    notificationStyleCombobox->addItem(QIcon::fromTheme("view-conversation-balloon"),
                                       tr("Using own notifications"));
    notificationStyleCombobox->addItem(QIcon::fromTheme("user-busy"), // dialog-cancel
                                       tr("Don't show notifications"));
    notificationStyleCombobox->setCurrentIndex(settings->value("showNotifications",
                                                               0).toInt());
    connect(notificationStyleCombobox, SIGNAL(currentIndexChanged(int)),
            this, SLOT(toggleNotificationDetails(int)));
    // Check FD.org notifications availability when selecting an option
    connect(notificationStyleCombobox, SIGNAL(currentIndexChanged(int)),
            this, SLOT(showDemoNotification(int)));

    notificationsStatusLabel = new QLabel(this);

    notifyNewTLCheckbox = new QCheckBox(this);
    notifyNewTLCheckbox->setChecked(settings->value("notifyNewTL",
                                                    false).toBool());
    notifyHLTLCheckbox = new QCheckBox(this);
    notifyHLTLCheckbox->setChecked(settings->value("notifyHLTL",
                                                   true).toBool());
    notifyNewMWCheckbox = new QCheckBox(this);
    notifyNewMWCheckbox->setChecked(settings->value("notifyNewMW",
                                                    false).toBool());
    notifyHLMWCheckbox = new QCheckBox(this);
    notifyHLMWCheckbox->setChecked(settings->value("notifyHLMW",
                                                   true).toBool());
    notifyErrorsCheckbox = new QCheckBox(this);
    notifyErrorsCheckbox->setChecked(settings->value("notifyErrors",
                                                     true).toBool());

    this->syncNotifierOptions();

    // Initial check to see if currently selected style is available
    this->checkNotifications(notificationStyleCombobox->currentIndex());


    notificationOptionsLayout = new QFormLayout();
    notificationOptionsLayout->addRow(tr("Notification Style"),
                                      notificationStyleCombobox);
    notificationOptionsLayout->addRow("", // Empty label on left to align with right column
                                      notificationsStatusLabel);
    notificationOptionsLayout->addRow(new QLabel("<br>" // TMP/FIXME: put these options inside a GroupBox?
                                                 "<b>"
                                                 + tr("Notify when receiving:")
                                                 + "</b>"
                                                   "<br>",
                                                 this));
    notificationOptionsLayout->addRow(tr("New posts"),
                                      notifyNewTLCheckbox);
    notificationOptionsLayout->addRow(tr("Highlighted posts"),
                                      notifyHLTLCheckbox);
    notificationOptionsLayout->addRow(tr("New activities in minor feed"),
                                      notifyNewMWCheckbox);
    notificationOptionsLayout->addRow(tr("Highlighted activities in minor feed"),
                                      notifyHLMWCheckbox);
    notificationOptionsLayout->addRow(tr("Important errors"),
                                      notifyErrorsCheckbox);

    notificationOptionsWidget = new QWidget(this);
    notificationOptionsWidget->setLayout(notificationOptionsLayout);
}


/*
 * Page 9, systray options
 *
 */
void ConfigDialog::createSystrayPage(QSettings *settings)
{
    systrayIconTypeCombobox = new QComboBox(this);
    systrayIconTypeCombobox->addItem(tr("Default"));
    systrayIconTypeCombobox->addItem(tr("System iconset, if available"));
    systrayIconTypeCombobox->addItem(tr("Show your current avatar"));
    systrayIconTypeCombobox->addItem(tr("Custom icon"));
    systrayIconTypeCombobox->setCurrentIndex(settings->value("systrayIconType",
                                                             0).toInt());
    connect(systrayIconTypeCombobox, SIGNAL(currentIndexChanged(int)),
            this, SLOT(toggleCustomIconButton(int)));


    systrayCustomIconButton = new QPushButton(tr("S&elect..."), this);
    systrayIconLastUsedDir = QDir::homePath();
    systrayCustomIconFN = settings->value("systrayCustomIconFN").toString();
    // FIXME: merge this with code used in pickCustomIconFile()
    // and turn the warning messageBox into a label
    if (!QPixmap(systrayCustomIconFN).isNull())
    {
        systrayCustomIconButton->setIcon(QIcon(systrayCustomIconFN));
        systrayCustomIconButton->setToolTip("<b></b>"
                                            + systrayCustomIconFN);
    }
    else
    {
        systrayCustomIconButton->setIcon(QIcon(":/icon/32x32/dianara.png"));
    }
    connect(systrayCustomIconButton, SIGNAL(clicked()),
            this, SLOT(pickCustomIconFile()));

    // Enable/disable initially based on loaded config
    this->toggleCustomIconButton(systrayIconTypeCombobox->currentIndex());


    systrayHideCheckbox = new QCheckBox(this);
    systrayHideCheckbox->setChecked(this->globalObj->getHideInTray());


    systrayOptionsLayout = new QFormLayout();
    systrayOptionsLayout->addRow(tr("System Tray Icon &Type"),
                                 systrayIconTypeCombobox);
    systrayOptionsLayout->addRow(tr("Custom &Icon"),
                                 systrayCustomIconButton);
    systrayOptionsLayout->addRow(tr("Hide window on startup"),
                                 systrayHideCheckbox);

    systrayOptionsWidget = new QWidget(this);
    systrayOptionsWidget->setLayout(systrayOptionsLayout);
}


QComboBox *ConfigDialog::newAvatarComboBox()
{
    QComboBox *avatarCombobox = new QComboBox(this);
    avatarCombobox->addItem("16x16");
    avatarCombobox->addItem("32x32");
    avatarCombobox->addItem("48x48");
    avatarCombobox->addItem("64x64");
    avatarCombobox->addItem("96x96");
    avatarCombobox->addItem("128x128");
    avatarCombobox->addItem("256x256");

    return avatarCombobox;
}



void ConfigDialog::syncNotifierOptions()
{
    this->toggleNotificationDetails(notificationStyleCombobox->currentIndex());

    this->fdNotifier->setNotificationOptions(notificationStyleCombobox->currentIndex(),
                                             notifyNewTLCheckbox->isChecked(),
                                             notifyHLTLCheckbox->isChecked(),
                                             notifyNewMWCheckbox->isChecked(),
                                             notifyHLMWCheckbox->isChecked(),
                                             notifyErrorsCheckbox->isChecked());
}


/*
 * Get a demo message for the current notification style
 *
 * Show also a warning is system notifications are not available
 *
 */
QString ConfigDialog::checkNotifications(int notificationStyle)
{
    QString demoText;
    if (notificationStyle == FDNotifications::SystemNotifications)
    {
        if (fdNotifier->areNotificationsAvailable())
        {
            demoText = tr("This is a system notification");
        }
        else
        {
            demoText = tr("System notifications are not available!")
                       + "<br>"
                       + tr("Own notifications will be used.");
            notificationsStatusLabel->setText("<i>"
                                              + demoText
                                              + "</i>");
            /* FIXME: Should also check availability of system tray icon,
             *        needed to show Qt's balloon notifications
             */
        }
    }
    else
    {
        demoText = tr("This is a basic notification");
    }

    return demoText;
}


void ConfigDialog::setPublicPosts(bool value)
{
    this->publicPostsCheckbox->setChecked(value);
    this->saveConfiguration(); // This might be overkill -- FIXME TMP
}



//////////////////////////////////////////////////////////////////////////////
///////////////////////////////// SLOTS //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////



void ConfigDialog::saveConfiguration()
{
    QSettings settings;
    if (!settings.isWritable())
    {
        // TMP FIXME: notify user properly

        qDebug() << "ERROR SAVING CONFIGURATION (maybe disk full?)";
        return;
    }

    settings.beginGroup("Configuration");

    // General
    settings.setValue("updateInterval", this->updateIntervalSpinbox->value());

    settings.setValue("tabsPosition", this->tabsPositionCombobox->currentIndex());
    settings.setValue("tabsMovable",  this->tabsMovableCheckbox->isChecked());


    // Fonts
    settings.setValue("font1", this->fontPicker1->getFontInfo());
    settings.setValue("font2", this->fontPicker2->getFontInfo());
    settings.setValue("font3", this->fontPicker3->getFontInfo());
    settings.setValue("font4", this->fontPicker4->getFontInfo());
    this->globalObj->syncFontSettings(this->fontPicker1->getFontInfo(),
                                      this->fontPicker2->getFontInfo(),
                                      this->fontPicker3->getFontInfo(),
                                      this->fontPicker4->getFontInfo());

    // Colors
    settings.setValue("color1", this->colorPicker1->getCurrentColor());
    settings.setValue("color2", this->colorPicker2->getCurrentColor());
    settings.setValue("color3", this->colorPicker3->getCurrentColor());
    settings.setValue("color4", this->colorPicker4->getCurrentColor());
    settings.setValue("color5", this->colorPicker5->getCurrentColor());
    settings.setValue("color6", this->colorPicker6->getCurrentColor());

    QStringList highlightColorsList;
    highlightColorsList << this->colorPicker1->getCurrentColor()
                        << this->colorPicker2->getCurrentColor()
                        << this->colorPicker3->getCurrentColor()
                        << this->colorPicker4->getCurrentColor()
                        << this->colorPicker5->getCurrentColor()
                        << this->colorPicker6->getCurrentColor();
    this->globalObj->syncColorSettings(highlightColorsList);


    // Timelines
    settings.setValue("postsPerPageMain",
                      this->postsPerPageMainSpinbox->value());
    settings.setValue("postsPerPageOther",
                      this->postsPerPageOtherSpinbox->value());
    settings.setValue("showDeletedPosts",
                      this->showDeletedCheckbox->isChecked());
    settings.setValue("hideDuplicatedPosts",
                      this->hideDuplicatesCheckbox->isChecked());
    settings.setValue("jumpToNewOnUpdate",
                      this->jumpToNewCheckbox->isChecked());
    settings.setValue("mfSnippetsType",
                      this->minorFeedSnippetsCombobox->currentIndex());
    settings.setValue("snippetCharLimit",
                      this->snippetLimitSpinbox->value());
    settings.setValue("snippetCharLimitHl",
                      this->snippetLimitHlSpinbox->value());
    settings.setValue("minorFeedAvatarIndex",
                      this->mfAvatarSizeCombobox->currentIndex());

    this->globalObj->syncTimelinesSettings(this->postsPerPageMainSpinbox->value(),
                                           this->postsPerPageOtherSpinbox->value(),
                                           this->showDeletedCheckbox->isChecked(),
                                           this->hideDuplicatesCheckbox->isChecked(),
                                           this->jumpToNewCheckbox->isChecked(),
                                           this->minorFeedSnippetsCombobox->currentIndex(),
                                           this->snippetLimitSpinbox->value(),
                                           this->snippetLimitHlSpinbox->value(),
                                           this->mfAvatarSizeCombobox->currentIndex());

    // Posts
    settings.setValue("postAvatarIndex",
                      this->postAvatarSizeCombobox->currentIndex());
    settings.setValue("commentAvatarIndex",
                      this->commentAvatarSizeCombobox->currentIndex());
    settings.setValue("postExtendedShares",
                      this->showExtendedSharesCheckbox->isChecked());
    settings.setValue("postShowExtraInfo",
                      this->showExtraInfoCheckbox->isChecked());
    settings.setValue("postHLAuthorComments",
                      this->postHLAuthorCommentsCheckbox->isChecked());
    settings.setValue("postHLOwnComments",
                      this->postHLOwnCommentsCheckbox->isChecked());
    settings.setValue("postIgnoreSslInImages",
                      this->postIgnoreSslInImages->isChecked());
    settings.setValue("postFullImages",
                      this->postFullImagesCheckbox->isChecked());
    this->globalObj->syncPostSettings(this->postAvatarSizeCombobox->currentIndex(),
                                      this->commentAvatarSizeCombobox->currentIndex(),
                                      this->showExtendedSharesCheckbox->isChecked(),
                                      this->showExtraInfoCheckbox->isChecked(),
                                      this->postHLAuthorCommentsCheckbox->isChecked(),
                                      this->postHLOwnCommentsCheckbox->isChecked(),
                                      this->postIgnoreSslInImages->isChecked(),
                                      this->postFullImagesCheckbox->isChecked());


    // Composer
    settings.setValue("publicPosts",
                      this->publicPostsCheckbox->isChecked());
    settings.setValue("useFilenameAsTitle",
                      this->useFilenameAsTitleCheckbox->isChecked());
    settings.setValue("showCharacterCounter",
                      this->showCharacterCounterCheckbox->isChecked());
    this->globalObj->syncComposerSettings(this->publicPostsCheckbox->isChecked(),
                                          this->useFilenameAsTitleCheckbox->isChecked(),
                                          this->showCharacterCounterCheckbox->isChecked());


    // Privacy
    settings.setValue("silentFollows",
                      this->silentFollowsCheckbox->isChecked());
    settings.setValue("silentLists",
                      this->silentListsCheckbox->isChecked());
    settings.setValue("silentLikes",
                      this->silentLikesCheckbox->isChecked());
    this->globalObj->syncPrivacySettings(this->silentFollowsCheckbox->isChecked(),
                                         this->silentListsCheckbox->isChecked(),
                                         this->silentLikesCheckbox->isChecked());


    // Notifications
    settings.setValue("showNotifications",
                      this->notificationStyleCombobox->currentIndex());
    settings.setValue("notifyNewTL",  this->notifyNewTLCheckbox->isChecked());
    settings.setValue("notifyHLTL",   this->notifyHLTLCheckbox->isChecked());
    settings.setValue("notifyNewMW",  this->notifyNewMWCheckbox->isChecked());
    settings.setValue("notifyHLMW",   this->notifyHLMWCheckbox->isChecked());
    settings.setValue("notifyErrors", this->notifyErrorsCheckbox->isChecked());
    this->syncNotifierOptions();
    this->globalObj->syncNotificationSettings(); // FIXME, still empty


    // Tray
    settings.setValue("systrayIconType", this->systrayIconTypeCombobox->currentIndex());
    settings.setValue("systrayCustomIconFN", this->systrayCustomIconFN);
    settings.setValue("systrayHideInTray", this->systrayHideCheckbox->isChecked());
    this->globalObj->syncTrayOptions(this->systrayHideCheckbox->isChecked()); // FIXME, some still empty


    settings.endGroup();


    settings.sync();
    emit configurationChanged(); // Ask MainWindow to reload some stuff

    this->hide();   // this->close() would end the program if mainWindow was hidden

    qDebug() << "ConfigDialog: config saved";
}



void ConfigDialog::pickCustomIconFile()
{
    systrayCustomIconFN = QFileDialog::getOpenFileName(this,
                                                       tr("Select custom icon"),
                                                       systrayIconLastUsedDir,
                                                       tr("Image files")
                                                       + " (*.png *.jpg *.jpeg *.gif);;"
                                                       + tr("All files") + " (*)");

    if (!systrayCustomIconFN.isEmpty())
    {
        qDebug() << "Selected" << systrayCustomIconFN << "as new custom tray icon";
        QFileInfo fileInfo(systrayCustomIconFN);
        this->systrayIconLastUsedDir = fileInfo.path();

        QPixmap iconPixmap = QPixmap(systrayCustomIconFN);
        if (!iconPixmap.isNull())
        {
            this->systrayCustomIconButton->setIcon(QIcon(systrayCustomIconFN));
            this->systrayCustomIconButton->setToolTip("<b></b>"
                                                      + systrayCustomIconFN);
        }
        else
        {
            QMessageBox::warning(this,
                                 tr("Invalid image"),
                                 tr("The selected image is not valid."));
            qDebug() << "Invalid tray icon file selected";
        }
    }
}


void ConfigDialog::showDemoNotification(int notificationStyle)
{
    notificationsStatusLabel->clear();

    if (notificationStyle == FDNotifications::NoNotifications)
    {
        return;
    }


    this->syncNotifierOptions();

    QString demoNotificationText = this->checkNotifications(notificationStyle);
    this->fdNotifier->showMessage(demoNotificationText);
}


void ConfigDialog::toggleNotificationDetails(int currentOption)
{
    bool state = true;
    if (currentOption == 2) // No notifications; disable details so it's clearer
    {
        state = false;
    }

    this->notifyNewTLCheckbox->setEnabled(state);
    this->notifyHLTLCheckbox->setEnabled(state);
    this->notifyNewMWCheckbox->setEnabled(state);
    this->notifyHLMWCheckbox->setEnabled(state);
    this->notifyErrorsCheckbox->setEnabled(state);
}


void ConfigDialog::toggleCustomIconButton(int currentOption)
{
    bool state = false;
    if (currentOption == 3) // Enable only for last option, "Custom icon"
    {
        state = true;
    }

    this->systrayCustomIconButton->setEnabled(state);
}


//////////////////////////////////////////////////////////////////////////////
/////////////////////////////// PROTECTED ////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////


void ConfigDialog::closeEvent(QCloseEvent *event)
{
    this->hide();
    event->ignore();
}

void ConfigDialog::hideEvent(QHideEvent *event)
{
    QSettings settings;
    settings.setValue("ConfigDialog/configWindowSize", this->size());

    event->accept();
}
