// Copyright 2021 Filippo Rusconi
// GPLv3+

#pragma once

/////////////////////// StdLib includes
#include <vector>
#include <limits>

/////////////////////// Qt includes
#include <QString>
#include <QPointF>


/////////////////////// Local includes
#include "pappsomspp/export-import-config.h"
#include "../../types.h"
#include "integrationscope.h"

namespace pappso
{

// This class represents the case where the user draws a rectangle in a colormap
// plot widget, with the aim of integrating data in two-dimension manner (over a
// range in the X axis and a range in the Y axis). The rectangle is not a
// rhomboid, it has squared angles.

/* Like this:

+---------------------------+  -
|                           |  |
|                           |  |
|                           |  m_height
|                           |  |
|                           |  |
P---------------------------+  -

|--------- m_width ---------|

With P the m_point.

*/

class PMSPP_LIB_DECL IntegrationScopeRect : public IntegrationScope
{
  public:
  IntegrationScopeRect();
  IntegrationScopeRect(const QPointF &point, double width, double height);
  IntegrationScopeRect(const QPointF &point, double width, Enums::DataKind data_kind_x, double height, Enums::DataKind data_kind_y);
  IntegrationScopeRect(const IntegrationScopeRect &other);

  virtual ~IntegrationScopeRect();
  
  using IntegrationScope::operator=;
  virtual IntegrationScopeRect &operator=(const IntegrationScopeRect &other);

  virtual IntegrationScopeFeatures getTopMostPoint(QPointF &point) const override;
  virtual IntegrationScopeFeatures getBottomMostPoint(QPointF &point) const override;

  virtual void setHeight(double height);
  virtual IntegrationScopeFeatures getHeight(double &height) const override;

  virtual bool range(Enums::Axis axis, double &start, double &end) const override;

  virtual void setDataKindX(Enums::DataKind data_kind) override;
  virtual bool getDataKindX(Enums::DataKind &data_kind) override;

  virtual void setDataKindY(Enums::DataKind data_kind) override;
  virtual bool getDataKindY(Enums::DataKind &data_kind) override;
  
  bool is1D() const override;
  bool is2D() const override;
  
  virtual bool isRectangle() const override;
  virtual bool isRhomboid() const override;
  
  virtual bool transpose() override;

  using IntegrationScope::update;
  virtual void update(const QPointF &point, double width, double height);

  virtual bool contains(const QPointF &point) const override;

  virtual QString toString() const override;

  virtual void reset() override;

  protected:
  double m_height;
  Enums::DataKind m_dataKindY = Enums::DataKind::unset;
};

typedef std::shared_ptr<IntegrationScopeRect> IntegrationScopeRectSPtr;
typedef std::shared_ptr<const IntegrationScopeRect> IntegrationScopeRectCstSPtr;

} // namespace pappso
