/*=========================================================================
*
*  Copyright NumFOCUS
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*         http://www.apache.org/licenses/LICENSE-2.0.txt
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*=========================================================================*/
#ifndef sitkCurvatureAnisotropicDiffusionImageFilter_h
#define sitkCurvatureAnisotropicDiffusionImageFilter_h

/*
 * WARNING: DO NOT EDIT THIS FILE!
 * THIS FILE IS AUTOMATICALLY GENERATED BY THE SIMPLEITK BUILD PROCESS.
 * Please look at sitkImageFilterTemplate.h.in to make changes.
 */

#include <memory>

#include "sitkBasicFilters.h"
#include "sitkImageFilter.h"

namespace itk::simple {

    /**\class CurvatureAnisotropicDiffusionImageFilter
\brief This filter performs anisotropic diffusion on a scalar itk::Image using the modified curvature diffusion equation (MCDE).

For detailed information on anisotropic diffusion and the MCDE see itkAnisotropicDiffusionFunction and itkCurvatureNDAnisotropicDiffusionFunction.

\par Inputs and Outputs
The input and output to this filter must be a scalar itk::Image with numerical pixel types (float or double). A user defined type which correctly defines arithmetic operations with floating point accuracy should also give correct results.


\par Parameters
Please first read all the documentation found in AnisotropicDiffusionImageFilter and AnisotropicDiffusionFunction . Also see CurvatureNDAnisotropicDiffusionFunction .


The default time step for this filter is set to the maximum theoretically stable value: 0.5 / 2^N, where N is the dimensionality of the image. For a 2D image, this means valid time steps are below 0.1250. For a 3D image, valid time steps are below 0.0625.

\see AnisotropicDiffusionImageFilter 


\see AnisotropicDiffusionFunction 


\see CurvatureNDAnisotropicDiffusionFunction
\sa itk::simple::CurvatureAnisotropicDiffusion for the procedural interface
\sa itk::CurvatureAnisotropicDiffusionImageFilter for the Doxygen on the original ITK class.
     */
    class SITKBasicFilters_EXPORT CurvatureAnisotropicDiffusionImageFilter : public ImageFilter {
    public:
      using Self = CurvatureAnisotropicDiffusionImageFilter;

      /** Destructor */
      virtual ~CurvatureAnisotropicDiffusionImageFilter();

      /** Default Constructor that takes no arguments and initializes
       * default parameters */
      CurvatureAnisotropicDiffusionImageFilter();

      /** Define the pixels types supported by this filter */
      using PixelIDTypeList = RealPixelIDTypeList;
\

      /**
       */
      SITK_RETURN_SELF_TYPE_HEADER SetTimeStep ( double TimeStep ) { this->m_TimeStep = TimeStep; return *this; }

      /**
       */
      double GetTimeStep() const { return this->m_TimeStep; }\

      /**
       */
      SITK_RETURN_SELF_TYPE_HEADER SetConductanceParameter ( double ConductanceParameter ) { this->m_ConductanceParameter = ConductanceParameter; return *this; }

      /**
       */
      double GetConductanceParameter() const { return this->m_ConductanceParameter; }\

      /**
       */
      SITK_RETURN_SELF_TYPE_HEADER SetConductanceScalingUpdateInterval ( unsigned int ConductanceScalingUpdateInterval ) { this->m_ConductanceScalingUpdateInterval = ConductanceScalingUpdateInterval; return *this; }

      /**
       */
      unsigned int GetConductanceScalingUpdateInterval() const { return this->m_ConductanceScalingUpdateInterval; }\

      /**
       */
      SITK_RETURN_SELF_TYPE_HEADER SetNumberOfIterations ( uint32_t NumberOfIterations ) { this->m_NumberOfIterations = NumberOfIterations; return *this; }

      /**
       */
      uint32_t GetNumberOfIterations() const { return this->m_NumberOfIterations; }

      /** Name of this class */
      std::string GetName() const { return std::string ("CurvatureAnisotropicDiffusionImageFilter"); }

      /** Print ourselves out */
      std::string ToString() const;


      /** Execute the filter on the input image */
#ifndef SWIG
      Image Execute ( Image&& image1 );
#endif
      Image Execute ( const Image& image1 );


      /** This method autmatically sets the optimal timestep for an image given its spacing. */
      double EstimateOptimalTimeStep(Image & inImage );

    private:

      /** Setup for member function dispatching */

      using MemberFunctionType = Image (Self::*)( const Image& image1 );
      template <class TImageType> Image ExecuteInternal ( const Image& image1 );


      friend struct detail::MemberFunctionAddressor<MemberFunctionType>;

      std::unique_ptr<detail::MemberFunctionFactory<MemberFunctionType> > m_MemberFactory;


      /* Time step for PDE solver */
      double  m_TimeStep{0.0625};

      /* Conductance parameter governing sensitivity of the conductance equation. */
      double  m_ConductanceParameter{3.0};

      /* Interval at which a new scaling for the conductance term is calculated. */
      unsigned int  m_ConductanceScalingUpdateInterval{1u};

      /* Number of iterations to run */
      uint32_t  m_NumberOfIterations{5u};


      bool m_InPlace{false};
    };

    /**\
     * \brief This filter performs anisotropic diffusion on a scalar itk::Image using the modified curvature diffusion equation (MCDE).
     *
     * This function directly calls the execute method of CurvatureAnisotropicDiffusionImageFilter
     * in order to support a procedural API
     *
     * \sa itk::simple::CurvatureAnisotropicDiffusionImageFilter for the object oriented interface
     * @{
     */
#ifndef SWIG
     SITKBasicFilters_EXPORT Image CurvatureAnisotropicDiffusion ( Image&& image1, double timeStep = 0.0625, double conductanceParameter = 3.0, unsigned int conductanceScalingUpdateInterval = 1u, uint32_t numberOfIterations = 5u );
#endif
     SITKBasicFilters_EXPORT Image CurvatureAnisotropicDiffusion ( const Image& image1, double timeStep = 0.0625, double conductanceParameter = 3.0, unsigned int conductanceScalingUpdateInterval = 1u, uint32_t numberOfIterations = 5u );

     /** @} */
}
#endif
