#include "summmethodselector.h"
#include "ui_summmethodselector.h"

SummMethodSelectorItem::SummMethodSelectorItem()
{
    method = createMethod();
}

SummAlgorithmCore *SummMethodSelectorItem::getMethod() const
{
    return method;
}

QString SummMethodSelectorItem::getName() const
{
    return "";
}

ParamsWidget *SummMethodSelectorItem::createParamsWidet() const
{
    return NULL;
}

SummAlgorithmCore *SummMethodSelectorItem::createMethod() const
{
    return NULL;
}

FixedLengthIntervalLmAlgorithmSummMethodSelectorItem::FixedLengthIntervalLmAlgorithmSummMethodSelectorItem() : SummMethodSelectorItem()
{
    method = new FixedLengthIntervalLmAlgorithmCore();
}

SummAlgorithmCore *FixedLengthIntervalLmAlgorithmSummMethodSelectorItem::getMethod() const
{
    return method;
}

QString FixedLengthIntervalLmAlgorithmSummMethodSelectorItem::getName() const
{
    return "Static LM method";
}

ParamsWidget *FixedLengthIntervalLmAlgorithmSummMethodSelectorItem::createParamsWidet() const
{
    return new ParamsWidgetFixedLengthLm();
}

SummAlgorithmCore *FixedLengthIntervalLmAlgorithmSummMethodSelectorItem::createMethod() const
{
    return new FixedLengthIntervalLmAlgorithmCore();
}

CoverageDrivenLmAlgorithmSummMethodSelectorItem::CoverageDrivenLmAlgorithmSummMethodSelectorItem() : SummMethodSelectorItem()
{
    method = new CoverageDrivenLmAlgorithmCore();
}

SummAlgorithmCore *CoverageDrivenLmAlgorithmSummMethodSelectorItem::getMethod() const
{
    return method;
}

QString CoverageDrivenLmAlgorithmSummMethodSelectorItem::getName() const
{
    return "Coverage-driven LM method";
}

ParamsWidget *CoverageDrivenLmAlgorithmSummMethodSelectorItem::createParamsWidet() const
{
    return new ParamsWidgetCoverageDrivenLm();
}

SummAlgorithmCore *CoverageDrivenLmAlgorithmSummMethodSelectorItem::createMethod() const
{
    return new CoverageDrivenLmAlgorithmCore();
}

SummMethodSelector::SummMethodSelector(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SummMethodSelector)
{
    ui->setupUi(this);
    paramsWidget = NULL;
    nextId = 0;    
}

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

void SummMethodSelector::addMethod(SummMethodSelectorItem *item)
{
    item->getMethod()->setId(nextId++);
    ui->algorithmSelector->addItem(item->getName(), QVariant::fromValue((void *)item));
}

void SummMethodSelector::setParamsWidget(ParamsWidget *paramsWidget)
{
    assert(paramsWidget != NULL);

    if(this->paramsWidget != NULL)
    {
        ui->paramsFrame->layout()->removeWidget(paramsWidget);
        delete this->paramsWidget;
    }
    else
    {
        QVBoxLayout *layout = new QVBoxLayout(ui->paramsFrame);
        layout->setSpacing(0);
        ui->paramsFrame->setLayout(layout);
    }

    this->paramsWidget = paramsWidget;
    paramsWidget->setParent(ui->paramsFrame);
    ui->paramsFrame->layout()->addWidget(paramsWidget);

    connect(paramsWidget, SIGNAL(paramsChanged()), SLOT(on_paramsWidget_paramsChanged()));
}

void SummMethodSelector::on_algorithmSelector_currentIndexChanged(int index)
{
    Q_UNUSED(index);

    SummMethodSelectorItem *item = getCurrentItem();

    ParamsWidget *paramsWidget = item->createParamsWidet();
    paramsWidget->setParams(item->getMethod()->getParams());
    setParamsWidget(paramsWidget);

    if(ui->autoRecomputeCheckbox->isChecked())
    {
        emit recomputeRequested(this);
    }
}

void SummMethodSelector::on_recomputeButton_clicked()
{
    emit recomputeRequested(this);
}

SummAlgorithmCore *SummMethodSelector::getMethod()
{
    SummMethodSelectorItem *item = getCurrentItem();

    SummAlgorithmCore *method = item->getMethod()->clone();
    method->setParams(paramsWidget->getParams());

    return method;
}

void SummMethodSelector::setMethod(SummAlgorithmCore *method)
{
    assert(method != NULL);
    ui->algorithmSelector->setCurrentIndex(method->getId());
    paramsWidget->setParams(method->getParams());
}

void SummMethodSelector::setMethod(unsigned int idx){
    assert(idx < ui->algorithmSelector->count());

    ui->algorithmSelector->setCurrentIndex(idx);
    paramsWidget->setParams(getCurrentItem()->getMethod()->getParams());
}

void SummMethodSelector::setAutoRecompute(bool autoRecompute)
{
    ui->autoRecomputeCheckbox->setChecked(autoRecompute);
}

SummMethodSelectorItem *SummMethodSelector::getCurrentItem()
{
   return (SummMethodSelectorItem *)ui->algorithmSelector->currentData().value<void *>();
}

void SummMethodSelector::on_resetParamsButton_clicked()
{
    SummMethodSelectorItem *item = getCurrentItem();
    paramsWidget->setParams(item->getMethod()->getParams());
}

void SummMethodSelector::on_makeDefaultParamsButton_clicked()
{
   SummMethodSelectorItem *item = getCurrentItem();
   item->getMethod()->setParams(paramsWidget->getParams());
}

void SummMethodSelector::on_autoRecomputeCheckbox_stateChanged(int arg1)
{
    Q_UNUSED(arg1);
    ui->recomputeButton->setEnabled(!ui->autoRecomputeCheckbox->isChecked());

    if(ui->autoRecomputeCheckbox->isChecked())
    {
        emit recomputeRequested(this);
    }
}

void SummMethodSelector::on_paramsWidget_paramsChanged()
{
    if(ui->autoRecomputeCheckbox->isChecked())
    {
        emit recomputeRequested(this);
    }
}
