/**
 * \file pappsomspp/widget/obo/obolistwidget/obolistwidget.cpp
 * \date 17/04/2021
 * \author Olivier Langella
 * \brief handles a list of obo term, select and click
 */


/*******************************************************************************
 * Copyright (c) 2021 Olivier Langella
 *<Olivier.Langella@universite-paris-saclay.fr>.
 *
 * This file is part of the PAPPSOms++ library.
 *
 *     PAPPSOms++ 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 3 of the License, or
 *     (at your option) any later version.
 *
 *     PAPPSOms++ 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 PAPPSOms++.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/

#include "obolistwidget.h"
#include "ui_uiobolistwidget.h"
#include <QDebug>
#include "obolistproxymodel.h"
#include "../../../core/mzrange.h"

using namespace pappso;

OboListWidget::OboListWidget(QWidget *parent) : QWidget(parent), ui(new Ui::OboListWidgetForm)
{
  qDebug();
  ui->setupUi(this);

  mpa_oboListModel = new OboListModel(this);
  mpa_oboListModel->loadPsiMod();

  mpa_oboListProxyModel = new OboListProxyModel(mpa_oboListModel, this);
  mpa_oboListProxyModel->setSourceModel(mpa_oboListModel);
  // mpa_oboListProxyModel->setSortRole(Qt::UserRole);

  ui->oboTermListView->setModel(mpa_oboListProxyModel);

  mpa_oboListProxyModel->sort(Qt::AscendingOrder);

  connect(ui->oboTermListView->selectionModel(),
          &QItemSelectionModel::selectionChanged,
          this,
          &OboListWidget::onSelectionChanged);
}

OboListWidget::~OboListWidget()
{
  delete ui;
  if(mpa_oboListProxyModel != nullptr)
    {
      delete mpa_oboListProxyModel;
    }
  if(mpa_oboListModel != nullptr)
    {
      delete mpa_oboListModel;
    }
}

void
pappso::OboListWidget::onSelectionChanged(const QItemSelection &selected,
                                          const QItemSelection &deselected [[maybe_unused]])
{
  QModelIndexList index_list = mpa_oboListProxyModel->mapSelectionToSource(selected).indexes();

  if(index_list.size() > 0)
    {
      QModelIndex index  = index_list.first();
      OboPsiModTerm term = mpa_oboListModel->data(index, Qt::UserRole).value<OboPsiModTerm>();
      qDebug() << term.getAccession();
      emit oboTermChanged(term);
    }
}

void
pappso::OboListWidget::filterMzPrecision(double target_mz, pappso::PrecisionPtr precision)
{
  qDebug();
  mpa_oboListProxyModel->filterMzPrecision(target_mz, precision);
  if(precision == nullptr)
    {
      ui->massFilterGroupBox->setChecked(false);
      ui->mzSpinBox->setValue(target_mz);
    }
  else
    {
      ui->massFilterGroupBox->setChecked(true);
      ui->precisionWidget->setPrecision(precision);
      ui->mzSpinBox->setValue(target_mz);
    }
}

void
pappso::OboListWidget::onFilterChanged()
{
  qDebug();
  if(ui->massFilterGroupBox->isChecked())
    {
      mpa_oboListProxyModel->filterMzPrecision(ui->mzSpinBox->value(),
                                               ui->precisionWidget->getPrecision());
    }
  else
    {
      mpa_oboListProxyModel->filterMzPrecision(0, nullptr);
    }
}

void
pappso::OboListWidget::onFilterChanged(double value [[maybe_unused]])
{
  qDebug();
  if(ui->massFilterGroupBox->isChecked())
    {
      mpa_oboListProxyModel->filterMzPrecision(ui->mzSpinBox->value(),
                                               ui->precisionWidget->getPrecision());
    }
  else
    {
      mpa_oboListProxyModel->filterMzPrecision(0, nullptr);
    }
}

void
pappso::OboListWidget::onFilterChanged(pappso::PrecisionPtr precision [[maybe_unused]])
{
  onFilterChanged();
}

double
pappso::OboListWidget::getMzTarget() const
{
  return ui->mzSpinBox->value();
}

pappso::PrecisionPtr
pappso::OboListWidget::getPrecisionPtr() const
{
  if(ui->massFilterGroupBox->isChecked())
    {
      return ui->precisionWidget->getPrecision();
    }
  return nullptr;
}
