
/* BEGIN software license
 *
 * msXpertSuite - mass spectrometry software suite
 * -----------------------------------------------
 * Copyright (C) 2009--2020 Filippo Rusconi
 *
 * http://www.msxpertsuite.org
 *
 * This file is part of the msXpertSuite project.
 *
 * The msXpertSuite project is the successor of the massXpert project. This
 * project now includes various independent modules:
 *
 * - massXpert, model polymer chemistries and simulate mass spectrometric data;
 * - mineXpert, a powerful TIC chromatogram/mass spectrum viewer/miner;
 *
 * 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/>.
 *
 * END software license
 */


#pragma once

/////////////////////// StdLib includes


/////////////////////// Qt includes
#include <QWidget>


/////////////////////// QCustomPlot
#include <qcustomplot.h>


/////////////////////// pappsomspp includes


/////////////////////// Local includes
#include "TracePlotLabel.hpp"


namespace MsXpS
{
namespace MineXpert
{

class TracePlotLabelList: public QObject
{
  Q_OBJECT

  public:
  TracePlotLabelList(QObject *parent);

  TracePlotLabelList(const QString &name,
                     const QString &plot_layer_name,
                     QObject *parent = nullptr);

  TracePlotLabelList(const QString &name,
                     const QString &plot_layer_name,
                     QCustomPlot *plot_rp,
                     QObject *parent = nullptr);

  TracePlotLabelList(const QString &name,
                     const QString &plot_layer_name,
                     QCustomPlot *plot_rp,
                     const QFont &font,
                     const QColor &color,
                     QObject *parent = nullptr);

  TracePlotLabelList(const QString &name,
                     const QString &plot_layer_name,
                     QCustomPlot *plot_rp,
                     bool should_manage_layout,
                     float x_axis_delta_trigger,
                     int label_vertical_shift_count_factor,
                     QObject *parent = nullptr);


  TracePlotLabelList(const QString &name,
                     const QString &plot_layer_name,
                     QCustomPlot *plot_rp,
                     bool should_manage_layout,
                     float x_axis_delta_trigger,
                     int label_vertical_shift_count_factor,
                     const QFont &font,
                     const QColor &color,
                     QObject *parent = nullptr);

  void setName(const QString &name);
  const QString &getName() const;

  void setPlot(QCustomPlot *plot_rp);
  QCustomPlot *getPlot();
  const QCustomPlot &getPlotCstRef() const;

  void setFont(const QFont &font);
  const QFont &getFont() const;

  void setColor(const QColor color);
  const QColor &getColor() const;

  void setShouldManageLayout(bool should_manage_layout);
  bool getShouldManageLayout() const;

  void setXAxisDeltaTrigger(float x_axis_delta_trigger);
  int getXAxisDeltaTrigger() const;

  void setLabelVerticalShiftCountFactor(int label_vertical_shift_count_factor);
  int getLabelVerticalShiftCountFactor();

  void newLabel(const QString &text,
                const QPointF &data_pointf,
                bool should_replot = true);

  void showLabels();
  void hideLabels();
  void setLabelsVisible(bool visible);
  void toggleLabelsVisibility();
  void eraseLabel(qsizetype index);
  void eraseLabels();

  int size();

  const QList<TracePlotLabelQSPtr> &getLabelsCstRef();

  void writeToUpdatedDrawPoint(bool should_replot);

  private:
  QList<TracePlotLabelQSPtr> m_labels;
  QString m_name;
  QString m_plotLayerName = "labelsLayer";
  QCustomPlot *mrp_plot = nullptr;

  // Tells if the the labels in this list are to be managed
  // for detection of overlaps (see below).
  bool m_shouldManageLayout = true;

  // The distance between two labeled x-axis values below which
  // the labels will be shifted on the y-axis (see below).
  float m_xAxisDeltaTrigger;

  // Compounding factor relative to the font size. If font size
  // is 12 pixels and this factor is 2, the vertical y-axis shift
  // between labels will be 24 pixels.
  int m_labelVerticalShiftCountFactor;

  QFont m_font   = QApplication::font();
  QColor m_color = QColor("black");

  int calculateLabelVerticalShiftCount(const QPointF data_pointf);

  QPointF calculateDrawPoint(const QPointF &data_pointf,
                             int vertical_shift_count);
};

using TracePlotLabelListQSPtr = QSharedPointer<TracePlotLabelList>;


} // namespace MineXpert

} // namespace MsXpS
