AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<RssManager>& manager, QWidget *parent) :
  QDialog(parent),
  ui(new Ui::AutomatedRssDownloader),
  m_manager(manager), m_editedRule(0)
{
  ui->setupUi(this);
  // Icons
  ui->removeRuleBtn->setIcon(IconProvider::instance()->getIcon("list-remove"));
  ui->addRuleBtn->setIcon(IconProvider::instance()->getIcon("list-add"));

  // Ui Settings
  ui->listRules->setSortingEnabled(true);
  ui->listRules->setSelectionMode(QAbstractItemView::ExtendedSelection);
  ui->treeMatchingArticles->setSortingEnabled(true);
  ui->hsplitter->setCollapsible(0, false);
  ui->hsplitter->setCollapsible(1, false);
  ui->hsplitter->setCollapsible(2, true); // Only the preview list is collapsible
  bool ok; Q_UNUSED(ok);
  ok = connect(ui->checkRegex, SIGNAL(toggled(bool)), SLOT(updateFieldsToolTips(bool)));
  Q_ASSERT(ok);
  ok = connect(ui->listRules, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayRulesListMenu(const QPoint&)));
  Q_ASSERT(ok);
  m_ruleList = manager.toStrongRef()->downloadRules();
  m_editableRuleList = new RssDownloadRuleList; // Read rule list from disk
  initLabelCombobox();
  loadFeedList();
  loadSettings();
  ok = connect(ui->listRules, SIGNAL(itemSelectionChanged()), SLOT(updateRuleDefinitionBox()));
  Q_ASSERT(ok);
  ok = connect(ui->listRules, SIGNAL(itemSelectionChanged()), SLOT(updateFeedList()));
  Q_ASSERT(ok);
  ok = connect(ui->listFeeds, SIGNAL(itemChanged(QListWidgetItem*)), SLOT(handleFeedCheckStateChange(QListWidgetItem*)));
  Q_ASSERT(ok);
  // Update matching articles when necessary
  ok = connect(ui->lineContains, SIGNAL(textEdited(QString)), SLOT(updateMatchingArticles()));
  Q_ASSERT(ok);
  ok = connect(ui->lineContains, SIGNAL(textEdited(QString)), SLOT(updateMustLineValidity()));
  Q_ASSERT(ok);
  ok = connect(ui->lineNotContains, SIGNAL(textEdited(QString)), SLOT(updateMatchingArticles()));
  Q_ASSERT(ok);
  ok = connect(ui->lineNotContains, SIGNAL(textEdited(QString)), SLOT(updateMustNotLineValidity()));
  Q_ASSERT(ok);
  ok = connect(ui->checkRegex, SIGNAL(stateChanged(int)), SLOT(updateMatchingArticles()));
  Q_ASSERT(ok);
  ok = connect(ui->checkRegex, SIGNAL(stateChanged(int)), SLOT(updateMustLineValidity()));
  Q_ASSERT(ok);
  ok = connect(ui->checkRegex, SIGNAL(stateChanged(int)), SLOT(updateMustNotLineValidity()));
  Q_ASSERT(ok);
  ok = connect(this, SIGNAL(finished(int)), SLOT(on_finished(int)));
  Q_ASSERT(ok);
  updateRuleDefinitionBox();
  updateFeedList();
}
void AutomatedRssDownloader::clearRuleDefinitionBox()
{
    m_ui->lineContains->clear();
    m_ui->lineNotContains->clear();
    m_ui->lineEFilter->clear();
    m_ui->checkBoxSaveDiffDir->setChecked(false);
    m_ui->lineSavePath->clear();
    m_ui->comboCategory->clearEditText();
    m_ui->comboCategory->setCurrentIndex(-1);
    m_ui->checkRegex->setChecked(false);
    m_ui->checkSmart->setChecked(false);
    m_ui->spinIgnorePeriod->setValue(0);
    m_ui->comboAddPaused->clearEditText();
    m_ui->comboAddPaused->setCurrentIndex(-1);
    updateFieldsToolTips(m_ui->checkRegex->isChecked());
    updateMustLineValidity();
    updateMustNotLineValidity();
    updateEpisodeFilterValidity();
}
void AutomatedRssDownloader::updateRuleDefinitionBox()
{
    const QList<QListWidgetItem *> selection = m_ui->listRules->selectedItems();
    QListWidgetItem *currentRuleItem = ((selection.count() == 1) ? selection.first() : nullptr);
    if (m_currentRuleItem != currentRuleItem) {
        saveEditedRule(); // Save previous rule first
        m_currentRuleItem = currentRuleItem;
        //m_ui->listRules->setCurrentItem(m_currentRuleItem);
    }

    // Update rule definition box
    if (m_currentRuleItem) {
        m_currentRule = RSS::AutoDownloader::instance()->ruleByName(m_currentRuleItem->text());

        m_ui->lineContains->setText(m_currentRule.mustContain());
        m_ui->lineNotContains->setText(m_currentRule.mustNotContain());
        if (!m_currentRule.episodeFilter().isEmpty())
            m_ui->lineEFilter->setText(m_currentRule.episodeFilter());
        else
            m_ui->lineEFilter->clear();
        m_ui->checkBoxSaveDiffDir->setChecked(!m_currentRule.savePath().isEmpty());
        m_ui->lineSavePath->setText(Utils::Fs::toNativePath(m_currentRule.savePath()));
        m_ui->checkRegex->blockSignals(true);
        m_ui->checkRegex->setChecked(m_currentRule.useRegex());
        m_ui->checkRegex->blockSignals(false);
        m_ui->checkSmart->blockSignals(true);
        m_ui->checkSmart->setChecked(m_currentRule.useSmartFilter());
        m_ui->checkSmart->blockSignals(false);
        m_ui->comboCategory->setCurrentIndex(m_ui->comboCategory->findText(m_currentRule.assignedCategory()));
        if (m_currentRule.assignedCategory().isEmpty())
            m_ui->comboCategory->clearEditText();
        int index = 0;
        if (m_currentRule.addPaused() == TriStateBool::True)
            index = 1;
        else if (m_currentRule.addPaused() == TriStateBool::False)
            index = 2;
        m_ui->comboAddPaused->setCurrentIndex(index);
        m_ui->spinIgnorePeriod->setValue(m_currentRule.ignoreDays());
        QDateTime dateTime = m_currentRule.lastMatch();
        QString lMatch;
        if (dateTime.isValid())
            lMatch = tr("Last Match: %1 days ago").arg(dateTime.daysTo(QDateTime::currentDateTime()));
        else
            lMatch = tr("Last Match: Unknown");
        m_ui->lblLastMatch->setText(lMatch);
        updateMustLineValidity();
        updateMustNotLineValidity();
        updateEpisodeFilterValidity();

        updateFieldsToolTips(m_ui->checkRegex->isChecked());
        m_ui->ruleDefBox->setEnabled(true);
    }
    else {
        m_currentRule = RSS::AutoDownloadRule();
        clearRuleDefinitionBox();
        m_ui->ruleDefBox->setEnabled(false);
    }

    updateFeedList();
    updateMatchingArticles();
}