#ifndef VTKTUTORIALPLUGIN_H__
#define	VTKTUTORIALPLUGIN_H__

#include "ritkApplicationPlugin.h"
#include "VTKTutorialPlugin.h"
#include "VTKTutorialWidget.h"

#include "ritkRImageVTKData.h"
#include <vtkScalarBarActor.h>
#include <vtkEventQtSlotConnect.h>

#include <itkMesh.h>
#include <itkTriangleCell.h>

class VTKTutorialPlugin : public ritk::ApplicationPlugin
{
	Q_OBJECT

public:
	/// Constructor
	VTKTutorialPlugin();
	/// Destructor
	virtual ~VTKTutorialPlugin();

	/// 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 Mesh typedefs */
	//@{
	typedef itk::Point<vtkFloatingPointType, 3>																		ItkPoint;
	typedef itk::DefaultStaticMeshTraits<vtkFloatingPointType, 3, 2, vtkFloatingPointType, vtkFloatingPointType>	MeshTraits;
	typedef itk::Mesh<vtkFloatingPointType, 3, MeshTraits>															MeshType;
	typedef MeshType::PointsContainer::ConstIterator																PointIterator;
	typedef MeshType::CellType																						CellType;
	typedef MeshType::CellsContainer::ConstIterator																	CellIterator;
	typedef CellType::PointIdIterator																				PointIdIterator;
	typedef itk::TriangleCell< CellType >																			TriangleCellType;
	//@}

signals:
	void UpdateGUI();

protected slots:
	void SetPolyDataType(ritk::RImageVTKData::PolyDataType Type);
	void SetVisualizationType(VTKTutorialWidget::VisualizationMode Mode, bool UseLUT);
	void ComputeLocalNeighborhood();
	void SetViewMode();
	void SetManipulationMode();
	// Connected to the widget's stereo on check box
	void CheckBoxStereoOnStateChanged(int State);
	// Connected to the widget's range interval min spinbox
	void RangeIntervalMinChanged(double d);
	// Connected to the widget's range interval max spinbox
	void RangeIntervalMaxChanged(double d);
	// Connected to the widget's clamp range interval button
	void ClampRangeInterval();

	// Connected to the widget's RGB interval min spinbox
	void RGBIntervalMinChanged(double d);
	// Connected to the widget's RGB interval max spinbox
	void RGBIntervalMaxChanged(double d);
	// Connected to the widget's clamp RGB interval button
	void ClampRGBInterval();

	// blabla ;)
	void SetCurrentFrameAsReferenceFrame();

	// Connected to the widget's display legend check box
	void DisplayLegend(int i);

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

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

	MeshType::Pointer vtkPolyDataToITKMesh(vtkPolyData *polyData);
	vtkPolyData* ITKMeshToVtkPolyData(MeshType::Pointer mesh);

protected:
	VTKTutorialWidget *m_Widget;

	// The current range data
	ritk::NewFrameEvent::RImageConstPointer m_CurrentFrame;

	/// The current frame data
  vtkSmartPointer<ritk::RImageVTKData> m_RImageVTKData;
	
	vtkSmartPointer<ritk::RImageActorPipeline> m_Actor;
	int m_Cnt;

	/// Display frame difference mode
	bool m_DisplayFrameDifference;
	/// The reference frame used to visualize frame differences
	ritk::NewFrameEvent::RImagePointer m_ReferenceFrame;

	vtkSmartPointer<vtkActor> m_SphereActor;
	vtkSmartPointer<vtkActor> m_NeighborhoodActor;
	vtkSmartPointer<vtkScalarBarActor> m_ScalarBarActor;

	/// Qt slot connector, e.g. for connecting a mouse event
	vtkSmartPointer<vtkEventQtSlotConnect> m_QtSlotConnector;

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

	// Actors for picked points and line in between
	vtkSmartPointer<vtkActor> m_PickPoint1Actor;
	vtkSmartPointer<vtkActor> m_PickPoint2Actor;
	vtkSmartPointer<vtkActor> m_LineActor;

	vtkSmartPointer<vtkPolyData> m_NewPolyData;
	vtkSmartPointer<vtkPoints> m_NewPoints;
	vtkSmartPointer<vtkCellArray> m_NewCells;
	vtkSmartPointer<vtkFloatArray> m_NewScalars;
};


#endif // VTKTUTORIALPLUGIN_H__
