#include "SpellFilterViewer.h"
#include <QVBoxLayout>
#include <QLabel>
#include <QSet>
#include <QPushButton>

SpellFilterViewer::SpellFilterViewer(QWidget *parent)
    : QWidget(parent)
{
    setupUi();
}

SpellFilter* SpellFilterViewer::toFilter()
{
    SpellFilter *ret = new SpellFilter();

    ret->setNameFilter(_name->text());
    ret->setSchoolFilter(_school->currentText());
    ret->setLevelFilter(_level->currentText());
    ret->setClassFilter(_class->currentText());
    ret->setRitualFilter(_ritual->checkState());
    ret->setConcentrationFilter(_concentration->checkState());
    ret->setVocalFilter(_vocal->checkState());
    ret->setSomaticFilter(_somatic->checkState());
    ret->setMaterialFilter(_material->checkState());
    ret->setMaterialExpensiveFilter(_expensiveMaterial->checkState());
    ret->setMaterialConsumedFilter(_consumedMaterial->checkState());

    return ret;
}

void SpellFilterViewer::populate(Spells &spells)
{
    QSet<QString> schools;
    QSet<QString> levels;
    QSet<QString> classes;

    _school->addItem("Any");
    _level->addItem("Any");
    _class->addItem("Any");

    for(int i = 0; i < spells.size(); ++i)
    {
        Spell spell = spells.at(i);
        schools.insert(spell.school());
        levels.insert(QString::number(spell.level()));
        for(QString classString : spell.classes())
        {
            classes.insert(classString);
        }
    }

    QStringList schoolsList(schools.toList());
    QStringList levelsList(levels.toList());
    QStringList classesList(classes.toList());

    qSort(schoolsList);
    qSort(levelsList);
    qSort(classesList);

    _school->addItems(schoolsList);
    _level->addItems(levelsList);
    _class->addItems(classesList);

    _school->setCurrentIndex(0);
    _level->setCurrentIndex(0);
    _class->setCurrentIndex(0);
}

void SpellFilterViewer::setResults(int results)
{
    _results->setText("Results: " + QString::number(results));
}

void SpellFilterViewer::setupUi()
{
    QVBoxLayout *layout = new QVBoxLayout(this);

    layout->addWidget(new QLabel("Name:", this));
    _name = new QLineEdit(this);
    layout->addWidget(_name);

    layout->addWidget(new QLabel("School:", this));
    _school = new QComboBox(this);
    layout->addWidget(_school);

    layout->addWidget(new QLabel("Level:", this));
    _level = new QComboBox(this);
    layout->addWidget(_level);

    layout->addWidget(new QLabel("Class:", this));
    _class = new QComboBox(this);
    layout->addWidget(_class);

    layout->addSpacing(10);
    layout->addWidget(new QLabel("Tags:", this));
    _ritual = new QCheckBox("Ritual");
    _ritual->setTristate(true);
    _ritual->setCheckState(Qt::PartiallyChecked);
    layout->addWidget(_ritual);

    _concentration = new QCheckBox("Concentration");
    _concentration->setTristate(true);
    _concentration->setCheckState(Qt::PartiallyChecked);
    layout->addWidget(_concentration);

    layout->addSpacing(10);
    layout->addWidget(new QLabel("Components:", this));
    _vocal = new QCheckBox("Vocal");
    _vocal->setTristate(true);
    _vocal->setCheckState(Qt::PartiallyChecked);
    layout->addWidget(_vocal);

    _somatic = new QCheckBox("Somatic");
    _somatic->setTristate(true);
    _somatic->setCheckState(Qt::PartiallyChecked);
    layout->addWidget(_somatic);

    _material = new QCheckBox("Material");
    _material->setTristate(true);
    _material->setCheckState(Qt::PartiallyChecked);
    layout->addWidget(_material);

    _expensiveMaterial = new QCheckBox("\t\t\t\tExpensive");
    _expensiveMaterial->setTristate(true);
    _expensiveMaterial->setEnabled(false);
    _expensiveMaterial->setCheckState(Qt::PartiallyChecked);
    layout->addWidget(_expensiveMaterial);

    _consumedMaterial = new QCheckBox("\t\t\t\tConsumed");
    _consumedMaterial->setTristate(true);
    _consumedMaterial->setEnabled(false);
    _consumedMaterial->setCheckState(Qt::PartiallyChecked);
    layout->addWidget(_consumedMaterial);

    layout->addStretch();

    _results = new QLabel("Results: 0");
    layout->addWidget(_results);

    QPushButton *clearButton = new QPushButton(this);
    clearButton->setText("Clear Filter");
    layout->addWidget(clearButton);
    this->setLayout(layout);

    connect(_name, &QLineEdit::textChanged, this, &SpellFilterViewer::filterChanged);
    connect(_school, SIGNAL(currentIndexChanged(int)), this, SIGNAL(filterChanged()));
    connect(_level, SIGNAL(currentIndexChanged(int)), this, SIGNAL(filterChanged()));
    connect(_class, SIGNAL(currentIndexChanged(int)), this, SIGNAL(filterChanged()));
    connect(_ritual, &QCheckBox::stateChanged, this, &SpellFilterViewer::filterChanged);
    connect(_concentration, &QCheckBox::stateChanged, this, &SpellFilterViewer::filterChanged);
    connect(_vocal, &QCheckBox::stateChanged, this, &SpellFilterViewer::filterChanged);
    connect(_somatic, &QCheckBox::stateChanged, this, &SpellFilterViewer::filterChanged);
    connect(_material, &QCheckBox::stateChanged, this, &SpellFilterViewer::filterChanged);
    connect(_material, &QCheckBox::stateChanged, this, &SpellFilterViewer::materialsClicked);
    connect(_expensiveMaterial, &QCheckBox::stateChanged, this, &SpellFilterViewer::filterChanged);
    connect(_expensiveMaterial, &QCheckBox::stateChanged, this, &SpellFilterViewer::materialsExpensiveClicked);
    connect(_consumedMaterial, &QCheckBox::stateChanged, this, &SpellFilterViewer::filterChanged);
    connect(clearButton, &QPushButton::clicked, this, &SpellFilterViewer::clearClicked);
}

void SpellFilterViewer::materialsClicked()
{
    // If materials if indeterminate, consumed and expensive must be as well.
    if(_material->checkState() == Qt::PartiallyChecked || _material->checkState() == Qt::Unchecked)
    {
        _consumedMaterial->setEnabled(false);
        _consumedMaterial->setCheckState(Qt::PartiallyChecked);
        _expensiveMaterial->setEnabled(false);
        _expensiveMaterial->setCheckState(Qt::PartiallyChecked);
    }
    else
    {
        _consumedMaterial->setEnabled(true);
        _expensiveMaterial->setEnabled(true);
    }
}

void SpellFilterViewer::materialsExpensiveClicked()
{
    if(_expensiveMaterial->checkState() == Qt::PartiallyChecked || _expensiveMaterial->checkState() == Qt::Unchecked)
    {
        _consumedMaterial->setEnabled(false);
        _consumedMaterial->setCheckState(Qt::PartiallyChecked);
    }
    else
    {
        _consumedMaterial->setEnabled(true);
    }
}

void SpellFilterViewer::clearClicked()
{
    _name->setText("");
    _school->setCurrentIndex(0);
    _level->setCurrentIndex(0);
    _class->setCurrentIndex(0);
    _ritual->setCheckState(Qt::PartiallyChecked);
    _concentration->setCheckState(Qt::PartiallyChecked);
    _vocal->setCheckState(Qt::PartiallyChecked);
    _somatic->setCheckState(Qt::PartiallyChecked);
    _material->setCheckState(Qt::PartiallyChecked);
    _consumedMaterial->setEnabled(false);
    _consumedMaterial->setCheckState(Qt::PartiallyChecked);
    _expensiveMaterial->setEnabled(false);
    _expensiveMaterial->setCheckState(Qt::PartiallyChecked);
    emit filterChanged();
}
