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

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkSourcePlugin.h
	Version:		$Revision: 1817 $
	Date:			$Date: 2011-09-30 16:52:28 +0200 (Fri, 30 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

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

#ifndef SOURCEPLUGIN_H__
#define SOURCEPLUGIN_H__

#include "ritkCore.h"

#include <QObject>
#include <QIcon>
#include "ritkPluginBase.h"

#include "ritkRImageSource.h"
#include "ritkAcquisitionPipeline.h"

namespace ritk
{

/**	@ingroup	Core
 *	@class		SourcePlugin
 *	@author		Jakob Wasza
 *	@brief		Class that provides the basic interface for RITK source plugins
 *
 *	@details
 *	This class provides the basic interface for RITK source plugins.
 *	The main task of an RITK source plugin is to provide a source for the acquisition pipeline and 
 *	routines that eventually trigger pipeline execution. The former is achieved by implementing 
 *	the GetSource() method that will eventually be called during the StartPlugin() method 
 *	connecting the wrapped reader (or source) to the front of the acquisition pipeline.
 *	As a player is a crucial part of the acquisition pipeline, an RITK source plugin has direct access to the pipeline. \n
 *	Optional, source plugins may provide a name and an icon that are shown in the player selection menu. \n
 *	Runtime computation is supported from RImageSource
 */
class CORE_EXPORT SourcePlugin : public QObject, public PluginBase
{
	Q_OBJECT

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

	/**	@brief	Start the filter plugin
	 *	@param	Pipeline	A pointer to the acquisition pipeline
	 *	@return	True if the plugin is started successfully, false otherwise
	 *
	 *	@details
	 *	A call to this method will start the source plugin. In particular,
	 *	this includes connecting the wrapped player to the front of the 
	 *	acquisition pipeline that has to be passed as argument to this function. 
	 *	This class' implementation will check if the argument is actually the 
	 *	acquisition pipeline. \n
	 *	After starting the plugin through this method the wrapped player is part 
	 *	of the pipeline and parameter changes have to be thread safe w.r.t 
	 *	to the acquisition pipeline. \n
	 *	Note that this method is NOT thread safe! Calling threads have to lock
	 *	the plugin manually.
	 *	@sa LockPipeline() @sa UnlockPipeline()
	 */
	virtual bool StartPlugin(void *Pipeline);

	/**	@brief	Stop the filter plugin
	 *	@return	True on success, false otherwise
	 *
	 *	@details
	 *	A call to this method will stop the source plugin. This includes
	 *	removing the wrapped player object from the acquisition pipeline.\n
	 *	Note that this call is NOT thread safe! \n
	 */
	virtual bool StopPlugin();

	/// Needs to be overridden.
	void GetRuntime(double *Runtime, double *RuntimeStdDeviation=0);

	/**	@brief	The name that is shown in the player selection menu
	 *	@return	The name
	 *
	 *	@details
	 *	Source plugins may provide a name that is shown in the player selection menu.
	 *	If no name is provided, the default plugin name is used. This base class'
	 *	implementation returns an empty string.
	 *	@sa PluginBase::GetName()
	 */
	virtual QString GetNameForSelectionMenu();

	/**	@brief	Get the icon for this player
	 *	@return	The icon
	 *
	 *	@details
	 *	Get the (optional) icon for this player that is shown next to the player name in the
	 *	player selection menu. This base returns an empty icon. Note that providing an icon is not
	 *	mandatory!
	 */
	virtual QIcon GetIconForSelectionMenu();

public slots:
	/**	@brief	Slot that is connected to the pipelines NewFrame() signal
	 *
	 *	@details
	 *	This slot is connected to the acquisition pipelines NewFrame() signal which
	 *	allows the player to react when a new frame is actually available. The slot
	 *	is connected during the ConnectPipeline() method. \n
	 *	This base class' implementation does nothing, subclasses may overload this 
	 *	method to do more meaningful stuff (e.g. increase frame index).
	 */
	virtual void NewFrame();

	/**	@brief	Slot that is used to start the player
	 *
	 *	@details
	 *	In contrast to other plugins, a player is not automatically started when
	 *	registering at the manager. Invoking this slot will emit the StartSignal()
	 *	signal that should be connected to the manager.
	 *	@see StartSignal(SourcePlugin*)
	 */
	void StartSlot();

signals:
	/**	@brief	Signal that is used to start the player
	 *	@param	Player	Pointer to this instance
	 *
	 *	@details
	 *	This signal is emitted when the StartSlot() slot is invoked.
	 */
	void StartSignal(SourcePlugin* Player);

protected:
	/**	@name	The source at the beginning of the acquisition pipeline */
	//@{
	typedef RImageSourceF2	SourceType;
	typedef SourceType::Pointer SourcePointer;
	/**	@brief	Return the source for this player
	 *	@return	A pointer to the player specific source
	 *
	 *	@brief
	 *	This method returns the RImage source for this player. A player
	 *	that is intended to be used with a camera should therefore
	 *	return a camera source. Subclasses have to provide this
	 *	method which will be called by the SetPipelineSource
	 */
	virtual SourcePointer GetSource()=0;
	//@}

protected:
	/// The wrapped source
	SourcePointer m_Source;
	/// Pointer to the acquisition pipeline
	AcquisitionPipeline *m_AcquisitionPipeline;
};

} // end namespace ritk

#endif // SOURCEPLUGIN_H__