#ifndef RISIMULATORPLUGIN_H__
#define	RISIMULATORPLUGIN_H__

#include "ritkSourcePlugin.h"
#include "TOFSimulatorSource.h"
#include "RISimulatorWidget.h"
#include "EditSceneDialog.h"

#include <vtkCameraActor.h>

#include <QMutex>
#include <QTimer>


class RISimulatorPlugin : public ritk::SourcePlugin
{
	Q_OBJECT

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

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

	/** @name	Player states */
	//@{
	typedef enum StateType
	{
		Idle,
		Playing, 
	} StateType;

	/** @brief	Set a parameter
	 *	
	 *	@details
	 *	Will set a parameter.
	 */
	virtual void SetParameter(QString Name, QString Value);


signals:
	void UpdateGUI();

protected:
	/// Has to be provided
	SourcePointer GetSource();

	/// Set the state of the player
	void SetState(StateType State);

protected slots:
	/// Connected to the widgets edit scene button
	void EditScene();
	/// Play
	void Play();
	/// Pause
	void Pause();
	/// Request the next frame
	void RequestFrame();
	/// Should be connected to the acquisition pipelines NewFrame() signal so we can tell the player widget to update its members
	void NewFrame();
	/// Enable/Disable noise simulation
	void ToggleNoiseSimulation();
	/// Set the standard deviation of the noise
	void SetNoiseVariance(int value);
	/// Enable/disable incorporating amplitudes into noise computation
	void ToggleIncorporateAmplitudes();
	/// Enable/disable simulation of specular reflections
	void ToggleReflectionSimulation();
	/// Set the perlin noise frequency of simulation of specular reflections
	void ReflectionFrequencyChanged(int Index);
	/// Set the octave count for the perline noise used for simulation of specular reflections
	void ReflectionOctaveChanged(int Index);
	/// Set the persistence value for perline noise to simulate specular reflections
	void ReflectionPersistanceChanged(double d);
	/// Load a perlin mask from file
	void LoadPerlinMaskPushButton();	
	/// Unload a perlin mask from file
	void UnloadPerlinMaskPushButton();	
	/// Set the FPS
	void SetFPS(int FPS);

protected:
	/// The widget
	RISimulatorWidget *m_Widget;
	/// The current state
	StateType m_State;
	/// Mutex used to lock access to the state
	QMutex m_StateMutex;
	/// Timer for live playing
	QTimer *m_Timer;
	/// The scene dialog
	EditSceneDialog *m_SceneDialog;
	/// Target FPS
	int m_TargetFPS;

	/// The camera actor
	vtkSmartPointer<vtkCameraActor> m_CameraActor;

	/** @name	The RI simulator. We use a ToF-like system */
	//@{
	typedef TOFSimulatorSourceF2 RISimulatorType;
	typedef RISimulatorType::Pointer RISimulatorPointer;
	RISimulatorPointer m_RISimulator;
	//@}

	/**	@name	Buffer images as input for the actual ToF simulator */
	//@{
	typedef RISimulatorType::DepthImageType::SizeType SizeType;
	SizeType m_CurrentSize;

	typedef RISimulatorType::DepthImageType DepthImageType;
	typedef DepthImageType::Pointer DepthImagePointer;
	DepthImagePointer m_DepthImage;

	typedef itk::Image<itk::FixedArray<float,4> > RGBAImageType;	
	typedef RGBAImageType::Pointer RGBAImagePointer;
	RGBAImagePointer m_RGBAImage;
	//@}
};


#endif // RANGESIMULATORPLUGIN_H__
