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

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkFrameGrabber.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 FRAMEGRABBER_H__
#define FRAMEGRABBER_H__

#include "ritkCore.h"

#include "ritkRImageFilterWrapper.h"

namespace ritk
{

/**	@ingroup	Core
 *	@class		FrameGrabber
 *	@author		Jakob Wasza
 *	@brief		Software frame grabber for range images
 *
 *	@details
 *	This class implements a softwar frame grabber for range images using an RImageFilterWrapper. \n
 *	As elements of the acquisition pipeline might generate their output in an address space 
 *	that is not valid throughout the lifespane of the pipeline, it is mandatory to relocate the data in
 *	an appropriate address space. Furthermore, as RImageFilterWrappers are supposed to graft (aka shallow copy)
 *	unfiltered data and outputs of wrapped filters due to performance issues, the actual pipeline output is
 *	likely to be subject to concurrent access that are not thread safe (e.g. filtering and applications). \n
 *	The solution to this problem is to append a framegrabber at the very end of the acquisition pipeline, that
 *	performs a deep copy of the pipeline's output. The deep copied data is then dispatched to the applications. \n
 *	NOTE: A framegrabber uses (is derived from) an RImageFilterWrapper as this base class inherently supports deep copy operations 
 *	and may be attached to the internal acquisition pipeline without further modifications. \n
 *	NOTE: The framegrabber should ALWAYS be created in the same thread context and address space as the acquisition pipeline \n
 *	NOTE: A framegrabber strategy does NOT resolve issues of invalid vtables that occurs if a subclass of RImage is 
 *	dynamically unloaded while an instance of the respective class is still alive within the framework.
 */
class CORE_EXPORT FrameGrabber : public RImageFilterWrapperF2
{
public:
	/** @name	Typedefs */
	//@{

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

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

	//@}

	/// Object creation
	itkNewMacro(Self);

	/// RTTI
	itkTypeMacro(Self, Superclass);

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

	/// Dummy
	void DoFiltering();

	/// Do the synchronization and memory relocation
	void GenerateData();

protected:
	/// Our range image pool
	std::vector<OutputImagePointer> m_RImagePool;

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

} // end namespace ritk

#endif // FRAMEGRABBER_H__