/**
 * \file pappsomspp/amino_acid/aastringcodemassmatching.h
 * \date 10/05/2023
 * \author Olivier Langella
 * \brief convert mass list to amino acid string code list
 */

/*******************************************************************************
 * Copyright (c) 2023 Olivier Langella <Olivier.Langella@u-psud.fr>.
 *
 * This file is part of PAPPSOms-tools.
 *
 *     PAPPSOms-tools 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-tools 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-tools.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/

#pragma once

#include "../exportinmportconfig.h"
#include "aastringcodec.h"
#include "../mzrange.h"

namespace pappso
{

/**
 * @brief convert  a list of mass to amino acid string codes
 */
class PMSPP_LIB_DECL AaStringCodeMassMatching
{
  public:
  /**
   * Default constructor
   */
  AaStringCodeMassMatching(const AaCode &aa_code,
                           std::size_t model_max_size,
                           PrecisionPtr precision);

  /**
   * Copy constructor
   *
   * @param other TODO
   */
  AaStringCodeMassMatching(const AaStringCodeMassMatching &other);

  /**
   * Destructor
   */
  ~AaStringCodeMassMatching();

  PrecisionPtr getPrecisionPtr() const;


  /** @brief get amino acid string code from mass delta list
   * mass delta is a list of masses differences found in a spectrum
   * see @file /pappsomspp/filers/filtepeakdelta.h functions
   */
  std::vector<uint32_t>
  getAaCodeFromMassList(std::vector<double> &mass_list) const;


  /** @brief get amino acid string code from a single mass delta
   * @param mass the mass to look for
   */
  std::vector<uint32_t> getAaCodeFromMass(double mass) const;


  /** @brief get amino acid string code from a single mass delta wearing a
   * specific modification
   * @param mass the mass to look for
   * @param aa amino acid with modification
   * @param quantifier the minimum number of this aa modified required in the
   * given aa sequence
   */
  std::vector<uint32_t> getAaCodeFromMassWearingModification(
    double mass, const Aa &aa, int quantifier) const;


  /** @brief filter a list of amino acid string code
   * find elementary amino acids (one base only) in the list and retrieve 2 or
   * more amino acid string containing only basic aminio acid found
   */
  std::vector<uint32_t> filterCodeList(std::vector<uint32_t> &code_list) const;

  private:
  PrecisionPtr m_precision = nullptr;
  const AaCode &m_aaCode;

  AaStringCodec m_aaCodec;


  uint32_t m_base = 0;

  struct aaCodeAndMassRange
  {
    std::uint32_t code  = 0;
    double mz_range_low = 0;
    double mz           = 0;
    double mz_range_up  = 0;
  };

  std::vector<aaCodeAndMassRange> m_codeMassList;
};
} // namespace pappso
