/*=========================================================================
*
*  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 sitkNaryAddImageFilter_h
#define sitkNaryAddImageFilter_h

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

#include <memory>

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

namespace itk::simple {

   /**\class NaryAddImageFilter

\brief Pixel-wise addition of N images.

This class is templated over the types of the input images and the type of the output image. Numeric conversions (castings) are done by the C++ defaults.

The pixel type of the input images must have a valid definition of the operator+ with each other. This condition is required because internally this filter will perform the operation

\code
pixel_from_image_N + pixel_from_image_(N+1)

\endcode


Additionally the type resulting from the sum, will be cast to the pixel type of the output image.

The total operation over one pixel will be

\code
output_pixel = static_cast<OutputPixelType>( input_pixel_N + input_pixel_(N+1) )

\endcode


For example, this filter could be used directly for adding images whose pixels are vectors of the same dimension, and to store the resulting vector in an output image of vector pixels.

\warning No numeric overflow checking is performed in this filter.

\sa itk::simple::NaryAdd for the procedural interface
   */
    class SITKBasicFilters_EXPORT NaryAddImageFilter
      : public ImageFilter
    {
    public:
      using Self = NaryAddImageFilter;

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


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

      /** Define the pixels types supported by this filter */
      using PixelIDTypeList = typelist2::append<BasicPixelIDTypeList, ComplexPixelIDTypeList>::type;




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

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

      /** Execute the filter on the input images */
      Image Execute ( const std::vector<Image> &images);
      Image Execute ( const Image& image1 );
      Image Execute ( const Image& image1, const Image& image2 );
      Image Execute ( const Image& image1, const Image& image2, const Image& image3 );
      Image Execute ( const Image& image1, const Image& image2, const Image& image3, const Image& image4 );
      Image Execute ( const Image& image1, const Image& image2, const Image& image3, const Image& image4, const Image& image5 );




    private:

      /** Setup for member function dispatching */

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



      friend struct detail::MemberFunctionAddressor<MemberFunctionType>;

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



      bool m_InPlace{false};
    };


    /**
     * \brief Pixel-wise addition of N images.
     *
     * This function directly calls the execute method of NaryAddImageFilter
     * in order to support a procedural API
     *
     * \sa itk::simple::NaryAddImageFilter for the object oriented interface
     * @{
     */
     SITKBasicFilters_EXPORT Image NaryAdd ( const std::vector<Image> &images  );

     SITKBasicFilters_EXPORT Image NaryAdd ( const Image& image1 );
     SITKBasicFilters_EXPORT Image NaryAdd ( const Image& image1, const Image& image2 );
     SITKBasicFilters_EXPORT Image NaryAdd ( const Image& image1, const Image& image2, const Image& image3 );
     SITKBasicFilters_EXPORT Image NaryAdd ( const Image& image1, const Image& image2, const Image& image3, const Image& image4 );
     SITKBasicFilters_EXPORT Image NaryAdd ( const Image& image1, const Image& image2, const Image& image3, const Image& image4, const Image& image5 );

     /** @{ */

}
#endif
