/// \ingroup vtk
/// \class ttkStableManifoldPersistence
/// \author Julien Tierny <julien.tierny@sorbonne-universite.fr>
/// \date June 2021
///
/// \brief TTK VTK-filter for attaching to an input stable manifold (given by
/// the Morse-Smale complex module) its persistence (given by the persistence
/// diagram).
///
/// Given an input stable manifold (1D, 2D or 3D) computed by the Morse-Smale
/// complex, this module attaches to it the persistence (and the type) of the
/// persistence pair of the critical point it is based on (i.e. the critical
/// point where the integral lines of the manifold terminate). The inputs of
/// this filter correspond to outputs of the Morse-Smale complex and
/// Persistence diagram modules (which need to be pre-exist in the analysis
/// pipeline).
///
/// \param Input0 Stable manifold (1D, 2D or 3D, vtkDataSet generated by the
/// Morse-Smale complex module).
/// \param Input1 Critical points (vtkPolyData generated by the Morse-Smale
/// complex module)
/// \param Input2 Persistence diagram (vtkUnstructuredGrid generated by the
/// Persistence diagram module)
/// \param Output Stable manifold with persistence and pair type.
///
/// This filter can be used as any other VTK filter (for instance, by using the
/// sequence of calls SetInputData(), Update(), GetOutput()).
///
/// See the related ParaView example state files for usage examples within a
/// VTK pipeline.
///
/// \sa ttkMorseSmaleComplex
/// \sa ttkPersistenceDiagram

#pragma once

// VTK Module
#include <ttkStableManifoldPersistenceModule.h>

// ttk code includes
#include <ttkAlgorithm.h>

class vtkDataArray;
class vtkPolyData;
class vtkUnstructuredGrid;

class TTKSTABLEMANIFOLDPERSISTENCE_EXPORT ttkStableManifoldPersistence
  : public ttkAlgorithm {

public:
  static ttkStableManifoldPersistence *New();
  vtkTypeMacro(ttkStableManifoldPersistence, ttkAlgorithm);

  vtkGetMacro(IsUnstable, bool);
  vtkSetMacro(IsUnstable, bool);

protected:
  ttkStableManifoldPersistence();

  int FillInputPortInformation(int port, vtkInformation *info) override;
  int FillOutputPortInformation(int port, vtkInformation *info) override;
  int RequestData(vtkInformation *request,
                  vtkInformationVector **inputVector,
                  vtkInformationVector *outputVector) override;

private:
  bool IsUnstable{false};

  std::vector<int> max2simplex_, min2simplex_;
  std::vector<double> simplex2persistence_;
  std::vector<int> simplex2pairType_;

  int AttachPersistence(vtkDataSet *output) const;

  int BuildSimplex2PersistenceMap(vtkDataSet *stableManifold,
                                  vtkPolyData *criticalPoints,
                                  vtkUnstructuredGrid *persistenceDiagram);
};
