/**
 * \file core/spoms/interpretationsaver.h
 * \date 16/02/2026
 * \author Aurélien Berthier, BENOIST Emile, TESSIER Dominique
 * \brief store alignment interpretations
 */


/*
 * PeptidOMS, Spectra to protein alignment tool
 * Copyright (C) 2026  Olivier Langella
 * <olivier.langella@cnrs.fr>
 *
 * This program 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.
 *
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#pragma once
#include <cstddef>
#include <memory>
#include <pappsomspp/core/massspectrum/qualifiedmassspectrum.h>
#include <vector>
#include "locationbackup.h"

namespace pappso
{
namespace spoms
{

class Protein;
/*
 * l'objet "ScenarioSaver" sert a stocker les 'x' meilleurs interpretations d'un
 * spectre en dynamique, c'est à dire que ces 'x' meilleures peuvent changer en
 * direct ('x' est a définir dans les parametres). Un "ScenarioSaver" est
 * principalement compose d'un tas binaire permettant d'effectuer en temps
 * logarithmique en 'x', la modification dynamique des meilleures
 * interpretations. Chaque interpretation est stockee sous la forme d'un
 * "ScenarioBackup"
 */
class InterpretationsSaver
{


  public:
  InterpretationsSaver(const pappso::spoms::Protein *protein_p,
                       int nb_locations_saved);
  InterpretationsSaver(const InterpretationsSaver &other);
  virtual ~InterpretationsSaver();

  /*
   * methode appelee lorsque l'on change de spectre (on pointe alors vers
   * l'objet "trees_position" du nouveau spectre)
   */
  // void updateSpectrum(int[] trees_position, NativeSpectrum spectrum);

  /*
   * methode appelee lorsque l'on change de proteine
   */
  // void updateProtein(int protein_number);

  /*
   * cette methodinterpretations_savere tente d'ajouter une interpretation dans
   * le tas. C'est possible si et seulement si son score est superieur au moins
   * bon score des interpretations retenus jusqu'a maintenant. Si c'est le cas,
   * on verifie qu'une autre interpretation 'x' du meme arbre n'est pas deja
   * presente dans le tas. Si ce n'est pas le cas, alors la nouvelle
   * interpretation prend simplement la place de la moins bonne. Si c'est le cas
   * et si la nouvelle interpretation a un meilleur score que 'x', alors elle
   * remplace 'x'
   */

  int tryAddLocation(int start_line, int end_line, int score, int tree_id);


  const std::vector<LocationBackup> &getLocations() const;

  double getLocationsScoreThreshold() const;


  // void saveSimpleAlignment(int interpretation_number, Alignment alignment);


  // void saveNonAlignedMass(int interpretation_number, Alignment alignment);

  /*
   * methode appelee lorsque les resultats courant doivent etre sauvegardes dans
   * le fichier de resultat
   */


  // void save(PrintWriter output);
  //
  const LocationBackup &getMaxScore() const;


  private:
  /*
   * methode interne liee au traitement du tas
   */

  void repositionLocation(int position);


  private:
  const std::size_t m_NB_LOCATIONS_SAVED = 1;
  std::vector<LocationBackup> m_locationHeap; // le tas binaire
  // LocationBackup current_heap_element;
  // int min_score_location; // le score de la moins bonne des interpretation
  // stockee dans le tas
  // int max_score_location;
  // double locations_score_threshold;

  // std::vector<int> trees_position; // une liste permettant de connaitre la
  // position d'une interpretation dans le tas
  // en fonction de son numero d'arbre

  const pappso::spoms::Protein
    *mp_protein; // permet de retenir le numero de la protein sur
                 // laquelle est effectue l'alignement courant

  // lequel est effectue l'alignement courant

  // std::vector<QString> simple_alignment_hits_modified;
  // std::vector<QString> simple_alignment_sequences;
  // std::vector<int> simple_alignment_scores;
  // std::vector<int> simple_alignment_nb_common_peaks;
  /*
private
private
String[] ;
private
int[] simple_alignment_scores;
private
int[] simple_alignment_nb_common_peaks;

private
String[] non_aligned_mass_hits_modified;
private
String[] non_aligned_mass_sequences;
private
int[] non_aligned_mass_scores;
private
int[] non_aligned_mass_nb_common_peaks;
private
double[] non_aligned_masses;

private
String[] hit_modified_and_real_sequence;*/
};
} // namespace spoms
} // namespace pappso
