#pragma once

/////////////////////// stdlib includes
#include <vector>
#include <memory>

/////////////////////// Qt includes
#include <QDataStream>

/////////////////////// Local includes
#include "pappsomspp/export-import-config.h"
#include "../../types.h"
#include "../../trace/datapoint.h"
#include "massdatacombinerinterface.h"
#include "pappsomspp/core/js_qml/jsclassregistrar.h"

namespace pappso
{

class MassSpectrumCombiner;

typedef std::shared_ptr<const MassSpectrumCombiner> MassSpectrumCombinerCstSPtr;
typedef std::shared_ptr<MassSpectrumCombiner> MassSpectrumCombinerSPtr;

class PMSPP_LIB_DECL MassSpectrumCombiner: public QObject,
                                           public MassDataCombinerInterface
{
  Q_OBJECT

  Q_PROPERTY(int size READ binCount NOTIFY binCountChanged)

  public:
  MassSpectrumCombiner(QObject *parent_p = nullptr);
  MassSpectrumCombiner(int decimal_places, QObject *parent_p = nullptr);
  MassSpectrumCombiner(std::vector<pappso_double> bins,
                       int decimalPlaces = -1,
                       QObject *parent_p = nullptr);
  MassSpectrumCombiner(MassSpectrumCombinerCstSPtr other,
                       QObject *parent_p = nullptr);
  MassSpectrumCombiner(const MassSpectrumCombiner &other,
                       QObject *parent_p = nullptr);
  MassSpectrumCombiner(const MassSpectrumCombiner &&other,
                       QObject *parent_p = nullptr);

  virtual ~MassSpectrumCombiner();

  Q_INVOKABLE void setBins(std::vector<pappso_double> bins);
  Q_INVOKABLE const std::vector<pappso_double> &getBins() const;
  Q_INVOKABLE std::size_t binCount() const;

  Q_INVOKABLE QString binsAsString() const;

  // # pragma message "This pragma is inside"
  static void registerJsConstructor(QJSEngine *engine);

  signals:
  void binCountChanged();

  protected:
  std::vector<pappso_double> m_bins;

  std::vector<pappso_double>::iterator findBin(pappso_double mz);
};

PAPPSO_REGISTER_JS_CLASS(pappso, MassSpectrumCombiner)

} // namespace pappso
