/*=========================================================================
*
*  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 sitkReinitializeLevelSetImageFilter_h
#define sitkReinitializeLevelSetImageFilter_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 ReinitializeLevelSetImageFilter
\brief Reinitialize the level set to the signed distance function.

ReinitializeLevelSetImageFilter reinitializes the input level set to the approximated signed distance function from a particular level set. The output is a level set of the same type as the input.

For some level set algorithms, it is useful to periodically reinitialize the level set function to prevent numerical accuracy problems in computing derivatives and curvature values where level sets are densely bunched together.

This class is templated over the image type which represents the level set.

This class supports narrowbanding. If the input narrowband is provided, the algorithm will only locate the level set within the input narrowband. For the output, the reinitialize level set is only valid for a distance of OutputNarrowBandwidth / 2 of either side of the level set of interest.

Implementation of this class is based on Chapter 11 of "Level Set Methods and Fast Marching Methods", J.A. Sethian, Cambridge Press, Second edition, 1999.
\sa itk::simple::ReinitializeLevelSet for the procedural interface
\sa itk::ReinitializeLevelSetImageFilter for the Doxygen on the original ITK class.
     */
    class SITKBasicFilters_EXPORT ReinitializeLevelSetImageFilter : public ImageFilter {
    public:
      using Self = ReinitializeLevelSetImageFilter;

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

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

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

      /**
       * Set/Get the value of the level set to be located. The default value is 0.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetLevelSetValue ( double LevelSetValue ) { this->m_LevelSetValue = LevelSetValue; return *this; }

      /**
       * Set/Get the value of the level set to be located. The default value is 0.
       */
      double GetLevelSetValue() const { return this->m_LevelSetValue; }\

      /**
       * Set/Get the narrowbanding flag. By default, narrowbanding is switched off.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetNarrowBanding ( bool NarrowBanding ) { this->m_NarrowBanding = NarrowBanding; return *this; }

      /** Set the value of NarrowBanding to true or false respectfully. */
      SITK_RETURN_SELF_TYPE_HEADER NarrowBandingOn() { return this->SetNarrowBanding(true); }
      SITK_RETURN_SELF_TYPE_HEADER NarrowBandingOff() { return this->SetNarrowBanding(false); }

      /**
       * Set/Get the narrowbanding flag. By default, narrowbanding is switched off.
       */
      bool GetNarrowBanding() const { return this->m_NarrowBanding; }\

      /**
       * Set/Get the input narrow bandwidth. The default value is 12.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetInputNarrowBandwidth ( double InputNarrowBandwidth ) { this->m_InputNarrowBandwidth = InputNarrowBandwidth; return *this; }

      /**
       * Set/Get the input narrow bandwidth. The default value is 12.
       */
      double GetInputNarrowBandwidth() const { return this->m_InputNarrowBandwidth; }\

      /**
       * Set/Get the output narrow bandwidth. The default value is 12.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetOutputNarrowBandwidth ( double OutputNarrowBandwidth ) { this->m_OutputNarrowBandwidth = OutputNarrowBandwidth; return *this; }

      /**
       * Set/Get the output narrow bandwidth. The default value is 12.
       */
      double GetOutputNarrowBandwidth() const { return this->m_OutputNarrowBandwidth; }

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

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


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

      Image Execute ( const Image& image1 );


      /** Set the bandwidth for both the input and output narrowband, By default, both the input and output are set to 12. */
      void NarrowBandwidth(double value );

    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;


      /* Set/Get the value of the level set to be located. The default value is 0. */
      double  m_LevelSetValue{0.0};

      /* Set/Get the narrowbanding flag. By default, narrowbanding is switched off. */
      bool  m_NarrowBanding{false};

      /* Set/Get the input narrow bandwidth. The default value is 12. */
      double  m_InputNarrowBandwidth{12.0};

      /* Set/Get the output narrow bandwidth. The default value is 12. */
      double  m_OutputNarrowBandwidth{12.0};



    };

    /**\
     * \brief Reinitialize the level set to the signed distance function.
     *
     * This function directly calls the execute method of ReinitializeLevelSetImageFilter
     * in order to support a procedural API
     *
     * \sa itk::simple::ReinitializeLevelSetImageFilter for the object oriented interface
     * @{
     */

     SITKBasicFilters_EXPORT Image ReinitializeLevelSet ( const Image& image1, double levelSetValue = 0.0, bool narrowBanding = false, double inputNarrowBandwidth = 12.0, double outputNarrowBandwidth = 12.0 );

     /** @} */
}
#endif
