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

#ifndef TOMOPROCESS_FILTER_MAXIMA_FILTER_HPP
#define TOMOPROCESS_FILTER_MAXIMA_FILTER_HPP

#include "filter.hpp"
#include "detail/maxima_filter.hpp"

TOMOPROCESS_OPEN_GLOBAL_NAMESPACE
TOMOPROCESS_OPEN_FILTER_NAMESPACE

/** \class MaximaFilter
  * \brief Find and select local maxima into an image.
  */
template< class ImageT>
class MaximaFilter
  : public Filter<
      itk::MaximaFilter<
        typename ImageT::InputImageType,
	typename ImageT::OutputImageType>,
      ImageT>
{
public:
  /// \brief This type.
  typedef MaximaFilter	Self;
  
  /// \brief Parent class.
  typedef Filter<
    itk::MaximaFilter<
      typename ImageT::InputImageType,
      typename ImageT::OutputImageType>,
    ImageT> SuperClass;
  
  /// \brief Image type.
  typedef ImageT ImageType;
  
  /// \brief Pixel type.
  typedef typename ImageType::OutputPixelType PixelType;
  
  /// \brief Maxima informations container type.
  typedef typename SuperClass::ITKFilterType::MaximaInformationsContainerType
    MaximaInformationsContainerType;
  
  /// \brief Clears filter data.
  virtual void ClearData()
  { this->m_Filter->ClearData(); }
  
  /// \brief Gets the informations on the maxima.
  /// \return Vector of maxima informations structures.
  virtual MaximaInformationsContainerType* GetMaximaInformations()
  { return this->m_Filter->GetMaximaInformations(); }
  
  /// \brief Sets parameters.
  /// \param[in] foreground sets the value in the output image to consider as "foreground".
  /// \param[in] background1 sets the value in the output image to consider as "background".
  /// \param[in] background2 sets the value in the output image to consider as cell walls.
  /// \param[in] radius sets the radius of the considered neighborhood.
  /// \param[in] sigma value of scale for the derivative operator.
  /// \param[in] eigenTol tolerance factor for maxima selections.
  /// \param[in] maximumError maximum error for gaussian kernel calculation (usually 0.02 or less).
  /// \param[in] plateauTol two neighbors pixels with intensity difference less than PlateauTol are considered to be part of the same plateau.
  /// \param[in] useImageSpacing sets if we use the image spacing into the computations.
  /// \param[in] draw tells the filter if it has to draw into the output image.
  virtual void SetParameters(PixelType foreground, PixelType background1, PixelType background2,
			     unsigned int radius, double sigma = 1.0, double eigenTol = 1.0e-1, double maximumError = 2.0e-2,
			     double plateauTol = 1.0e-5, bool useImageSpacing = false, bool draw = false)
  {
    this->m_Filter->SetForeground(foreground);
    this->m_Filter->SetBackground1(background1);
    this->m_Filter->SetBackground2(background2);
    this->m_Filter->SetRadius(radius);
    this->m_Filter->SetSigma(sigma);
    this->m_Filter->SetEigenTol(eigenTol);
    this->m_Filter->SetMaximumError(maximumError);
    this->m_Filter->SetPlateauTol(plateauTol);
    this->m_Filter->SetUseImageSpacing(useImageSpacing);
    
    SuperClass::SetDraw(draw);
    this->m_Filter->SetDraw(draw);
  }
};

TOMOPROCESS_CLOSE_FILTER_NAMESPACE
TOMOPROCESS_CLOSE_GLOBAL_NAMESPACE

#endif // TOMOPROCESS_FILTER_MAXIMA_FILTER_HPP