/*=========================================================================
*
*  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 sitkInvertDisplacementFieldImageFilter_h
#define sitkInvertDisplacementFieldImageFilter_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 InvertDisplacementFieldImageFilter
\brief Iteratively estimate the inverse field of a displacement field.

\author Nick Tustison 


\author Brian Avants
\sa itk::simple::InvertDisplacementField for the procedural interface
\sa itk::InvertDisplacementFieldImageFilter for the Doxygen on the original ITK class.
     */
    class SITKBasicFilters_EXPORT InvertDisplacementFieldImageFilter : public ImageFilter {
    public:
      using Self = InvertDisplacementFieldImageFilter;

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

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

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

      /**
       */
      SITK_RETURN_SELF_TYPE_HEADER SetMaximumNumberOfIterations ( uint32_t MaximumNumberOfIterations ) { this->m_MaximumNumberOfIterations = MaximumNumberOfIterations; return *this; }

      /**
       */
      uint32_t GetMaximumNumberOfIterations() const { return this->m_MaximumNumberOfIterations; }\

      /**
       */
      SITK_RETURN_SELF_TYPE_HEADER SetMaxErrorToleranceThreshold ( double MaxErrorToleranceThreshold ) { this->m_MaxErrorToleranceThreshold = MaxErrorToleranceThreshold; return *this; }

      /**
       */
      double GetMaxErrorToleranceThreshold() const { return this->m_MaxErrorToleranceThreshold; }\

      /**
       */
      SITK_RETURN_SELF_TYPE_HEADER SetMeanErrorToleranceThreshold ( double MeanErrorToleranceThreshold ) { this->m_MeanErrorToleranceThreshold = MeanErrorToleranceThreshold; return *this; }

      /**
       */
      double GetMeanErrorToleranceThreshold() const { return this->m_MeanErrorToleranceThreshold; }\

      /**
       */
      SITK_RETURN_SELF_TYPE_HEADER SetEnforceBoundaryCondition ( bool EnforceBoundaryCondition ) { this->m_EnforceBoundaryCondition = EnforceBoundaryCondition; return *this; }

      /** Set the value of EnforceBoundaryCondition to true or false respectfully. */
      SITK_RETURN_SELF_TYPE_HEADER EnforceBoundaryConditionOn() { return this->SetEnforceBoundaryCondition(true); }
      SITK_RETURN_SELF_TYPE_HEADER EnforceBoundaryConditionOff() { return this->SetEnforceBoundaryCondition(false); }

      /**
       */
      bool GetEnforceBoundaryCondition() const { return this->m_EnforceBoundaryCondition; }
     /**
      *
      *
      * This is a measurement. Its value is updated in the Execute
      * methods, so the value will only be valid after an execution.
      */
     double GetMaxErrorNorm() const { return this->m_MaxErrorNorm; };

     /**
      *
      *
      * This is a measurement. Its value is updated in the Execute
      * methods, so the value will only be valid after an execution.
      */
     double GetMeanErrorNorm() const { return this->m_MeanErrorNorm; };


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

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


      /** Execute the filter on the input image */

      Image Execute ( const Image& image1 );

    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;


      /* Number of iterations to run */
      uint32_t  m_MaximumNumberOfIterations{10u};

      double  m_MaxErrorToleranceThreshold{0.1};

      double  m_MeanErrorToleranceThreshold{0.001};

      bool  m_EnforceBoundaryCondition{true};


      double m_MaxErrorNorm{0.0};

      double m_MeanErrorNorm{0.0};


    };

    /**\
     * \brief Iteratively estimate the inverse field of a displacement field.
     *
     * This function directly calls the execute method of InvertDisplacementFieldImageFilter
     * in order to support a procedural API
     *
     * \sa itk::simple::InvertDisplacementFieldImageFilter for the object oriented interface
     * @{
     */

     SITKBasicFilters_EXPORT Image InvertDisplacementField ( const Image& image1, uint32_t maximumNumberOfIterations = 10u, double maxErrorToleranceThreshold = 0.1, double meanErrorToleranceThreshold = 0.001, bool enforceBoundaryCondition = true );

     /** @} */
}
#endif
