#ifndef VTKDATAPROCESSINGPLUGIN_H__
#define	VTKDATAPROCESSINGPLUGIN_H__

#include "ritkApplicationPlugin.h"
#include "VTKDataProcessingPlugin.h"
#include "VTKDataProcessingWidget.h"

#include "ritkRImage.h"
#include "ritkRGBRImage.h"
//#include "../../SourcePlugins/PMDCamCube/PMDCamCubeRImage.h"

#include "ritkRImageActorPipeline.h"

#include <vtkPolyData.h>
#include <vtkPolyDataReader.h>
#include <vtkPolyDataWriter.h>
#include <vtkEventQtSlotConnect.h>

/**	@name	 VTK typedefs */
//@{
typedef vtkSmartPointer<vtkPolyData>			vtkPolyDataRef;
typedef vtkSmartPointer<vtkPolyDataReader>		vtkPolyDataReaderRef;
typedef vtkSmartPointer<vtkPolyDataWriter>		vtkPolyDataWriterRef;
typedef vtkSmartPointer<vtkActor>				vtkActorRef;
typedef vtkSmartPointer<vtkEventQtSlotConnect>  vtkEventQtSlotConnectRef;
typedef vtkSmartPointer<ritk::RImageActorPipeline>	RImageActorPipelineRef;
//@}

class VTKDataProcessingPlugin : public ritk::ApplicationPlugin
{
	Q_OBJECT

public:
	/// Constructor
	VTKDataProcessingPlugin();
	/// Destructor
	~VTKDataProcessingPlugin();

	/// Get the name @sa Plugin::GetName
	QString GetName();

	/// Get the plugins GUI @sa Plugin::GetPluginGUI
	QWidget *GetPluginGUI();

	/// Intercept the event.
	void ProcessEvent(ritk::Event::Pointer EventP);

	/**	@name The input types */
	//@{
	typedef ritk::RImageF2						RImageType;
	typedef RImageType::Pointer			RImagePointer;
	typedef RImageType::ConstPointer		RImageConstPointer;

	/*typedef PMDCamCubeRImageF2 CamCubeImageType;
	typedef CamCubeImageType::Pointer CamCubeImagePointer;
	typedef CamCubeImageType::ConstPointer CamCubeImageConstPointer;*/
	//@}

signals:
	void UpdateGUI();

protected slots:
	/// Load VTK data
	void LoadVTKData();
	/// Load range data
	void LoadRangeData();
	/// Save the data
	void SaveData();

	/// Perform segmentation
	void PerformSegmentation();
	/// Perform triangulation
	void PerformTriangulation();
	/// Perform triangulation
	void PerformDecimation();
	
	/// Connected to the widget's display right button event
	void RightButtonPressEventHandling(vtkObject* caller, unsigned long vtk_event, void* client_data, void* call_data);

	/// Save the marker coordinates
	void SaveMarkerCoordinates();

	/// Save range data
	void SaveRangeData();
	/// Save flag data
	void SaveFlagData();

protected:
	/// Update point picker GUI elements
	void UpdatePointPickerGUI();

protected:
	VTKDataProcessingWidget *m_Widget;	
	
	/// The data actor
	RImageActorPipelineRef m_DataActor3D;

	/// RITK data
	ritk::NewFrameEvent::RImageType::WorldCoordImageType::ConstPointer	m_WorldCoordImage;
	ritk::NewFrameEvent::RImageType::RangeImageType::ConstPointer		m_RangeImage;
	ritk::RGBRImageUCF2::RGBImageType::ConstPointer						m_RGBImage;
	
	//CamCubeImageConstPointer m_CamCubeImage;

	/// The current frame data
	ritk::NewFrameEvent::RImageConstPointer m_CurrentFrame;
	vtkSmartPointer<ritk::RImageVTKData> m_RImageVTKData;

	vtkPolyDataRef m_PolyData;

	/// The data
	vtkPolyDataRef m_Data;
	/// The data reader
	vtkPolyDataReaderRef m_VTKReader;
	/// The data writer
	vtkPolyDataWriterRef m_VTKWriter;
	/// The processed data
	vtkPolyDataRef m_ProcessedData;
	
	/// The data input file path
	QString m_InputDataFilePath;	
	/// The data output file path
	QString m_OutputDataFilePath;	

	/// Poly data bounds
	double m_DataBounds[6]; 
	/// Segmentation bounds
	double m_SegmentationBounds[6];

	/// Qt slot connector, e.g. for connecting a mouse event
	vtkEventQtSlotConnectRef m_QtSlotConnector;

	// Pick points, 3D positions
	double * m_PickPoint1;
	double * m_PickPoint2;
	double * m_PickPoint3;
	double * m_PickPoint4;
	double m_Distance;

	// Actors for picked points and line in between
	vtkActorRef m_PickPoint1Actor;
	vtkActorRef m_PickPoint2Actor;
	vtkActorRef m_PickPoint3Actor;
	vtkActorRef m_PickPoint4Actor;
	vtkActorRef m_LineActor;
};


#endif // VTKDATAPROCESSINGPLUGIN_H__
