//=========================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
//
//  This software is distributed WITHOUT ANY WARRANTY; without even
//  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//  PURPOSE.  See the above copyright notice for more information.
//=========================================================================
// .NAME vtkCMBTriangleMesher
// .SECTION Description
// This class will mesh a given 2 dimensional polygon and return each
// loop as a unique vtkPolyData
//
// Input: vtkPolyData
// Output: vtkMultiBlockDataSet
//
//   The input vtkPolyData must have certain properties.
//   It is assumed that all lines form closed polygons.
//   Any polygon that you want to be meshed must be stored
//   as a series of VTK_LINE's with the following properties
//
//   The input vtkPolyData needs to be processed using
//   the vtkCMBPrepareForTriangleMesher class that helps you describe
//   how the poly data will be meshed
//
//   See vtkCMBPrepareForTriangleMesher for how to format the input poly data

#ifndef __vtkCMBTriangleMultiBlockMesher_h
#define __vtkCMBTriangleMultiBlockMesher_h

#include "cmbSystemConfig.h"
#include "vtkCMBMeshingModule.h" // For export macro
#include "vtkMultiBlockDataSetAlgorithm.h"
#include <limits>
#include <map>

class VTKCMBMESHING_EXPORT vtkCMBTriangleMultiBlockMesher : public vtkMultiBlockDataSetAlgorithm
{

public:
  static vtkCMBTriangleMultiBlockMesher* New();
  vtkTypeMacro(vtkCMBTriangleMultiBlockMesher, vtkMultiBlockDataSetAlgorithm);
  void PrintSelf(ostream& os, vtkIndent indent) override;

  //For info on properties see vtkCMBTriangleMesher.h
  vtkSetMacro(UseUniqueAreas, bool);
  vtkGetMacro(UseUniqueAreas, bool);
  vtkSetMacro(PreserveBoundaries, bool); //allows triangle to insert points on boundaries
  vtkGetMacro(PreserveBoundaries, bool);
  vtkSetMacro(PreserveEdges, bool); //Adds VTK_LINES with arcIds preserved
  vtkGetMacro(PreserveEdges, bool);
  vtkSetMacro(MaxArea, double);
  vtkGetMacro(MaxArea, double);
  vtkGetMacro(ComputedMaxArea, double);
  enum MaxAreaModeOptions
  {
    NoMaxArea,
    AbsoluteArea,
    RelativeToBounds,
    RelativeToBoundsAndSegments
  };
  vtkSetClampMacro(MaxAreaMode, int, 0, 3);
  vtkGetMacro(MaxAreaMode, int);
  vtkSetMacro(VerboseOutput, bool);
  vtkGetMacro(VerboseOutput, bool);
  vtkBooleanMacro(VerboseOutput, bool);
  vtkSetMacro(UseMinAngle, bool);
  vtkGetMacro(UseMinAngle, bool);
  vtkSetClampMacro(MinAngle, double, 0, VTK_DOUBLE_MAX);
  vtkGetMacro(MinAngle, double);

protected:
  vtkCMBTriangleMultiBlockMesher();
  ~vtkCMBTriangleMultiBlockMesher() override;

  bool UseOldMesher;
  double MinAngle;
  bool UseMinAngle;
  bool PreserveBoundaries;
  bool PreserveEdges;
  double MaxArea;
  double ComputedMaxArea;
  int MaxAreaMode;
  bool UseUniqueAreas;

  //Used to configure triangle's 'V' flag
  bool VerboseOutput;

  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
  int FillInputPortInformation(int port, vtkInformation* info) override;

private:
  vtkCMBTriangleMultiBlockMesher(const vtkCMBTriangleMultiBlockMesher&); // Not implemented.
  void operator=(const vtkCMBTriangleMultiBlockMesher&);                 // Not implemented.
};

#endif
