/**
 * \file utils/peptideevidencestore.cpp
 * \date 18/11/2017
 * \author Olivier Langella
 * \brief store unique instances of peptide evidences
 */


/*******************************************************************************
 * Copyright (c) 2017 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 "peptideevidencestore.h"
#include <QDebug>
#include <pappsomspp/pappsoexception.h>

#include "../core/peptideevidence.h"
#include "../core/msrun.h"
#include "../core/peptidextp.h"

std::shared_ptr<PeptideEvidence> &
PeptideEvidenceStore::recordInstance(const PeptideEvidence *p_peptide_evidence)
{
  _peptide_evidence_list.push_back(p_peptide_evidence->makePeptideEvidenceSp());

  // qDebug() << "PeptideEvidenceStore::getInstance end " <<
  // find_it->second.get()->getScan() << " size=" <<
  // _multimap_scan_evidence.size();
  return _peptide_evidence_list.back();
}

std::shared_ptr<PeptideEvidence> &
PeptideEvidenceStore::getInstance(const PeptideEvidence *p_peptide_evidence)
{
  // qDebug() << __FILE__ << " " << __FUNCTION__<< " " << __LINE__ << " scan="
  // << p_peptide_evidence->getScan(); qDebug() <<
  // "PeptideEvidenceStore::getInstance begin" ;
  std::multimap<unsigned int, PeptideEvidenceSp>::iterator it =
    _multimap_scan_evidence.find(p_peptide_evidence->getScanNumber());
  std::multimap<unsigned int, PeptideEvidenceSp>::iterator find_it =
    _multimap_scan_evidence.end();


  while((find_it == _multimap_scan_evidence.end()) &&
        (it->first == p_peptide_evidence->getScanNumber()) && (it != find_it))
    {
      if(it->second.get()->getPeptideXtpSp().get() ==
         p_peptide_evidence->getPeptideXtpSp().get())
        {
          // it is the same peptide
          find_it = it;
        }
      else
        {
          // throw
          // pappso::PappsoException(QObject::tr("PeptideEvidenceStore::getInstance
          // multiple peptide for scan %1").arg(p_peptide_evidence->getScan()));
        }
      it++;
    }

  if(find_it == _multimap_scan_evidence.end())
    {
      // insert it
      find_it = _multimap_scan_evidence.insert(
        std::pair<unsigned int, PeptideEvidenceSp>(
          p_peptide_evidence->getScanNumber(),
          p_peptide_evidence->makePeptideEvidenceSp()));
      _peptide_evidence_list.push_back(find_it->second);
    }
  // qDebug() << "PeptideEvidenceStore::getInstance end " <<
  // find_it->second.get()->getScan() << " size=" <<
  // _multimap_scan_evidence.size(); qDebug() << __FILE__ << " " <<
  // __FUNCTION__<< " " << __LINE__;
  return find_it->second;
}


std::size_t
PeptideEvidenceStore::size() const
{
  return _peptide_evidence_list.size();
}

void
PeptideEvidenceStore::clearMap()
{
  qDebug() << "PeptideEvidenceStore::clearMap begin";
  _multimap_scan_evidence.clear();
  qDebug() << "PeptideEvidenceStore::clearMap end";
}

void
PeptideEvidenceStore::updateAutomaticFilters(
  const AutomaticFilterParameters &automatic_filter_parameters)
{
  qDebug() << "PeptideEvidenceStore::updateAutomaticFilters begin";
  for(PeptideEvidenceSp &peptide_evidence_sp : _peptide_evidence_list)
    {
      peptide_evidence_sp.get()->updateAutomaticFilters(
        automatic_filter_parameters);
    }
  qDebug() << "PeptideEvidenceStore::updateAutomaticFilters end";
}

const std::vector<std::shared_ptr<PeptideEvidence>> &
PeptideEvidenceStore::getPeptideEvidenceList() const
{
  return _peptide_evidence_list;
}


void
PeptideEvidenceStore::getSameXicPeptideEvidenceList(
  std::vector<const PeptideEvidence *> &peptide_evidence_list,
  const MsRun *p_msrun,
  const PeptideXtp *p_peptide,
  unsigned int charge) const
{
  for(const PeptideEvidenceSp &peptide_evidence_sp : _peptide_evidence_list)
    {
      if(p_msrun != peptide_evidence_sp.get()->getMsRunP())
        continue;
      else if(p_peptide != peptide_evidence_sp.get()->getPeptideXtpSp().get())
        continue;
      else if(charge != peptide_evidence_sp.get()->getCharge())
        continue;
      peptide_evidence_list.push_back(peptide_evidence_sp.get());
    }
}
