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

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkVTKImageActorPipeline.cxx
	Version:		$Revision: 1761 $
	Date:			$Date: 2011-09-23 17:25:41 +0200 (Fr, 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

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

#include "ritkVTKImageActorPipeline.h"

#include <vtkObjectFactory.h>
#include <vtkProperty.h>

#include "vtkBMPWriter.h"
#include "vtkBMPReader.h"
#include "vtkRenderer.h"

namespace ritk
{

// Implements static VTKImageActorPipeline *New();
vtkStandardNewMacro(VTKImageActorPipeline);

//----------------------------------------------------------------------------
VTKImageActorPipeline::VTKImageActorPipeline()
{
	// Initialize the mutex
	m_Mutex = vtkSmartPointer<vtkMutexLock>::New();

	// Initialize the device
	m_Device = vtkSmartPointer<vtkImageActor>::New();
	
	// Set up the pipeline
	m_Data = vtkSmartPointer<vtkImageData>::New();	

	// Allocate dummy for initialization
	m_Data->SetDimensions(1, 1, 1);
    m_Data->SetSpacing(1, 1, 1);
    m_Data->SetOrigin(0, 0, 0);
    m_Data->AllocateScalars();
    m_Data->SetNumberOfScalarComponents(1);
	m_Data->SetScalarTypeToUnsignedChar();
	
	this->SetInput(m_Data);	
}


//----------------------------------------------------------------------------
VTKImageActorPipeline::~VTKImageActorPipeline()
{
}


//----------------------------------------------------------------------------
void
VTKImageActorPipeline::SetData(VTKImageDataPointer Data, bool DeepCopy)
{
	// Lock the pipeline
	Lock();

	// Set the data to the pipeline
	if ( DeepCopy )
	{
		m_Data->DeepCopy(Data);		
		Superclass::SetInput(m_Data);
		m_Device->SetInput(m_Data);				
	}

	else
	{
		m_Data = Data;		
		Superclass::SetInput(m_Data);
		m_Device->SetInput(m_Data);
	}

	// Modified (not sure about the benifit from these calls)
	this->Modified();
	m_Device->Modified();

	// Unlock the pipeline
	Unlock();
}



//----------------------------------------------------------------------------
void
VTKImageActorPipeline::SetInput(VTKImageDataPointer Data)
{
	// Lock the pipeline
	Lock();

	Superclass::SetInput(Data);
	m_Device->SetInput(Data);	

	// Modified (not sure about the benifit from these calls)
	this->Modified();
	m_Device->Modified();	

	// Unlock the pipeline
	Unlock();
}


//----------------------------------------------------------------------------
void
VTKImageActorPipeline::Render(vtkRenderer *Renderer)
{
	// Lock the pipeline
	Lock();

	// The actual rendering
	m_Device->Render(Renderer);

	// Unlock the pipeline
	Unlock();
}


//----------------------------------------------------------------------------
void
VTKImageActorPipeline::Lock()
{
	m_Mutex->Lock();
}


//----------------------------------------------------------------------------
void
VTKImageActorPipeline::Unlock()
{
	m_Mutex->Unlock();
}


//----------------------------------------------------------------------------
void 
VTKImageActorPipeline::Modified()
{
	if ( this->m_Device ) // Will be NULL only during destruction of this class.
	{
		this->m_Device->Modified();
	}
	this->vtkImageActor::Modified();
}


//----------------------------------------------------------------------------
double*
VTKImageActorPipeline::GetBounds()
{
	double *d;
	Lock();
	d = Superclass::GetBounds();
	d = m_Device->GetBounds();	
	Unlock();
	return d;
}


//----------------------------------------------------------------------------
int
VTKImageActorPipeline::RenderOpaqueGeometry(vtkViewport *viewport)
{
	int i;
	Lock();
	i = Superclass::RenderOpaqueGeometry(viewport);
	m_Device->RenderOpaqueGeometry(viewport);
	Unlock();
	return i;
}
		

} // end namespace ritk
