#pragma once

#include <vector>
#include <memory>

#include <QObject>
#include <QDataStream>
#include <QMetaType>


#include "pappsomspp/export-import-config.h"
#include "pappsomspp/core/types.h"
#include "trace.h"
#include "datapoint.h"
#include "pappsomspp/core/mzrange.h"

namespace pappso
{


class MapTrace;

// FIXME: not sure how these are actually used?
PMSPP_LIB_DECL QDataStream &operator<<(QDataStream &out, const Trace &trace);
PMSPP_LIB_DECL QDataStream &operator>>(QDataStream &out, Trace &trace);


typedef std::shared_ptr<MapTrace> MapTraceSPtr;
typedef std::shared_ptr<const MapTrace> MapTraceCstSPtr;

class TraceCombiner;
class TracePlusCombiner;
class TraceMinusCombiner;

class PMSPP_LIB_DECL MapTrace : public std::map<pappso_double, pappso_double>
{
  public:
  MapTrace();
  MapTrace(
    const std::vector<std::pair<pappso_double, pappso_double>> &dataPoints);
  MapTrace(const std::vector<DataPoint> &dataPoints);
  MapTrace(const MapTrace &other);
  MapTrace(const Trace &trace);

  virtual ~MapTrace();

  size_t initialize(const std::vector<pappso_double> &xVector,
                    const std::vector<pappso_double> &yVector);

  size_t initialize(const std::map<pappso_double, pappso_double> &map);

  virtual MapTrace &operator=(const MapTrace &other);

  MapTraceSPtr makeMapTraceSPtr() const;
  MapTraceCstSPtr makeMapTraceCstSPtr() const;

  std::vector<pappso_double> xValues();
  std::vector<pappso_double> yValues();

  void insertOrUpdate(const DataPoint &data_point);
  void insertOrUpdate(const Trace &trace);

  Trace toTrace() const;
  QString toString() const;

  protected:
  private:
};


} // namespace pappso

Q_DECLARE_METATYPE(pappso::MapTrace);
Q_DECLARE_METATYPE(pappso::MapTrace *);

extern int mapTraceMetaTypeId;
extern int mapTracePtrMetaTypeId;
