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

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkTruncatedSignedDistanceFunctionRayCasterEntity.h
	Version:		$Revision: 2941 $
	Date:			$Date: 2012-04-06 12:08:07 +0200 (Fr, 06 Apr 2012) $

	Copyright (c) 2010-2011
	Pattern Recognition Lab, 
    University Erlangen-Nuremberg, Germany
    All rights reserved.

	This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
	See RITKCopyright.txt for more information.

	http://www5.informatik.uni-erlangen.de/research/software/ritk

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


#ifndef RITKTRUNCATEDSIGNEDDISTANCEFUNCTIONRAYCASTERENTITY_H__
#define RITKTRUNCATEDSIGNEDDISTANCEFUNCTIONRAYCASTERENTITY_H__

#if defined(WIN32)
	#include <windows.h>
	// Due to explicit template instantiation
	#pragma warning(disable : 4661)
#endif


#include <GL/glu.h>

#include "ritkCuda.h"
#include "ritkVisualization.h"
#include "ritkOpenGLVolumeRayCastEntity.h"

#include "ritkTruncatedSignedDistanceFunctionRayCasterEntityControlUnit.h"
#include "ritkTruncatedSignedDistanceFunction.h"
#include "ritkTruncatedSignedDistanceFunctionRayCaster.h"

#include "ritkRImage.h"


namespace ritk
{

/**	@ingroup	Cuda
 *	@class		TruncatedSignedDistanceFunctionRayCasterEntity
 *	@author		Jakob Wasza
 *	@brief		Entity for a TSDF ray caster
 *
 *	@details
 */
class CUDA_EXPORT TruncatedSignedDistanceFunctionRayCasterEntity : public OpenGLVolumeRayCastEntity<TruncatedSignedDistanceFunction, RImage<float,2> >
{
	Q_OBJECT

public:
	/**	@name	Standard ITK typedefs */
	//@{
	typedef TruncatedSignedDistanceFunctionRayCasterEntity									Self;
	typedef OpenGLVolumeRayCastEntity<TruncatedSignedDistanceFunction, RImage<float,2> >	Superclass;
	typedef itk::SmartPointer<Self>															Pointer;
	typedef itk::SmartPointer<const Self>													ConstPointer;
	//@}

	/**	@name	Volume and image typedefs */
	//@{
	typedef Superclass::VolumeType				TSDFType;
	typedef TSDFType::Pointer					TSDFPointer;
	typedef TSDFType::ConstPointer				TSDFConstPointer;
	typedef Superclass::OutputImageType			RangeImageType;
	typedef RangeImageType::Pointer				RangeImagePointer;
	typedef RangeImageType::ConstPointer		RangeImageConstPointer;
	//@}

	/**	@name	The ray caster */
	//@{
	typedef Superclass::RayCasterType			RayCasterType;
	typedef Superclass::RayCasterPointer		RayCasterPointer;
	//@}

	/// RTTI
	itkTypeMacro(TruncatedSignedDistanceFunctionRayCasterEntity, OpenGLVolumeRayCastEntity);

	/// Object creation
	itkNewMacro(Self);

	/// Rendering
	virtual void PostProcessAndRender();

	/// The controlunit of this entity.
	virtual QDockWidget* GetControlUnit() const;

signals:
	/// Signal that is emitted when a new range image has been generated
	void RangeImageAvailable(ritk::RImage<float,2>::ConstPointer);


protected:
	/// Constructor
	TruncatedSignedDistanceFunctionRayCasterEntity();
	/// Destructor
	virtual ~TruncatedSignedDistanceFunctionRayCasterEntity();

	/**	@name The Cuda TSDF ray caster */
	//@{
	typedef TruncatedSignedDistanceFunctionRayCaster<RImage<float,2> > TSDFRayCasterType;
	//@}

	/// Initialize all OpenGL related members
	virtual void InitGL();
	/// Release all OpenGL related members
	virtual void CloseGL();

	/// Load a shader
	virtual GLuint LoadShader(const char *Program, bool VertexFlag);

protected slots:
	/// Set whether to render the bounding box
	void RenderBoundingBox(bool);
	/// Set the LUT to render
	void SetLUT(int id);

protected:
	/// Flag to indicate initialization
	bool m_InitFlag;

	/// The control unit
	TruncatedSignedDistanceFunctionRayCasterEntityControlUnit *m_ControlUnit;

	/// The texture
	GLuint m_Texture;

	/// The LUT texture
	GLuint m_LUTTexture;

	/**	@name Shader */
	//@{
	/// The shader program
	GLuint m_ShaderProgram;
	/// Handles to the shader objects
	std::vector<GLuint> m_ShaderHandles;
	//@}

	/**	@name The output RImages */
	//@{
	typedef ritk::RImage<float,2> RImageType;
	std::vector<RImageType::Pointer> m_RImagePool;
	//@}

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

} // ritk

#endif // RITKTRUNCATEDSIGNEDDISTANCEFUNCTIONRAYCASTERENTITY_H__