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

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkRImageSource.h
	Version:		$Revision: 1761 $
	Date:			$Date: 2011-09-23 17:25:41 +0200 (Fri, 23 Sep 2011) $

	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 RIMAGEREADER_H__
#define RIMAGEREADER_H__

#include "ritkCommon.h"

#include <itkImageSource.h>
#include "ritkTimer.h"
#include "ritkRImage.h"

namespace ritk
{

/**	@ingroup	Common
  *	@class		RImageSource
  *	@author		Jakob Wasza
  * @brief		Base class to create range images
  *
  * @details
  *	This class provides the basic interface for creating RImages, objects derived from this class
  *	are meant to be at the front of the processing pipeline. A RImageSource can be used like a regular ITK process
  * object, e.g. Update() and GetOutput(). Internal, a call to Update() will trigger the GenerateRImage() routine
  * that all subclasses have to provide (the output is already allocated). This base class is templated over a range image that has 
  *	to be a range image base class.  Using a base class allows a concrete source to be used in a generic processing pipeline 
  *	(i.e. sources and filters are connected through the base class, only). If a class derived from this base class is suposed to generate a sub class
  *	of the template parameter it is therefore necessary that the correct output is created and set within the sub class'
  *	constructor and that access to the source's output is donce via a dynamic cast to the concrete range image type. This can
  *	be accomplished by calling the ChangeOutputMacro(RIMAGETYPE) and the CastOutputMacro(RIMAGEBASE,RIMAGESUB) macros.
  * Calls to ChangeOutputMacro(RIMAGETYPE) should be restricted to constructors to avoid inconsistencies within a 
  *	processing pipeline. The following code snippet illustrates the correct usage of the macros:
  *	\code
  * template<class TRImageBase, class TRImageSub>
  * MySource<TRImageBase,TRImageSub>::
  * MySource()
  * {
  *  // Output macro
  *  ChangeOutputMacro(TRImageSub)
  *
  * ...
  * }
  *	
  * template<class TRImageBase, class TRImageSub>
  * void
  * MySource<TRImageBase,TRImageSub>::
  * GenerateRImage()
  * {
  *  // Cast to the correct output (This will generate a variable CastedOutput from type TRImageSub::Pointer)
  *  CastOutput(TRImageBase,TRImageSub)
  *
  *  // Use CastedOutput instead of GetOutput()
  *  CastedOutput->GetSomeSubImage()->SetSomeVariable(42);
  *  ...
  * }
  *	\endcode
  *	Automatic runtime evaluation is supported by this class' implementation of the GenerateData() method and the 
  *	Timer class that RImageSource is derived from: The timer will be started at the beginning of GenerateData() 
  *	method and stopped after all calls (especially GenerateRImage()) finished. Elapsed times will be averaged over 10 passes.
  */
template<class TRImage>
class RImageSource : public itk::ImageSource<TRImage>, public TimerD
{
public:
	/** @name Typedefs */
	//@{

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

	/** @name RImage typedefs */
	//@{
	typedef TRImage							RImageType;
	typedef typename RImageType::Pointer	RImagePointer;
	//@}

	//@}

	/// RTTI
	itkTypeMacro(RImageSource, itk::ImageSource);

	/** @brief	Generate the output information
	 *
	 *	@details
	 *	Prepare the allocation of the output image during the first back propagation of the pipeline. And is inherited
	 *	from itk::ImageSource. As this base class is intended to be at the very beginning of a pipeline it is inevitable
	 *	that the regions are set by this method. Subclasses must provide an implementation! \n
	 *	Note: It would be more appropriate to define a pure virtual function that is called by this class' implementation of
	 *	GenerateOutputInformation().
	 */
	virtual void GenerateOutputInformation();


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

	/**	@brief	Create the range image
	 *
	 *	This method has to be implemented by all sub-classes and has to provide the actual creation (loading from file, live stream) 
	 *	of the range image. When updating the range image reader the base class' GenerateData() method will be invoked which, eventually, will
	 *	call this creation routine. Subclasses implementations of these methods have to make sure, that the data is available via
	 *	GetOutput() after a call of this method.
	 */
	virtual void GenerateRImage() = 0;

	/// Overriding ImageSource. Will call GenerateRImage()
	virtual void GenerateData();

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

/// Change the output
#define ChangeOutputMacro(RIMAGETYPE)									\
	typename RIMAGETYPE::Pointer NewOutput = RIMAGETYPE::New();			\
	this->ProcessObject::SetNthOutput(0, NewOutput.GetPointer());		\

/// Cast the output
#define CastOutput(RIMAGEBASE,RIMAGESUB)																		\
	typename RIMAGESUB::Pointer CastedOutput = dynamic_cast<RIMAGESUB*>((RIMAGEBASE*)this->GetOutput());		\
	if ( !CastedOutput )																						\
	{																											\
		itkExceptionMacro(<<"Could not cast to correct type. Did you forget to call ChangeOutputMacro?");		\
	}


/** @name Template instantiations */
//@{
typedef class COMMON_EXPORT RImageSource<RImageF2> RImageSourceF2;
typedef RImageSource<RImageF2> RImageSourceF2;
//@}




//#include "RImageSourcec.txx"

} // end namespace ritk

#endif // RIMAGEREADER_H__
