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

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkGraphicsInteropImportImageContainer.h
	Version:		$Revision: 2774 $
	Date:			$Date: 2012-03-13 10:52:35 +0100 (Di, 13 Mrz 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 GRAPHICSINTEROPIMPORTIMAGECONTAINER_H__
#define GRAPHICSINTEROPIMPORTIMAGECONTAINER_H__


#include "ritkVisualization.h"
#include "ritkGenericImportImageContainer.h"


#include <GL/glu.h>

namespace ritk
{

/**	@ingroup	Visualization
 *	@class		GraphicsInteropImportImageContainer
 *	@author		Jakob Wasza
 *	@brief		Interface for container interoperability with OpenGL
 *
 *	@details
 *	This class extends the generic import image container concept in RITK with OpenGL interoperability. 
 *	This class is intended to be used for CUDA/OpenCL and OpenGL interoperability. \n
 *	Note that a GraphicsInteropImportImageContainer can register multiple VBOs. Therefore, inheriting classes have to ensure consistency.
 *	@todo	Check if VBOs are the only supported buffer objects or if FBOs can be supported,too.
 */
template<typename TElementIdentifier, typename TElement>
class GraphicsInteropImportImageContainer : public GenericImportImageContainer<TElementIdentifier,TElement>
{
public:
	/**	@name	Std typedefs */
	//@{
	typedef GraphicsInteropImportImageContainer							Self;
	typedef GenericImportImageContainer<TElementIdentifier,TElement>	Superclass;
	typedef itk::SmartPointer<Self>										Pointer;
	typedef itk::SmartPointer<const Self>								ConstPointer;
	//@}

	/// For convenience
	//@{
	typedef Superclass													GenericImportImageContainerType;
	typedef typename Superclass::ImportImageContainerType				ImportImageContainerType;
	typedef TElement													Element;
	typedef TElementIdentifier											ElementIdentifier;
	//@}
	
	/// RTTI
	itkTypeMacro(GraphicsInteropImportImageContainer, GenericImportImageContainer);


	/**	@name	Host/device synchronization. Is delegated to the superclass */
	//@{
	virtual void SynchronizeDevice();
	virtual void SynchronizeHost();
	//@}

	/**	@name	Deep copy. Is delegated to the superclass */
	//@{
	virtual void DeepCopy(ImportImageContainerType *Container);
	virtual void DeepCopy(const ImportImageContainerType *Container);
	//@}

	/// Must be implemented by all subclasses
	virtual void RegisterVBO(GLuint target) const =0;

	/// Must be implemented by all subclasses
	virtual void UnregisterVBO(GLuint target) const =0;

	/// Must be implemented by all subclasses
	virtual void CopyToVBO(GLuint target, size_t  size) const =0;

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

	/// Print
	virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;

	/**	@name	Memory (de)allocation. Is delegated to the superclass */
	//@{
	virtual Element* AllocateElements(ElementIdentifier size) const;
	virtual void DeallocateManagedMemory();
	//@}

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


} // namespace ritk

#endif // GRAPHICSINTEROPIMPORTIMAGECONTAINER_H__
