/**
 * \file src/gui/xic_view/xic_box/xicbox.cpp
 * \date 12/1/2018
 * \author Olivier Langella
 * \brief XIC box widget
 */
/*******************************************************************************
 * Copyright (c) 2018 Olivier Langella <olivier.langella@u-psud.fr>.
 *
 * This file is part of XTPcpp.
 *
 *     XTPcpp 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.
 *
 *     XTPcpp 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 XTPcpp.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Olivier Langella <olivier.langella@u-psud.fr> - initial API and
 *implementation
 ******************************************************************************/

#include "xicbox.h"
#include "ui_xic_box.h"
#include <QMessageBox>
#include <pappsomspp/exception/exceptionnotfound.h>
#include "../xicworkerthread.h"
#include "../../project_view/projectwindow.h"
#include <pappsomspp/processing/detection/tracedetectionzivy.h>
#include <pappsomspp/exception/exceptionnotpossible.h>


bool
XicBoxNaturalIsotope::contains(const pappso::TracePeakCstSPtr &peak) const
{
  for(const pappso::TracePeakCstSPtr &peak_i : detected_peak_list)
    {
      if(peak_i.get() == peak.get())
        {
          return true;
        }
    }
  return false;
}

void
XicBoxNaturalIsotope::computeMeanIntensityIn(
  const std::vector<std::size_t> &rt_list)
{
  meanIntensityInCurrentPeak = 0;

  for(auto indice : rt_list)
    {
      qDebug() << xic_sp.get()->at(indice).y;
      meanIntensityInCurrentPeak += xic_sp.get()->at(indice).y;
    }

  meanIntensityInCurrentPeak /= rt_list.size();
  qDebug() << meanIntensityInCurrentPeak;
}


class XicDetectionList : public pappso::TraceDetectionSinkInterface
{
  public:
  XicDetectionList()
  {
    _max_peak = nullptr;
  }
  void
  setPeptideEvidenceList(
    const std::vector<const PeptideEvidence *> &peptide_evidence_list)
  {
    for(const PeptideEvidence *p_evidence : peptide_evidence_list)
      {
        _rt_list.push_back(p_evidence->getHardenedRetentionTime());
      }
  }
  void
  setTracePeak(pappso::TracePeak &xic_peak) override
  {
    pappso::TracePeakCstSPtr peak_sp = xic_peak.makeTracePeakCstSPtr();
    _peak_list.push_back(peak_sp);

    for(pappso::pappso_double rt : _rt_list)
      {
        if(xic_peak.containsRt(rt))
          {
            if((_max_peak == nullptr) ||
               (xic_peak.getArea() > _max_peak.get()->getArea()))
              {
                _max_peak = peak_sp;
              }
          }
      }
  };
  const pappso::TracePeakCstSPtr &
  getMatchedPeak() const
  {
    return _max_peak;
  }
  const std::vector<pappso::TracePeakCstSPtr> &
  getXicPeakList() const
  {
    return _peak_list;
  };
  void
  clear()
  {
    _peak_list.clear();
    _max_peak = nullptr;
  };

  private:
  unsigned int _count = 0;
  std::vector<pappso::TracePeakCstSPtr> _peak_list;
  std::vector<pappso::pappso_double> _rt_list;
  pappso::TracePeakCstSPtr _max_peak;
};


XicBox::XicBox(XicWindow *parent) : QWidget(parent), ui(new Ui::XicBox)
{
  _p_xic_window = parent;
  ui->setupUi(this);

  XicWorkerThread *p_worker = new XicWorkerThread(this);
  p_worker->moveToThread(&_xic_thread);
  _xic_thread.start();


  // ui->histo_widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom );
  // ui->xic_list_widget->setLayout(new QVBoxLayout(ui->xic_list_widget));
  ui->histo_widget->legend->setVisible(true);

  if(_p_xic_window->isRetentionTimeSeconds())
    {
      ui->xic_widget->setRetentionTimeInSeconds();
    }
  else
    {
      ui->xic_widget->setRetentionTimeInMinutes();
    }

#if QT_VERSION >= 0x050000
  // Qt5 code
  connect(this, &XicBox::loadXic, p_worker, &XicWorkerThread::doXicLoad);
  connect(p_worker, &XicWorkerThread::xicLoaded, this, &XicBox::setXic);
  connect(p_worker, &XicWorkerThread::operationFailed, this, &XicBox::error);


  connect(this,
          &XicBox::computeIsotopeMassList,
          p_worker,
          &XicWorkerThread::doComputeIsotopeMassList);
  connect(p_worker,
          &XicWorkerThread::isotopeMassListComputed,
          this,
          &XicBox::setIsotopeMassList);

  connect(
    _p_xic_window, &XicWindow::reExtractXicNeeded, this, &XicBox::reExtractXic);
  /*  connect(ui->xic_widget,
          qOverload<std::vector<std::pair<pappso::XicCstSPtr,
  pappso::XicPeakSp>>>( &pappso::XicWidget::xicPeakListChanged), this,
          &XicBox::setXicPeakList);

  connect(ui->xic_widget,
          &pappso::XicWidget::clicked,
          this,
          &XicBox::onXicWidgetClick);
*/
  connect(_p_xic_window,
          &XicWindow::rtUnitChangeNeeded,
          this,
          &XicBox::onRtUnitChanged);

  /** @brief Handle axis size to move simultaneously in boxs
   */
  connect(ui->xic_widget->getRtAxisP(),
          qOverload<const QCPRange &>(&QCPAxis::rangeChanged),
          this,
          &XicBox::doGetNewRtRange);
  connect(ui->xic_widget->getIntensityAxisP(),
          qOverload<const QCPRange &>(&QCPAxis::rangeChanged),
          this,
          &XicBox::doGetNewIntensityRange);
  connect(
    this, &XicBox::fitAxisRangeInXics, _p_xic_window, &XicWindow::doFitAllAxis);

#else
// Qt4 code
#endif


  QStringList msrun_list;
  for(MsRunSp msrun_sp : _p_xic_window->getProjectWindow()
                           ->getProjectP()
                           ->getMsRunStore()
                           .getMsRunList())
    {
      msrun_list << msrun_sp.get()->getFileName();
      qDebug() << "ProteinListWindow::setIdentificationGroup "
               << msrun_sp.get()->getFileName();
    }
}

XicBox::~XicBox()
{
  qDebug() << "XicBox::~XicBox";
  _xic_thread.quit();
  _xic_thread.wait();
}

void
XicBox::rescaleXicWidget(QString axis_name, QCPRange new_range)
{
  ui->xic_widget->rescaleOneRange(axis_name, new_range);
}

void
XicBox::doGetNewRtRange(QCPRange new_range)
{
  emit fitAxisRangeInXics("xAxis", new_range);
}

void
XicBox::doGetNewIntensityRange(QCPRange new_range)
{
  emit fitAxisRangeInXics("yAxis", new_range);
}

QCPRange
XicBox::getRtRange()
{
  return ui->xic_widget->getRtAxisP()->range();
}

ZivyParams
XicBox::getZivyParamsUsed()
{
  return _p_xic_window->getZivyParams();
}

void
XicBox::onXicWidgetClick(double rt [[maybe_unused]],
                         double intensity [[maybe_unused]])
{
  qDebug();
  ui->xic_widget->clearXicPeakBorders();
  std::vector<pappso::TracePeakCstSPtr> draw_peak_borders;
  for(XicBoxNaturalIsotope peak : _natural_isotope_list)
    {
      qDebug();
      draw_peak_borders.push_back(peak.one_peak_sp);
      if(peak.one_peak_sp.get() != nullptr)
        {
          ui->xic_widget->drawXicPeakBorders(peak.one_peak_sp);
        }
    }

  if(_peptide_evidence_list.size() == 0)
    {
      drawObservedAreaBars(draw_peak_borders);
    }
}

void
XicBox::remove()
{
  _p_xic_window->removeXicBox(this);
}

void
XicBox::error(QString error_message)
{
  QMessageBox::warning(this, tr("Error extracting XIC :"), error_message);
}

void
XicBox::extractXicInOtherMsRun()
{
  qDebug();
  try
    {
      QString location =
        QFileInfo(_p_peptide_evidence->getMsRunP()->getFileName())
          .absoluteDir()
          .absolutePath();
      QStringList filenames = QFileDialog::getOpenFileNames(
        this, tr("Open new mzXML"), location, tr("mzXML Files (*.mzXML)"));

      foreach(QString new_filename, filenames)
        {
          MsRunSp msrun_sp = _p_xic_window->getProjectWindow()
                               ->getProjectP()
                               ->getMsRunStore()
                               .getInstance(new_filename);
          _p_xic_window->addXicInMsRun(_p_peptide_evidence, msrun_sp);
        }
    }
  catch(pappso::ExceptionNotFound &error)
    {
      qDebug() << " not found ";
    }
}

void
XicBox::setPeptideEvidence(const PeptideEvidence *p_peptide_evidence)
{


  _p_peptide_evidence = p_peptide_evidence;
  _msrun_sp = p_peptide_evidence->getIdentificationDataSource()->getMsRunSp();

  ui->peptide_label->setText(
    _p_peptide_evidence->getPeptideXtpSp().get()->toString());
  ui->charge_label->setText(
    QString("%1").arg(_p_peptide_evidence->getCharge()));
  ui->mz_label->setText(
    QString::number(_p_peptide_evidence->getTheoreticalMz(), 'f', 4));
  ui->msrun_label->setText(
    QFileInfo(_p_peptide_evidence->getMsRunP()->getFileName()).fileName());
  ui->msrun_label->setToolTip("Test2");
  // get same xic peptide evidence (msrun, peptide, charge)
  // p_projet
  _peptide_evidence_list.clear();
  _p_xic_window->getProjectWindow()
    ->getProjectP()
    ->getSameXicPeptideEvidenceList(
      _peptide_evidence_list,
      _msrun_sp.get(),
      _p_peptide_evidence->getPeptideXtpSp().get(),
      _p_peptide_evidence->getCharge());

  emit computeIsotopeMassList(_p_peptide_evidence->getPeptideXtpSp(),
                              _p_peptide_evidence->getCharge(),
                              _p_xic_window->getXicExtractPrecision(),
                              ui->isotopic_distribution_spinbox->value());
}

void
XicBox::setPeptideEvidenceInMsRun(const PeptideEvidence *p_peptide_evidence,
                                  MsRunSp msrun_sp)
{
  _p_peptide_evidence = p_peptide_evidence;
  _msrun_sp           = msrun_sp;

  ui->peptide_label->setText(
    _p_peptide_evidence->getPeptideXtpSp().get()->toString());
  ui->charge_label->setText(
    QString("%1").arg(_p_peptide_evidence->getCharge()));
  ui->mz_label->setText(
    QString::number(_p_peptide_evidence->getTheoreticalMz(), 'f', 4));
  ui->msrun_label->setText(QFileInfo(msrun_sp->getFileName()).fileName());
  ui->msrun_label->setToolTip("Test");
  // get same xic peptide evidence (msrun, peptide, charge)
  // p_projet
  _peptide_evidence_list.clear();

  _p_xic_window->getProjectWindow()
    ->getProjectP()
    ->getSameXicPeptideEvidenceList(
      _peptide_evidence_list,
      _msrun_sp.get(),
      _p_peptide_evidence->getPeptideXtpSp().get(),
      _p_peptide_evidence->getCharge());
  //_p_xic_window->getProjectWindow()->getProjectP()->getSameXicPeptideEvidenceList(p_peptide_evidence,
  //_peptide_evidence_list);

  emit computeIsotopeMassList(_p_peptide_evidence->getPeptideXtpSp(),
                              _p_peptide_evidence->getCharge(),
                              _p_xic_window->getXicExtractPrecision(),
                              ui->isotopic_distribution_spinbox->value());
}

const PeptideEvidence *
XicBox::getPeptideEvidenceP() const
{
  return _p_peptide_evidence;
}

MsRunSp
XicBox::getMsRunSp()
{
  return _msrun_sp;
}

void
XicBox::setXic(std::vector<pappso::XicCstSPtr> xic_sp_list)
{
  qDebug() << xic_sp_list.size();
  ui->xic_widget->clear();
  for(std::size_t i = 0; i < xic_sp_list.size(); i++)
    {
      _natural_isotope_list[i].xic_sp = xic_sp_list[i];
    }
  // pappso::XicWidget * xic_widget = new pappso::XicWidget(this);
  // ui->xic_list_widget->layout()->addWidget(xic_widget);
  for(XicBoxNaturalIsotope &xic_isotope : _natural_isotope_list)
    {
      // qDebug() << "XicBox::setXic xic " << xic_isotope.xic_sp.get();
      if(xic_isotope.xic_sp.get() == nullptr)
        {
          throw new pappso::PappsoException(
            "Error in XicBox::setXic:\n xic_isotope.xic_sp.get() == nullptr");
        }
      qDebug() << xic_isotope.xic_sp.get()->size();
      ui->xic_widget->addXicSp(xic_isotope.xic_sp);
      QString isotope_name = QString("+%1").arg(
        xic_isotope.peptide_natural_isotope_sp.get()->getIsotopeNumber());
      if(xic_isotope.peptide_natural_isotope_sp.get()->getIsotopeRank() > 1)
        {
          isotope_name =
            QString("+%1 [%2]")
              .arg(xic_isotope.peptide_natural_isotope_sp.get()
                     ->getIsotopeNumber())
              .arg(
                xic_isotope.peptide_natural_isotope_sp.get()->getIsotopeRank());
        }
      isotope_name.append(QString(" (%1%)").arg((
        int)(xic_isotope.peptide_natural_isotope_sp.get()->getIntensityRatio() *
             100)));
      ui->xic_widget->setName(xic_isotope.xic_sp.get(), isotope_name);

      if(xic_isotope.peptide_natural_isotope_sp.get()->getIsotopeNumber() == 0)
        {
          for(const PeptideEvidence *peptide_evidence : _peptide_evidence_list)
            {
              qDebug() << peptide_evidence->getHardenedRetentionTime();
              ui->xic_widget->addMsMsEvent(
                xic_isotope.xic_sp.get(),
                peptide_evidence->getHardenedRetentionTime());
            }
        }
    }
  qDebug();

  if(!_scaled)
    {
      ui->xic_widget->rescale();
      _scaled = true;
    }

  /*
  if (_isotope_mass_list.size() > _xic_widget_list.size()) {
      emit loadXic(_p_peptide_evidence->getMsRunP(),
  _isotope_mass_list[_xic_widget_list.size()].get()->getMz(),
  _p_xic_window->getXicExtractPrecision(), XicExtractMethod::max);
  }
  */
  XicDetectionList xic_list;
  xic_list.setPeptideEvidenceList(_peptide_evidence_list);

  std::vector<pappso::TracePeakCstSPtr> draw_peak_borders;

  for(XicBoxNaturalIsotope &xic_isotope : _natural_isotope_list)
    {
      try
        {
          xic_list.clear();
          _p_xic_window->xicDetect(*(xic_isotope.xic_sp.get()), &xic_list);
          xic_isotope.matched_peak_sp    = xic_list.getMatchedPeak();
          xic_isotope.detected_peak_list = xic_list.getXicPeakList();
          ui->xic_widget->addXicPeakList(xic_isotope.xic_sp.get(),
                                         xic_list.getXicPeakList());
          draw_peak_borders.push_back(xic_isotope.matched_peak_sp);
        }
      catch(const pappso::ExceptionNotPossible &e)
        {
          qDebug() << e.qwhat();
        }
    }

  qDebug() << "XicBox::setXic plot";
  ui->xic_widget->plot();
  drawObservedAreaBars(draw_peak_borders);
}


void
XicBox::drawObservedAreaBars(
  const std::vector<pappso::TracePeakCstSPtr> &observed_peak_to_draw_list)
{
  if(m_observedAreaBars == nullptr)
    {
      qDebug() << " new QCPBars";
      m_observedAreaBars =
        new QCPBars(ui->histo_widget->xAxis, ui->histo_widget->yAxis2);
      //       m_observedRatioBars = new QCPBars(ui->histo_widget->xAxis,
      //       ui->histo_widget->yAxis);
    }
  else
    {
      qDebug() << "plot clearData";
      m_observedAreaBars->data().clear();
      //       m_observedRatioBars->data().clear();
    }
  m_observedAreaBars->setName("peak area");
  //   m_observedRatioBars->setName("obs. ratio");
  // ui->histo_widget->yAxis2->setLabel("intensity");


  QVector<double> observed_intensity_data;
  QVector<double> observed_ratio_data;
  QVector<QString> labels;

  QVector<double> ticks;
  double sum = 0;
  int i      = 0;

  std::vector<std::size_t> common_peak_rt_measure_list;

  qDebug() << " plot _isotope_mass_list";
  for(const XicBoxNaturalIsotope &xic_isotope : _natural_isotope_list)
    {
      pappso::TracePeakCstSPtr peak_to_draw;
      for(pappso::TracePeakCstSPtr observed_peak : observed_peak_to_draw_list)
        {
          if(xic_isotope.contains(observed_peak))
            {
              peak_to_draw = observed_peak;
            }
        }
      if(peak_to_draw.get() == nullptr)
        {
        }
      else
        {
          addCommonRt(common_peak_rt_measure_list,
                      peak_to_draw.get(),
                      xic_isotope.xic_sp.get());


          sum += peak_to_draw.get()->getArea();
          observed_intensity_data << peak_to_draw.get()->getArea();
          QString isotope_name = QString("+%1").arg(
            xic_isotope.peptide_natural_isotope_sp.get()->getIsotopeNumber());
          if(xic_isotope.peptide_natural_isotope_sp.get()->getIsotopeRank() > 1)
            {
              isotope_name =
                QString("+%1 [%2]")
                  .arg(xic_isotope.peptide_natural_isotope_sp.get()
                         ->getIsotopeNumber())
                  .arg(xic_isotope.peptide_natural_isotope_sp.get()
                         ->getIsotopeRank());
            }
          isotope_name.append(QString(" (%1%)").arg(
            (int)(xic_isotope.peptide_natural_isotope_sp.get()
                    ->getIntensityRatio() *
                  100)));
          labels << isotope_name;
          ticks << i;
        }
      i++;
    }

  //   m_observedRatioBars->setPen(QPen(QColor("red")));
  m_observedAreaBars->setPen(QColor(180, 15, 32, 200));
  m_observedAreaBars->setBrush(QColor(180, 15, 32, 200));
  //_graph_peak_surface_list.back()->setScatterStyle(QCPScatterStyle::ssDot);
  // observed_intensity->setBrush(QBrush(QColor(170, 255, 0, 0)));

  double sum_observed_ratio = 0;
  double total_ratio        = 0;
  for(XicBoxNaturalIsotope &xic_isotope : _natural_isotope_list)
    {
      xic_isotope.computeMeanIntensityIn(common_peak_rt_measure_list);

      sum_observed_ratio += xic_isotope.meanIntensityInCurrentPeak;
      total_ratio +=
        xic_isotope.peptide_natural_isotope_sp.get()->getIntensityRatio();
    }
  for(XicBoxNaturalIsotope &xic_isotope : _natural_isotope_list)
    {
      observed_ratio_data << ((xic_isotope.meanIntensityInCurrentPeak /
                               sum_observed_ratio) *
                              total_ratio);
    }

  if(ticks.size() > 0)
    {
      for(double &tick : ticks)
        {
          tick += 0.1;
        }
      m_observedAreaBars->setData(ticks, observed_intensity_data);
      m_observedAreaBars->setWidth(0.6);

      //       QVector<QString> labels;
      //       for(double tick : ticks)
      //         {
      //           labels.push_back(QString::number(tick));
      //         }
      //       QSharedPointer<QCPAxisTickerText> textTicker(new
      //       QCPAxisTickerText); textTicker->addTicks(ticks, labels);
      //       ui->histo_widget->yAxis->setTicker(textTicker);
      //       m_observedRatioBars->setData(ticks, observed_ratio_data);

      ui->histo_widget->yAxis2->setVisible(true);
      ui->histo_widget->yAxis2->setRange(0, sum);
      ui->histo_widget->yAxis2->setLabel("observed intensity");
      ui->histo_widget->yAxis2->setLabelPadding(0);
      ui->histo_widget->replot();
    }
  qDebug();
}


void
XicBox::setIsotopeMassList(
  std::vector<pappso::PeptideNaturalIsotopeAverageSp> isotope_mass_list)
{
  _natural_isotope_list.clear();
  std::vector<pappso::pappso_double> mass_list;
  for(pappso::PeptideNaturalIsotopeAverageSp &natural_isotope_average :
      isotope_mass_list)
    {
      mass_list.push_back(natural_isotope_average.get()->getMz());
      _natural_isotope_list.push_back(
        {nullptr, natural_isotope_average, nullptr, nullptr, {}});
    }

  emit loadXic(_msrun_sp,
               mass_list,
               _p_xic_window->getXicExtractPrecision(),
               pappso::XicExtractMethod::max);

  // histogram
  if(m_theoreticalRatioBars == nullptr)
    {
      m_theoreticalRatioBars =
        new QCPBars(ui->histo_widget->xAxis, ui->histo_widget->yAxis);
    }
  else
    {
      m_theoreticalRatioBars->data()->clear();
    }
  m_theoreticalRatioBars->setName("th. ratio");
  ui->histo_widget->xAxis->setLabel("isotopes");
  m_theoreticalRatioBars->setPen(QColor(59, 154, 178));
  m_theoreticalRatioBars->setBrush(QColor(59, 154, 178));
  // ui->histo_widget->yAxis->setLabel("th. ratio");

  QVector<double> theoretical_ratio_data;

  QVector<double> ticks;
  QVector<QString> labels;
  int i      = 0;
  double sum = 0;
  for(const XicBoxNaturalIsotope &xic_isotope : _natural_isotope_list)
    {
      sum += xic_isotope.peptide_natural_isotope_sp.get()->getIntensityRatio();
      theoretical_ratio_data
        << xic_isotope.peptide_natural_isotope_sp.get()->getIntensityRatio();
      QString isotope_name = QString("+%1").arg(
        xic_isotope.peptide_natural_isotope_sp.get()->getIsotopeNumber());
      if(xic_isotope.peptide_natural_isotope_sp.get()->getIsotopeRank() > 1)
        {
          isotope_name =
            QString("+%1 [%2]")
              .arg(xic_isotope.peptide_natural_isotope_sp.get()
                     ->getIsotopeNumber())
              .arg(
                xic_isotope.peptide_natural_isotope_sp.get()->getIsotopeRank());
        }
      isotope_name.append(QString(" (%1%)").arg((
        int)(xic_isotope.peptide_natural_isotope_sp.get()->getIntensityRatio() *
             100)));
      labels << QString::number(
        xic_isotope.peptide_natural_isotope_sp.get()->getIsotopeNumber());
      ticks << i;
      i++;
    }
  QSharedPointer<QCPAxisTickerText> textTicker(new QCPAxisTickerText);
  textTicker->addTicks(ticks, labels);
  ui->histo_widget->xAxis->setTicker(textTicker);
  ui->histo_widget->xAxis->setTickLabelRotation(0);
  // ui->histo_widget->xAxis->setSubTicks(false);
  // ui->histo_widget->xAxis->setTickLength(0, 4);
  // ui->histo_widget->xAxis->setRange(0, 8);
  /*
    ui->histo_widget->xAxis->setAutoTickStep(
      false); // <-- disable to use your own value

    ui->histo_widget->xAxis->setTickStep(1);
  */
  for(double &tick : ticks)
    {
      tick -= 0.1;
    }
  m_theoreticalRatioBars->setData(ticks, theoretical_ratio_data);
  m_theoreticalRatioBars->setWidth(0.6);


  ui->histo_widget->yAxis->setRange(0, sum);
  ui->histo_widget->yAxis->setLabel("intensity ratio");
  ui->histo_widget->yAxis->setLabelPadding(0);
  ui->histo_widget->xAxis->setRange(-0.5, _natural_isotope_list.size() - 0.5);
  ui->histo_widget->replot();
}


void
XicBox::reExtractXic()
{
  qDebug();
  ui->xic_widget->clear();

  std::vector<pappso::pappso_double> mass_list;
  for(const XicBoxNaturalIsotope &xic_isotope : _natural_isotope_list)
    {
      mass_list.push_back(
        xic_isotope.peptide_natural_isotope_sp.get()->getMz());
    }
  emit loadXic(_msrun_sp,
               mass_list,
               _p_xic_window->getXicExtractPrecision(),
               _p_xic_window->getXicExtractionMethod());
  qDebug();
}

void
XicBox::setRetentionTime(double rt)
{
  qDebug() << " begin";
  ui->rt_label->setText(tr("rt=%1 (sec) rt=%2 (min)").arg(rt).arg(rt / 60));
}
void
XicBox::setXicPeakList(
  std::vector<std::pair<pappso::XicCstSPtr, pappso::TracePeakCstSPtr>>
    xic_peak_list)
{
  qDebug() << " begin";
  QString html;
  for(XicBoxNaturalIsotope &xic_isotope : _natural_isotope_list)
    {
      xic_isotope.one_peak_sp = nullptr;
    }

  for(std::pair<pappso::XicCstSPtr, pappso::TracePeakCstSPtr> &pair_xic_peak :
      xic_peak_list)
    {
      for(XicBoxNaturalIsotope &xic_isotope : _natural_isotope_list)
        {
          if(xic_isotope.xic_sp.get() == pair_xic_peak.first.get())
            {
              xic_isotope.one_peak_sp = pair_xic_peak.second;
            }
        }
      html.append(
        tr("<p>%1<br/>area: %2<br/>rt begin: %3<br/>rt max: "
           "%4<br/>rt end: %5<br/></p>")
          .arg(ui->xic_widget->getName(pair_xic_peak.first.get()))
          .arg(QString::number(
            std::trunc(pair_xic_peak.second.get()->getArea()), 'G', 16))
          .arg(pair_xic_peak.second.get()->getLeftBoundary().x)
          .arg(pair_xic_peak.second.get()->getMaxXicElement().x)
          .arg(pair_xic_peak.second.get()->getRightBoundary().x));
    }

  ui->xic_widget->setToolTip(html);
  /*
      if (_popup_peak_info == nullptr) delete _popup_peak_info;
      _popup_peak_info = new QFrame( this ,Qt::Popup);
      //_popup_peak_info->setFrameStyle(Qt::WinPanel|Qt::Raised );
      _popup_peak_info->resize(150,100);
      _popup_peak_info->show();
      */
}


void
XicBox::onRtUnitChanged()
{
  if(_p_xic_window->isRetentionTimeSeconds())
    {
      ui->xic_widget->setRetentionTimeInSeconds();
    }
  else
    {
      ui->xic_widget->setRetentionTimeInMinutes();
    }
}

void
XicBox::onIsotopicDistributionClick()
{
  //   ui->histo_widget->legend->clear();
  setPeptideEvidence(_p_peptide_evidence);
}

void
XicBox::addCommonRt(std::vector<std::size_t> &common_peak_rt_measure_list,
                    const pappso::TracePeak *peak,
                    const pappso::Xic *xic) const
{

  if(common_peak_rt_measure_list.size() == 0)
    { // no common peaks, filling with whole peak
      auto it = pappso::findFirstEqualOrGreaterX(
        xic->begin(), xic->end(), peak->getLeftBoundary().x);
      auto itend = pappso::findFirstGreaterX(
        xic->begin(), xic->end(), peak->getRightBoundary().x);

      std::size_t i = it - xic->begin();

      while(it != itend)
        {
          if(it->y > (0.6 * peak->getMaxXicElement().y))
            {
              common_peak_rt_measure_list.push_back(i);
            }
          it++;
          i++;
        }
    }
  else
    {
      std::vector<std::size_t> intersect(common_peak_rt_measure_list);
      std::vector<std::size_t> new_rt;
      auto it = pappso::findFirstEqualOrGreaterX(
        xic->begin(), xic->end(), peak->getLeftBoundary().x);
      auto itend = pappso::findFirstGreaterX(
        xic->begin(), xic->end(), peak->getRightBoundary().x);

      std::size_t i = it - xic->begin();
      while(it != itend)
        {
          if(it->y > 0)
            {
              new_rt.push_back(i);
            }
          it++;
          i++;
        }

      auto itinter = std::set_intersection(intersect.begin(),
                                           intersect.end(),
                                           new_rt.begin(),
                                           new_rt.end(),
                                           common_peak_rt_measure_list.begin());
      common_peak_rt_measure_list.resize(itinter -
                                         common_peak_rt_measure_list.begin());
      /*
            for(auto indice : common_peak_rt_measure_list)
              {
                qDebug() << indice << " " << xic->at(indice).x << " "
                         << xic->at(indice).y;
              }
              */
    }
}

std::vector<XicBoxNaturalIsotope>
XicBox::getNaturalIsotopList() const
{
  return _natural_isotope_list;
}

double
XicBox::getIsotopicFractionDistribution() const
{
  return ui->isotopic_distribution_spinbox->value();
}
