/*============================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/

#ifndef itkMultiHistogramFilter_h
#define itkMultiHistogramFilter_h

#include <itkImageToImageFilter.h>

namespace itk
{
  /**
   * \brief Computes a multi-bin local histogram for each voxel.
   *
   * For each voxel, a local histogram is computed within a neighbourhood of configurable
   * size. The histogram bin counts are output as separate images, one per bin.
   *
   * \tparam TInputImageType The input image type.
   * \tparam TOuputImageType The output image type.
   */
  template<typename TInputImageType, typename TOuputImageType >
  class MultiHistogramFilter : public ImageToImageFilter< TInputImageType, TOuputImageType>
  {
    public:
      typedef MultiHistogramFilter                                    Self;
      typedef ImageToImageFilter< TInputImageType, TOuputImageType >  Superclass;
      typedef SmartPointer< Self >                                    Pointer;
      typedef typename TInputImageType::ConstPointer                       InputImagePointer;
      typedef typename TOuputImageType::Pointer                       OutputImagePointer;
      typedef typename TOuputImageType::RegionType                    OutputImageRegionType;

      itkNewMacro (Self);
      itkTypeMacro(MultiHistogramFilter, ImageToImageFilter);

      itkSetMacro(Delta, double);
      itkGetConstMacro(Delta, double);

      itkSetMacro(Offset, double);
      itkGetConstMacro(Offset, double);

      itkSetMacro(Bins, int);
      itkGetConstMacro(Bins, int);

      itkSetMacro(Size, int);
      itkGetConstMacro(Size, int);

      itkSetMacro(UseImageIntensityRange, bool);
      itkGetConstMacro(UseImageIntensityRange, bool);

    protected:
      MultiHistogramFilter();
      ~MultiHistogramFilter() override{};

      void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, ThreadIdType threadId) override;
      void BeforeThreadedGenerateData(void) override;


      using itk::ProcessObject::MakeOutput;
      itk::ProcessObject::DataObjectPointer MakeOutput(itk::ProcessObject::DataObjectPointerArraySizeType /*idx*/) override;

      void CreateOutputImage(InputImagePointer input, OutputImagePointer output);

    private:
      MultiHistogramFilter(const Self &); // purposely not implemented
      void operator=(const Self &); // purposely not implemented

      double m_Delta;
      double m_Offset;
      int m_Bins;
      int m_Size;
      bool m_UseImageIntensityRange;
  };
}

#ifndef ITK_MANUAL_INSTANTIATION
#include <itkMultiHistogramFilter.cpp>
#endif

#endif // itkMultiHistogramFilter_h
