/**
 * \file pappsomspp/psm/peptidespectrummatch.h
 * \date 2/4/2015
 * \author Olivier Langella
 * \brief find peaks matching between ions and spectrum
 */

/*******************************************************************************
 * Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.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/>.
 *
 * Contributors:
 *     Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and
 *implementation
 ******************************************************************************/

#pragma once

#include "../massspectrum/massspectrum.h"
#include "../mzrange.h"
#include "../peptide/peptidefragmention.h"
#include "../peptide/peptidefragmentionlistbase.h"
#include "peakionmatch.h"

namespace pappso
{


class PMSPP_LIB_DECL PeptideSpectrumMatch
{
  public:
  PeptideSpectrumMatch(const MassSpectrum &spectrum,
                       const pappso::PeptideSp &peptideSp,
                       unsigned int parent_charge,
                       PrecisionPtr precision,
                       const std::list<PeptideIon> &ion_type_list);
  PeptideSpectrumMatch(
    const MassSpectrum &spectrum,
    const PeptideFragmentIonListBase &peptide_fragment_ion_list,
    unsigned int parent_charge,
    PrecisionPtr precision,
    const std::list<PeptideIon> &ion_type_list);
  PeptideSpectrumMatch(
    const MassSpectrum &spectrum,
    std::vector<PeptideFragmentIonSp> &v_peptide_fragment_ion,
    std::vector<unsigned int> &v_peptide_fragment_ion_charge,
    PrecisionPtr precision);
  PeptideSpectrumMatch(const PeptideSpectrumMatch &other);

  virtual ~PeptideSpectrumMatch();

  bool contains(const PeptideFragmentIon *peptideFragmentIonSp,
                unsigned int z) const;

  typedef std::list<PeakIonMatch>::const_iterator const_iterator;

  unsigned int size() const;
  const_iterator begin() const;
  const_iterator end() const;

  unsigned int countTotalMatchedIons() const;
  const std::array<unsigned int, PEPTIDE_ION_TYPE_COUNT> &
  getIonTypeCountArray() const;

  private:
  void privMatchIonList(const MassSpectrum &spectrum,
                        const PeptideFragmentIonListBase &fragmentIonList,
                        unsigned int max_charge,
                        const std::list<PeptideIon> &ion_type_list);

  virtual std::list<DataPoint>::iterator
  getBestPeakIterator(std::list<DataPoint> &peak_list,
                      const PeptideFragmentIonSp &ion,
                      unsigned int charge) const;


  private:
  PrecisionPtr _precision;

  std::list<PeakIonMatch> _peak_ion_match_list;

  std::array<unsigned int, PEPTIDE_ION_TYPE_COUNT> _ion_type_count = {{0}};
};


} // namespace pappso
