/*=========================================================================
*
*  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 sitkZeroFluxNeumannPadImageFilter_h
#define sitkZeroFluxNeumannPadImageFilter_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 ZeroFluxNeumannPadImageFilter
\brief Increase the image size by padding according to the zero-flux Neumann boundary condition.

A filter which extends the image size and fill the missing pixels according to a Neumann boundary condition where first, upwind derivatives on the boundary are zero. This is a useful condition in solving some classes of differential equations.

For example, invoking this filter on an image with a corner like: \code
* * * * * *

* * * * * *

* 1 2 3 4 5 (where * denotes pixels that lie

* 3 3 5 5 6 outside of the image boundary)

* 4 4 6 7 8

\endcode
 returns the following padded image: \code
1 1 1 2 3 4 5

1 1 1 2 3 4 5

1 1 1 2 3 4 5

3 3 3 3 5 5 6 (note the corner values)

4 4 4 4 6 7 8

\endcode


\author Gaetan Lehmann. Biologie du Developpement et de la Reproduction, INRA de Jouy-en-Josas, France.


\see WrapPadImageFilter , MirrorPadImageFilter , ConstantPadImageFilter , ZeroFluxNeumannBoundaryCondition
\sa itk::simple::ZeroFluxNeumannPad for the procedural interface
\sa itk::ZeroFluxNeumannPadImageFilter for the Doxygen on the original ITK class.
     */
    class SITKBasicFilters_EXPORT ZeroFluxNeumannPadImageFilter : public ImageFilter {
    public:
      using Self = ZeroFluxNeumannPadImageFilter;

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

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

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

      /**
       */
      SITK_RETURN_SELF_TYPE_HEADER SetPadLowerBound ( std::vector<unsigned int> PadLowerBound ) { this->m_PadLowerBound = std::move(PadLowerBound); return *this; }

      /**
       */
      std::vector<unsigned int> GetPadLowerBound() const { return this->m_PadLowerBound; }\

      /**
       */
      SITK_RETURN_SELF_TYPE_HEADER SetPadUpperBound ( std::vector<unsigned int> PadUpperBound ) { this->m_PadUpperBound = std::move(PadUpperBound); return *this; }

      /**
       */
      std::vector<unsigned int> GetPadUpperBound() const { return this->m_PadUpperBound; }

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

      /** 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;


      std::vector<unsigned int>  m_PadLowerBound{std::vector<unsigned int>(3, 0)};

      std::vector<unsigned int>  m_PadUpperBound{std::vector<unsigned int>(3, 0)};


    };

    /**\
     * \brief Increase the image size by padding according to the zero-flux Neumann boundary condition.
     *
     * This function directly calls the execute method of ZeroFluxNeumannPadImageFilter
     * in order to support a procedural API
     *
     * \sa itk::simple::ZeroFluxNeumannPadImageFilter for the object oriented interface
     * @{
     */

     SITKBasicFilters_EXPORT Image ZeroFluxNeumannPad ( const Image& image1, std::vector<unsigned int> padLowerBound = std::vector<unsigned int>(3, 0), std::vector<unsigned int> padUpperBound = std::vector<unsigned int>(3, 0) );

     /** @} */
}
#endif
