/*=========================================================================
*
*  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 sitkTileImageFilter_h
#define sitkTileImageFilter_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 TileImageFilter

\brief Tile multiple input images into a single output image.

This filter will tile multiple images using a user-specified layout. The tile sizes will be large enough to accommodate the largest image for each tile. The layout is specified with the SetLayout method. The layout has the same dimension as the output image. If all entries of the layout are positive, the tiled output will contain the exact number of tiles. If the layout contains a 0 in the last dimension, the filter will compute a size that will accommodate all of the images. Empty tiles are filled with the value specified with the SetDefault value method. The input images must have a dimension less than or equal to the output image. The output image have a larger dimension than the input images. This filter can be used to create a volume from a series of inputs by specifying a layout of 1,1,0.

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

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


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

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


\

      /**
       * Set/Get the layout of the tiles. If the last Layout value is 0, the filter will compute a value that will accommodate all of the images.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetLayout ( std::vector<uint32_t> Layout ) { this->m_Layout = std::move(Layout); return *this; }

      /**
       * Set/Get the layout of the tiles. If the last Layout value is 0, the filter will compute a value that will accommodate all of the images.
       */
      std::vector<uint32_t> GetLayout() const { return this->m_Layout; }\

      /**
       * Set the pixel value for locations that are not covered by an input image. The default default pixel value is Zero.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetDefaultPixelValue ( double DefaultPixelValue ) { this->m_DefaultPixelValue = DefaultPixelValue; return *this; }

      /**
       * Get the pixel value for locations that are not covered by an input image.
       */
      double GetDefaultPixelValue() const { return this->m_DefaultPixelValue; }

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

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


      std::vector<uint32_t>  m_Layout{std::vector<uint32_t>(3, 100)};

      double  m_DefaultPixelValue{0.0};


    };


    /**
     * \brief Tile multiple input images into a single output image.
     *
     * This function directly calls the execute method of TileImageFilter
     * in order to support a procedural API
     *
     * \sa itk::simple::TileImageFilter for the object oriented interface
     * @{
     */
     SITKBasicFilters_EXPORT Image Tile ( const std::vector<Image> &images , std::vector<uint32_t> layout = std::vector<uint32_t>(3, 100), double defaultPixelValue = 0.0 );

     SITKBasicFilters_EXPORT Image Tile ( const Image& image1, std::vector<uint32_t> layout = std::vector<uint32_t>(3, 100), double defaultPixelValue = 0.0 );
     SITKBasicFilters_EXPORT Image Tile ( const Image& image1, const Image& image2, std::vector<uint32_t> layout = std::vector<uint32_t>(3, 100), double defaultPixelValue = 0.0 );
     SITKBasicFilters_EXPORT Image Tile ( const Image& image1, const Image& image2, const Image& image3, std::vector<uint32_t> layout = std::vector<uint32_t>(3, 100), double defaultPixelValue = 0.0 );
     SITKBasicFilters_EXPORT Image Tile ( const Image& image1, const Image& image2, const Image& image3, const Image& image4, std::vector<uint32_t> layout = std::vector<uint32_t>(3, 100), double defaultPixelValue = 0.0 );
     SITKBasicFilters_EXPORT Image Tile ( const Image& image1, const Image& image2, const Image& image3, const Image& image4, const Image& image5, std::vector<uint32_t> layout = std::vector<uint32_t>(3, 100), double defaultPixelValue = 0.0 );

     /** @{ */

}
#endif
