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

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

#include "ritkGenericPayloadContainer.h"

namespace ritk
{

/**	@ingroup	Common
  *	@class		ImagePayloadContainer
  *	@author		Jakob Wasza
  *	@brief		Class that defines a payload container for itk::Images
  *
  *	@details
  *	This class is a concrete version of an GenericPayloadContainer. It is supposed to be
  *	used with regular itk::Images. This class provides all functionality to enable proper
  *	grafting or deep copying of itk::Images.
  */
template<class TImageType>
class ImagePayloadContainer : public GenericPayloadContainer
{
public:
	/** @name Standard typedefs */
	//@{
	typedef ImagePayloadContainer			Self;
	typedef GenericPayloadContainer			Superclass;
	typedef itk::SmartPointer<Self>			Pointer;
	typedef itk::SmartPointer<const Self>	ConstPointer;
	//@}

	/// Typedefs for the superclass' payload and our image payload
	//@{
	typedef Superclass::PayloadType					PayloadType;
	typedef PayloadType::Pointer					PayloadPointer;
	typedef PayloadType::ConstPointer				PayloadConstPointer;
	typedef TImageType								ImagePayloadType;
	typedef typename ImagePayloadType::Pointer		ImagePayloadPointer;
	typedef typename ImagePayloadType::ConstPointer	ImagePayloadConstPointer;
	//@}

	/// Object creation
	itkNewMacro(Self);

	/// RTTI
	itkTypeMacro(ImagePayloadContainer, GenericPayloadContainer);

	/// Overloaded. Will simply ensure that only images defined by the template parameter can be used
	virtual void SetPayload(PayloadType *payload);


	/**	@brief	Graft a data object
	 *	@param	data	the data object
	 *
	 *	@details
	 *	This methods has to graft (aka. shallow copy) the given data object. 
	 *	Usually, grafting should only performed if the given argument can be casted to a generic payload container.
	 *	This method should then graft the container's actual payload.
	 */
	virtual void Graft(const DataObject *data);

	/**	@brief	Deep copy a data object
	 *	@param	data	the data object
	 *
	 *	@details
	 *	This method has to deep-copy the given data object.
	 *	@sa	Graft()
	 */
	virtual void DeepCopy(const DataObject *data);
		

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

	/// Print the object on a stream
	virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;

private:
	/// purposely not implemented
	ImagePayloadContainer(Self&);

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

/// Macro that eases appending of image payloads. The idx will be stored in the IdxName var. To be used within RImages only!
#define AppendImagePayloadContainerMacro(IdxName, ImageType, Image, Identifier)					\
{																								\
	typedef ritk::ImagePayloadContainer<ImageType> ImageContainerType;							\
	typename ImageContainerType::Pointer _ImagePayload = ImageContainerType::New();				\
	_ImagePayload->SetPayload(Image);															\
	_ImagePayload->SetIdentifier(Identifier);													\
	IdxName = this->AppendPayloadContainer(_ImagePayload);										\
}

} // namespace ritk



#endif // RITK_IMAGEPAYLOADCONTAINER_H__
