#ifndef RANGECUDABILATERALIMAGEFILTER_H__
#define RANGECUDABILATERALIMAGEFILTER_H__

#include "ritkRImageFilterWrapper.h"
#include "CUDABilateralImageFilter.h"

/**	@class	RangeCUDABilateralImageFilter
 *	@author	Jakob Wasza
 *	@brief	range wrapper class for the CUDABilateralImageFilter
 *	
 *	@details
 *	This is a range filter wrapper class for the CUDABilateralImageFilter
 *	\sa CUDABilateralImageFilter
 */
template <class TRImage>
class RangeCUDABilateralImageFilter : public ritk::RImageFilterWrapper<TRImage>
{
public:
	/** @name	Typedefs */
	//@{

	/** @name	Standard typedefs */
	//@{
	typedef RangeCUDABilateralImageFilter			Self;
	typedef ritk::RImageFilterWrapper<TRImage>		Superclass;
	typedef itk::SmartPointer<Self>					Pointer;
	typedef itk::SmartPointer<const Self>			ConstPointer;
	//@}

	/**	@name	Input and output typedefs */
	//@{
	typedef typename Superclass::InputImageType		InputImageType;
	typedef typename InputImageType::Pointer		InputImagePointer;
	typedef typename InputImageType::ConstPointer	InputImageConstPointer;
	typedef typename Superclass::OutputImageType	OutputImageType;
	typedef typename OutputImageType::Pointer		OutputImagePointer;
	//@}

	//@}

	/// Object creation
	itkNewMacro(Self);

	/// RTTI
	itkTypeMacro(RangeCUDABilateralImageFilter, RImageFilterWrapper);

	/**	@name Range parameters */
	//@{
	/// Set the kernel size of the range gaussian (spatial as well as range)
	void SetRangeKernelSize(int size);
	/// Set the spatial (domain) spread in pixels
	void SetRangeSigmaSpatial(float SpatialSigma);
	/// Set the range spreak in mm
	void SetRangeSigmaRange(float RangeSigma);
	/// Get the geometric spread parameter
	float GetRangeSigmaSpatial();
	/// Get the photometric spread parameter
	float GetRangeSigmaRange();
	//@}


protected:
	/// Constructor
	RangeCUDABilateralImageFilter();
	/// Destructor
	~RangeCUDABilateralImageFilter();

	/// Filtering routine
	void DoFiltering();

protected:
	/** @name range filtering */
	//@{
	/// The kernel size (radius) of the range gaussian
	int m_RangeKernelSize;
	/// The geometric spread parameter for the range image
	float m_RangeSigmaSpatial;
	/// The range spread parameter for the range image
	float m_RangeSigmaRange;
	//@}
	


	/**	@name Typedefs for the filters */
	//@{
	typedef CUDABilateralImageFilter<typename InputImageType::RangeImageType,typename OutputImageType::RangeImageType>  RangeFilterType;
	typedef typename RangeFilterType::Pointer RangeFilterPointer;
	RangeFilterPointer m_RangeFilter;
	//@}

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

#include "RangeCUDABilateralImageFilter.txx"


#endif // RANGECUDABILATERALIMAGEFILTER_H__
