/**
 * \file pappsomspp/vendors/tims/xicextractor/timsdirectxicextractor.cpp
 * \date 21/09/2019
 * \author Olivier Langella
 * \brief minimum functions to extract XICs from Tims Data
 */

/*******************************************************************************
 * Copyright (c) 2019 Olivier Langella <Olivier.Langella@u-psud.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 "timsdirectxicextractor.h"
#include "../../../msrun/xiccoord/xiccoordtims.h"
#include "../../../exception/exceptioninterrupted.h"
#include <QDebug>

using namespace pappso;

TimsDirectXicExtractor::TimsDirectXicExtractor(MsRunReaderSPtr &msrun_reader)
  : pappso::TimsXicExtractorInterface(msrun_reader)
{
}

TimsDirectXicExtractor::~TimsDirectXicExtractor()
{
}


void
pappso::TimsDirectXicExtractor::protectedExtractXicCoordSPtrList(
  UiMonitorInterface &monitor,
  std::vector<XicCoordSPtr>::iterator it_xic_coord_list_begin,
  std::vector<XicCoordSPtr>::iterator it_xic_coord_list_end)
{
  qDebug();
  std::size_t xic_total_number =
    std::distance(it_xic_coord_list_begin, it_xic_coord_list_end);
  if(xic_total_number == 0)
    return;

  std::vector<XicCoordTims *> xic_coord_tims_list;
  xic_coord_tims_list.reserve(xic_total_number);

  for(auto it = it_xic_coord_list_begin; it != it_xic_coord_list_end; it++)
    {
      XicCoordTims *p_xic_coord_tims = dynamic_cast<XicCoordTims *>(it->get());
      if(p_xic_coord_tims == nullptr)
        {
        }
      else
        {
          xic_coord_tims_list.push_back(p_xic_coord_tims);
        }
    }

  std::sort(xic_coord_tims_list.begin(),
            xic_coord_tims_list.end(),
            [](const XicCoordTims *pa, const XicCoordTims *pb) {
              return pa->rtTarget < pb->rtTarget;
            });


  std::vector<std::size_t> tims_frameid_list =
    mp_timsData->getTimsMS1FrameIdsInRtRange(
      xic_coord_tims_list[0]->rtTarget - m_retentionTimeAroundTarget,
      xic_coord_tims_list.back()->rtTarget + m_retentionTimeAroundTarget);

  monitor.setStatus(QObject::tr("extracting %1 XICs on %2 Tims frames")
                      .arg(xic_total_number)
                      .arg(tims_frameid_list.size()));
  monitor.setTotalSteps(tims_frameid_list.size());

  qDebug() << " tims_frameid_list.size()=" << tims_frameid_list.size();
  qDebug() << " rt begin=" << xic_coord_tims_list[0]->rtTarget;
  qDebug() << " rt end=" << xic_coord_tims_list.back()->rtTarget;
  for(std::size_t frame_id : tims_frameid_list)
    {
      std::vector<XicCoordTims *>::iterator itXicListbegin =
        xic_coord_tims_list.begin();
      std::vector<XicCoordTims *>::iterator itXicListend =
        xic_coord_tims_list.end();
      qDebug();
      TimsFrameCstSPtr frame_sptr =
        mp_timsData->getTimsFrameCstSPtrCached(frame_id);
      qDebug();
      double rtframe = frame_sptr.get()->getRtInSeconds();
      qDebug();

      double rtbeginframe = rtframe - m_retentionTimeAroundTarget;
      double rtendframe   = rtframe + m_retentionTimeAroundTarget;

      if(rtbeginframe < 0)
        rtbeginframe = 0;

      qDebug() << rtbeginframe;
      while((itXicListbegin != itXicListend) &&
            ((*itXicListbegin)->rtTarget < rtbeginframe))
        {
          itXicListbegin++;
        }
      qDebug();
      itXicListend = itXicListbegin;
      while((itXicListend != xic_coord_tims_list.end()) &&
            ((*itXicListend)->rtTarget < rtendframe))
        {
          itXicListend++;
        }
      frame_sptr.get()->extractTimsXicListInRtRange(
        itXicListbegin, itXicListend, m_xicExtractMethod);

      qDebug() << "" << frame_sptr.get()->getId();
      monitor.count();
      if(monitor.shouldIstop())
        {
          throw pappso::ExceptionInterrupted(
            QObject::tr("Xic extraction process interrupted"));
        }
    }
  qDebug();
}
