/*=========================================================================
*
*  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 sitkGrayscaleGeodesicErodeImageFilter_h
#define sitkGrayscaleGeodesicErodeImageFilter_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 GrayscaleGeodesicErodeImageFilter
\brief geodesic gray scale erosion of an image

Geodesic erosion operates on a "marker" image and a "mask" image. The marker image is eroded using an elementary structuring element (neighborhood of radius one using only the face connected neighbors). The resulting image is then compared with the mask image. The output image is the pixelwise maximum of the eroded marker image and the mask image.

Geodesic erosion is run either one iteration or until convergence. In the convergence case, the filter is equivalent to "reconstruction by erosion". This filter is implemented to handle both scenarios. The one iteration case is multi-threaded. The convergence case is delegated to another instance of the same filter (but configured to run a single iteration).

The marker image must be greater than or equal to the mask image (on a pixel by pixel basis).

Geodesic morphology is described in Chapter 6 of Pierre Soille's book "Morphological Image Analysis: Principles and Applications", Second Edition, Springer, 2003.

A noniterative version of this algorithm can be found in the ReconstructionByErosionImageFilter . This noniterative solution is much faster than the implementation provided here. All ITK filters that previously used GrayscaleGeodesicErodeImageFilter as part of their implementation have been converted to use the ReconstructionByErosionImageFilter . The GrayscaleGeodesicErodeImageFilter is maintained for backward compatibility.

\see MorphologyImageFilter , GrayscaleErodeImageFilter , GrayscaleFunctionErodeImageFilter , BinaryErodeImageFilter , ReconstructionByErosionImageFilter
\sa itk::simple::GrayscaleGeodesicErode for the procedural interface
\sa itk::GrayscaleGeodesicErodeImageFilter for the Doxygen on the original ITK class.
     */
    class SITKBasicFilters_EXPORT GrayscaleGeodesicErodeImageFilter : public ImageFilter {
    public:
      using Self = GrayscaleGeodesicErodeImageFilter;

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

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

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

      /**
       * Set/Get whether the filter should run one iteration or until convergence. When run to convergence, this filter is equivalent to "reconstruction by erosion". Default is off.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetRunOneIteration ( bool RunOneIteration ) { this->m_RunOneIteration = RunOneIteration; return *this; }

      /** Set the value of RunOneIteration to true or false respectfully. */
      SITK_RETURN_SELF_TYPE_HEADER RunOneIterationOn() { return this->SetRunOneIteration(true); }
      SITK_RETURN_SELF_TYPE_HEADER RunOneIterationOff() { return this->SetRunOneIteration(false); }

      /**
       * Set/Get whether the filter should run one iteration or until convergence. When run to convergence, this filter is equivalent to "reconstruction by erosion". Default is off.
       */
      bool GetRunOneIteration() const { return this->m_RunOneIteration; }\

      /**
       * Set/Get whether the connected components are defined strictly by face connectivity or by face+edge+vertex connectivity. Default is FullyConnectedOff. For objects that are 1 pixel wide, use FullyConnectedOn.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetFullyConnected ( bool FullyConnected ) { this->m_FullyConnected = FullyConnected; return *this; }

      /** Set the value of FullyConnected to true or false respectfully. */
      SITK_RETURN_SELF_TYPE_HEADER FullyConnectedOn() { return this->SetFullyConnected(true); }
      SITK_RETURN_SELF_TYPE_HEADER FullyConnectedOff() { return this->SetFullyConnected(false); }

      /**
       * Set/Get whether the connected components are defined strictly by face connectivity or by face+edge+vertex connectivity. Default is FullyConnectedOff. For objects that are 1 pixel wide, use FullyConnectedOn.
       */
      bool GetFullyConnected() const { return this->m_FullyConnected; }

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

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


      /** Execute the filter on the input images */

      Image Execute ( const Image& image1, const Image& image2 );

    private:

      /** Setup for member function dispatching */

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


      friend struct detail::MemberFunctionAddressor<MemberFunctionType>;

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


      /*  */
      bool  m_RunOneIteration{false};

      /*  */
      bool  m_FullyConnected{false};


    };

    /**\
     * \brief geodesic gray scale erosion of an image
     *
     * This function directly calls the execute method of GrayscaleGeodesicErodeImageFilter
     * in order to support a procedural API
     *
     * \sa itk::simple::GrayscaleGeodesicErodeImageFilter for the object oriented interface
     * @{
     */

     SITKBasicFilters_EXPORT Image GrayscaleGeodesicErode ( const Image& image1, const Image& image2, bool runOneIteration = false, bool fullyConnected = false );

     /** @} */
}
#endif
