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

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

#include "ritkCommon.h"

#include <itkObjectFactory.h>
#include <itkDataObject.h>

namespace ritk
{

/**	@ingroup	Common
  *	@class		GenericPayloadContainer
  *	@author		Jakob Wasza
  *	@brief		Class that defines a generic payload for range images
  *
  *	@details
  *	The concept of generic payload containers (GPCs) enables the storage of any payload data in the range image base class at run-time.
  *	In this context, GPCs can be seen as a wrapper/container of the actual data. This base class provides the basic interface for accessing
  *	the payload and a run-time identifier. As the pipeline propagation concept pursued in RITK requires proper grafting and/or deep-copying
  *	of data from a processobject's input to the output, the interface for these methods is provided. However, note that the methods are pure
  *	abstract, as grafting/deep-copying depends on the acutal data (i.e. images vs. landmarks).
  */
class COMMON_EXPORT GenericPayloadContainer : public itk::DataObject
{
public:
	/** @name Standard typedefs */
	//@{
	typedef GenericPayloadContainer			Self;
	typedef itk::DataObject					Superclass;
	typedef itk::SmartPointer<Self>			Pointer;
	typedef itk::SmartPointer<const Self>	ConstPointer;
	//@}

	/// Typedefs for the payload. This enfores that the payload type has to be derived from itk::Object
	//@{
	typedef itk::DataObject					PayloadType;
	typedef PayloadType::Pointer			PayloadPointer;
	typedef PayloadType::ConstPointer		PayloadConstPointer;
	//@}

	/// RTTI
	itkTypeMacro(GenericPayloadContainer, itk::Object);

	/**	@name Set/get the actual payload */
	//@{
	itkSetObjectMacro(Payload, PayloadType);
	itkGetObjectMacro(Payload, PayloadType);
	itkGetConstObjectMacro(Payload, PayloadType);
	//@}

	/**	@name Set/get the identifier for this payload */
	//@{
	itkSetMacro(Identifier, std::string&);
	itkGetConstMacro(Identifier, const std::string&);
	//@}

	/**	@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)=0;

	/**	@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)=0;
		

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

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

protected:
	/// The actual payload
	PayloadPointer m_Payload;
	/// The identifer for the payload
	std::string m_Identifier;

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

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


} // namespace ritk


#endif // RITK_GENERICPAYLOADCONTAINER_H__
