/**
 * \file pappsomspp/vendors/tims/timsdatafastmap.h
 * \date 16/12/2023
 * \author Olivier Langella
 * \brief replacement fot std::map dedicated to tims data for fast computations
 */

/*******************************************************************************
 * Copyright (c) 2023 Olivier Langella
 *<Olivier.Langella@universite-paris-saclay.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/>.
 *
 ******************************************************************************/

#pragma once

#include <cstdlib>
#include <vector>
#include <map>
#include <QThread>
#include "pappsomspp/export-import-config.h"

namespace pappso
{
/**
 * @brief replacement for std::map
 *
 * Beware to use it carefully : clear the tofIndexList before using it
 *
 */
class PMSPP_LIB_DECL TimsDataFastMap
{
  public:
  static std::map<QThread *, TimsDataFastMap> m_preAllocatedFastMapPerThread;
  static TimsDataFastMap &getTimsDataFastMapInstance();

  // static constexpr quint32 index_not_defined{
  //  std::numeric_limits<quint32>::max()};

  struct TimsDataFastMapElement
  {
    bool first_access = true;
    std::size_t count = 0;
  };

  /** @brief accumulates intesity for the given tof index
   *
   * sets the count value on the first access ( first_access is true) and add
   * the tof index to the tofIndexList then increments it if it is called on the
   * same tof index
   */
  std::size_t accumulateIntensity(quint32 tofIndex, std::size_t intensity);


  /** @brief reads intensity for a tof_index
   *
   * reads the cumulated intensity for this tof index and replaces the first
   * access boolean to true.
   * => this is important to reuse the map in an other computation
   * No need to erase the content or initialize it
   */
  std::size_t readIntensity(quint32);


  /** @brief downsize mz resolution to lower the number of real mz computations
   *
   * the map is modified in place
   *
   * @param mzindex_merge_window width of the mzindex window used to merge all
   * intensities into a single point. This results in faster computing.
   */
  void downsizeMzRawMap(std::size_t mzindex_merge_window);

  /** @brief simple filter to agregate counts on neigbhor mobility slots (+1)
   *
   * the map is modified in place
   *
   */
  void builtInCentroid();

  void removeArtefactualSpike();

  const std::vector<quint32> &getTofIndexList() const;

  void clear();

  private:
  TimsDataFastMap();

  std::vector<quint32> tofIndexList;

  std::vector<TimsDataFastMapElement> mapTofIndexIntensity;
};

} // namespace pappso
