#ifndef KINECTRANGETOWORLDFILTER_H__
#define KINECTRANGETOWORLDFILTER_H__

#include "RITKCommon.h"

#include <itkImageToImageFilter.h>



/**	@class		KinectRangeToWorldFilter
 *	@author		Jakob Wasza
 *	@brief		Filter that generates a world coord image from a kinect range image
 *
 *	@details
 *	This filter generates a world coord image (3D points at each pixel) from a kinect range image (orthogonal distances at each pixel).
 */
template<class TRangeImage, class TFlagImage, class TWorldCoordImage> 
class KinectRangeToWorldFilter : public itk::ImageToImageFilter<TRangeImage, TWorldCoordImage>
{
public:
	/** @name	Typedefs */
	//@{

	/** @name	Standard typedefs */
	//@{
	typedef KinectRangeToWorldFilter								Self;
	typedef itk::ImageToImageFilter<TRangeImage,TWorldCoordImage>	Superclass;
	typedef itk::SmartPointer<Self>									Pointer;
	typedef itk::SmartPointer<const Self>							ConstPointer;
	typedef itk::DataObject::Pointer								DataObjectPointer;
	//@}

	/**	@name	Input, output and Flag typedefs */
	//@{
	typedef typename Superclass::InputImageType		InputImageType;
	typedef typename InputImageType::Pointer		InputImagePointer;
	typedef typename InputImageType::ConstPointer	InputImageConstPointer;
	typedef typename InputImageType::PixelType		InputPixelType;
	typedef typename Superclass::OutputImageType	OutputImageType;
	typedef typename OutputImageType::Pointer		OutputImagePointer;
	typedef typename OutputImageType::PixelType		OutputImagePixelType;
	typedef TFlagImage								FlagImageType;
	typedef typename FlagImageType::Pointer			FlagImagePointer;
	//@}

	//@}

	/// Object creation
	itkNewMacro(Self);

	/// RTTI
	itkTypeMacro(KinectRangeToWorldFilter, itk::ImageToImageFilter);

	/**	@name	Set/Get the Flag image input */
	//@{
	itkSetInputMacro(FlagImage,FlagImageType,1);
	itkGetInputMacro(FlagImage,FlagImageType,1);
	//@}

	/**	@name	Set/get the conversion parameters */
	//@{
	void SetConversionParameters(float XToZ, float YToZ);
	void GetConversionParameters(float *XToZ, float *YToZ);
	//@}


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

	/** @name  Threaded data generation */
	//@{
	virtual void BeforeThreadedGenerateData();
	virtual void ThreadedGenerateData(const OutputImageRegionType& OutputRegionForThread,int threadId);
	virtual void AfterThreadedGenerateData();
	//@}

protected:
	/**	@name Members used to compute the world coords out of the range data */
	//@{
	float m_XToZ;
	float m_YToZ;
	//@}


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


/** @name Template instantiations */
//@{
typedef KinectRangeToWorldFilter<itk::Image<float,2>, itk::Image<unsigned char,2>, itk::Image<itk::Vector<float,3>,2>> KinectRangeToWorldFilterF2;
//@}



#endif // KINECTRANGETOWORLDFILTER_H__