/**============================================================================
 *
 * \file   streaming_filter.hpp
 * \brief  Declarations for the StrealingFilter class.
 *
 * \author Leblanc Christophe.
 * \date   07/12/2012
 * \email cleblancad@gmail.com
 *
 * Code inspired from:
 * 'Getting Started with ITK + VTK'
 * L. Ibanez, W. Schroeder, Insight Software Consortium.
 *
 *===========================================================================*/

#ifndef TOMOPROCESS_FILTER_STREAMING_FILTER_HPP
#define TOMOPROCESS_FILTER_STREAMING_FILTER_HPP

#include "filter.hpp"
#include "detail/streaming_filter.hpp"
#include "detail/image_region_splitter_for_maurer.hpp"

TOMOPROCESS_OPEN_GLOBAL_NAMESPACE
TOMOPROCESS_OPEN_FILTER_NAMESPACE

/** \class StreamingFilter.
 * \brief Cuts in pieces an image.
 */
template<class ImageT>
class StreamingFilter
  : public Filter<
      itk::StreamingFilter<
        typename ImageT::InputImageType,
	typename ImageT::OutputImageType>,
      ImageT>
{
public:
  /// \brief This class.
  typedef StreamingFilter Self;
  
  /// \brief Parent class.
  typedef Filter<
    itk::StreamingFilter<
      typename ImageT::InputImageType,
      typename ImageT::OutputImageType>,
    ImageT> SuperClass;
  
  /// \brief Image type.
  typedef ImageT 	ImageType;
  
  /// \brief Image region splitter type.
  typedef itk::ImageRegionSplitterForMaurer<
    ImageType::InputImageType::ImageDimension>	SplitterType;
    
  /// \brief Splitter pointer type.
  typedef typename SplitterType::Pointer 	SplitterPtrType;
  
  /// \brief Splitter constant pointer type.
  typedef typename SplitterType::ConstPointer	SplitterConstPtrType;
  
  /// \brief Image informations container type.
  typedef typename SuperClass::ITKFilterType::ImageInformationsContainerType
    ImageInformationsContainerType;
    
  /// \brief Get list of informations about images.
  /// \return Informations.
  inline const ImageInformationsContainerType* GetImageInformations() const
  { return this->m_Filter->GetImageInformations(); }
  
  /// \brief Sets the parameters.
  /// \param[in] numberOfStreamDivisions sets the number of pieces to divide the input. The upstream pipeline will be executed this many times.
  /// \param[in] createTemporaryFiles creates temporary files for each streaming slice.
  /// \param[in] removeTemporaryFiles removes the created temporary files.
  /// \param[in] os output stream for error messages.
  virtual void SetParameters(unsigned int numberOfStreamDivisions = 1, 
			     bool createTemporaryFiles = true,
			     bool removeTemporaryFiles = true,
			     std::ostream &os = std::cerr)
  {
    m_Splitter = SplitterType::New();
    m_Splitter->SetErrorStream(os);
    
    this->m_Filter->SetNumberOfStreamDivisions(numberOfStreamDivisions);
    this->m_Filter->SetRegionSplitter(m_Splitter);
    this->m_Filter->SetErrorStream(os);
    
    // Check temporary files parameters.
    if(removeTemporaryFiles && !createTemporaryFiles) removeTemporaryFiles = false;
    
    this->m_Filter->SetCreateTemporaryFiles(createTemporaryFiles);
    this->m_Filter->SetRemoveTemporaryFiles(removeTemporaryFiles);
  }
  
protected:
  /// \brief Image region splitter.
  SplitterPtrType m_Splitter;
};

TOMOPROCESS_CLOSE_FILTER_NAMESPACE
TOMOPROCESS_CLOSE_FILTER_NAMESPACE

#endif // TOMOPROCESS_FILTER_STREAMING_FILTER_HPP