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

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

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

#include "ritkImagePayloadContainer.h"
#include "ritkGenericImportImageContainer.h"


namespace ritk
{

//----------------------------------------------------------------------------
template<class TImageType>
ImagePayloadContainer<TImageType>::ImagePayloadContainer()
{
}


//----------------------------------------------------------------------------
template<class TImageType>
ImagePayloadContainer<TImageType>::~ImagePayloadContainer()
{
}


//----------------------------------------------------------------------------
template<class TImageType>
void
ImagePayloadContainer<TImageType>
::SetPayload(PayloadType *payload)
{
	// Sanity check. Note that we also accept null pointer
	ImagePayloadPointer test = dynamic_cast<ImagePayloadType*>((ImagePayloadType*)payload);
	if ( payload && !test )
		itkExceptionMacro(<<"Could not cast payload to the correct image!");

	// Set the payload via the superclass
	Superclass::SetPayload(payload);
}


//----------------------------------------------------------------------------
template<class TImageType>
void
ImagePayloadContainer<TImageType>
::Graft(const DataObject *data)
{
	// Sanity check for correct image container payload type
	Self::ConstPointer IPC = dynamic_cast<const Self*>((const Self*)data);
	if ( !IPC )
		itkExceptionMacro(<<"Could not cast argument to correct image payload container!");
	if ( IPC->GetIdentifier().compare(this->GetIdentifier()) != 0 )
		itkExceptionMacro(<<"Invalid payload identifiers detected: " << IPC->GetIdentifier() << " vs. " << this->GetIdentifier());

	// Early termination if we have a null pointer as source payload
	if ( !IPC->GetPayload() )
		return;

	// Sanity check for the source image payload
	ImagePayloadPointer SourceImage = dynamic_cast<ImagePayloadType*>((ImagePayloadType*)IPC->GetPayload());
	if ( !SourceImage )
		itkExceptionMacro(<<"Could not derive a valid source image: Identifier=" << this->GetIdentifier() << " Ptr=" << (void*)IPC->GetPayload());

	// Derive the target image and sanity check
	ImagePayloadPointer TargetImage = NULL;
	if ( !this->GetPayload() )
	{
		TargetImage = dynamic_cast<ImagePayloadType*>((itk::LightObject*)IPC->GetPayload()->CreateAnother());
		this->SetPayload(TargetImage);
	}
	else
	{
		TargetImage = dynamic_cast<ImagePayloadType*>((ImagePayloadType*)this->GetPayload());
	}
	if ( !TargetImage )
		itkExceptionMacro(<<"Could not derive a valid target image: Identifier=" << this->GetIdentifier());

	// Simply graft
	TargetImage->Graft(SourceImage);
}


//----------------------------------------------------------------------------
template<class TImageType>
void
ImagePayloadContainer<TImageType>
::DeepCopy(const DataObject *data)
{
	// Sanity check for correct image container payload type
	Self::ConstPointer IPC = dynamic_cast<const Self*>((const Self*)data);
	if ( !IPC )
		itkExceptionMacro(<<"Could not cast argument to correct image payload container!");
	if ( IPC->GetIdentifier().compare(this->GetIdentifier()) != 0 )
		itkExceptionMacro(<<"Invalid payload identifiers detected: " << IPC->GetIdentifier() << " vs. " << this->GetIdentifier());

	// Early termination if we have a null pointer as source payload
	if ( !IPC->GetPayload() )
		return;

	// Sanity check for the source image payload
	ImagePayloadPointer SourceImage = dynamic_cast<ImagePayloadType*>((ImagePayloadType*)IPC->GetPayload());
	if ( !SourceImage )
		itkExceptionMacro(<<"Could not derive a valid source image: Identifier=" << this->GetIdentifier() << " Ptr=" << (void*)IPC->GetPayload());

	// Derive the target image and sanity check
	ImagePayloadPointer TargetImage = NULL;
	if ( !this->GetPayload() )
	{
		TargetImage = dynamic_cast<ImagePayloadType*>((itk::LightObject*)IPC->GetPayload()->CreateAnother());
		this->SetPayload(TargetImage);
	}
	else
	{
		TargetImage = dynamic_cast<ImagePayloadType*>((ImagePayloadType*)this->GetPayload());
	}
	if ( !TargetImage )
		itkExceptionMacro(<<"Could not derive a valid target image: Identifier=" << this->GetIdentifier());

	// Copy all information
	TargetImage->CopyInformation(SourceImage);
	TargetImage->SetBufferedRegion(SourceImage->GetBufferedRegion());
	TargetImage->SetRequestedRegion(SourceImage->GetRequestedRegion());

	// Copy. This macro also accounts for generic pixel containers...
	GIIC_IMAGE_DEEPCOPY(ImagePayloadType, SourceImage, TargetImage);	
}


//----------------------------------------------------------------------------
template<class TImageType>
void
ImagePayloadContainer<TImageType>
::PrintSelf(std::ostream &os, itk::Indent indent) const
{
	Superclass::PrintSelf(os, indent);
	os << indent << "ImagePayloadContainer" << std::endl;
	os << indent << indent << "Payload: " << this->GetPayload() << std::endl;
}






} // namespace ritk