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

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkRImageFilePlayerWidget.h
	Version:		$Revision: 2734 $
	Date:			$Date: 2012-03-07 13:17:13 +0100 (Mi, 07 Mrz 2012) $

	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 RIMAGEFILEPLAYERWIDGET_H__
#define RIMAGEFILEPLAYERWIDGET_H__

#include <QWidget>
#include "ui_ritkRImageFilePlayerWidget.h"

#include <QMutex>

namespace ritk
{

/** @ingroup	Core
 *	@class		RImageFilePlayerWidget
 *	@author		Sebastian Bauer / Jakob Wasza
 *	@brief		Widget intended to be used with a RImageFilePlayer
 *
 *	@details
 *	This widget provides the graphical interface for controlling a range image file player.
 *	The widget therefore defines valid states and a set signals that are emitted upon
 *	user interaction. Such interactions in general change the state of the widget but it
 *	is not possible for the widget to determine whether the triggered event really succeeded
 *	(e.g. opening a file could fail). Therefore, the widget will not update its state. This has
 *	to be done by the object that is connected to the signal via the SetState() method. Upon
 *	the next call to UpdateGUI() the widget will match its GUI to the current state.
 *	Note that due to limitations of Qt the call to UpdateGUI() may only performed from the main thread context.
 *	Slots therefore have to trigger the GUI update through sending an event (postEvent);
 */
class RImageFilePlayerWidget : public QWidget, public Ui_RImageFilePlayerWidget
{
	Q_OBJECT

public:
	/// Constructor
	RImageFilePlayerWidget(QWidget *parent = 0);
	/// Destructor
	virtual ~RImageFilePlayerWidget();

	//@{
	enum FileInterfaceStateType 
	{
		ClosedState, 
		OpenedState, 
		PlayForwardState, 
		PlayBackwardState,
	};
	/// Set the state
	void SetState(FileInterfaceStateType State);
	/// Get the state
	FileInterfaceStateType GetState();
	//@}

	/// Set the file name for this widget. To be used before UpdateGUI()
	void SetFileName(QString FileName);

	/// Set the number of available frames. To be used before UpdateGUI()
	void SetNumberOfFrames(unsigned long);

	/// Set the image resolution. To be used before UpdateGUI()
	void SetImageResolution(unsigned int SX, unsigned int SY);

	/// Set the current frame id
	void SetFrameID(unsigned long);

public slots:
	/// Will update the GUI to match the current state.
	void UpdateGUI();

	/** @name Usere interaction signals*/
	//@{
signals:
	/// Signal emitted when the user selects a file to play. Parameter is the file name
	void OpenFileEvent(QString FileName);
	/// Signal emitted when the user pushes the pause button
	void PauseEvent();
	/// Signal emitted when the user pushed the stop button
	void StopEvent();
	/// Signal emitted when the user pushes the play-backward button
	void PlayBackwardEvent();
	/// Signal emitted when the user pushes the play-forward button
	void PlayForwardEvent();
	/// Signal emitted when the user pushes the step-backward button
	void StepBackwardEvent();
	/// Signal emitted when the user pushes the step-forward button
	void StepForwardEvent();
	/// Signal emitted when the user enters a specific frame number. Parameter is the index of the frame
	void GoToFrameEvent(unsigned long FrameID);
	/// Signal emitted when the user klicks the loop checkbox. Parameter is whether looping is enabled or disabled
	void ToggleLoopEvent(bool Enabled);
	/// Signal emitted when the user klicks the timestamp delivery checkbox. Parameter is whether timestamp delivery is enabled or disabled
	void ToggleTimestampDeliveryEvent(bool Enabled);
	/// Signal emitted when the frame interval changes the frame interval slider.
	void FrameIntervalEvent(int Interval);
	//@}	

protected slots:
	/// Intermediate function for selecting a file. Will emit OpenFileEvent() if a valid name is selected
	void SelectFile();
	/// Intermediate function for entering a frame index. Will emit GoToFrameEvent()
	void EnterFrameIndex();
	/// Intermediate function for managing looping. Will emit ToggleLoopEvent()
	void LoopEvent();
	/// Intermediate function for managing timestamp delivery. Will emit ToggleTimestampDeliveryEvent()
	void TimestampDeliveryEvent();
	/// Intermediate function for the slider Will emit GoToFrameEvent(). Connecting directly does not work
	void SliderValueChanged(int);
	/// Intermediate function for the frame interval slider. Will emit FrameIntervalEvent(). 
	void SliderFrameIntervalChanged(int);
	/// Intermediate function for the frame interval line edit. Will emit FrameIntervalEvent().
	void LineEditFrameIntervalChanged(const QString &Text);

protected:
	/// The current state of the widget
	FileInterfaceStateType m_CurrentState;
	/// Mutex used to lock the current state
	QMutex m_StateMutex;
	/// The current file name (only valid if the state is set to OpenedState)
	QString m_CurrentFileName;
	/// The number of available frames (only valid if the state is set to OpenedStated)
	unsigned long m_NumberOfFrames;
	/// The current frame id provided by the player
	unsigned long m_CurrentFrameID;
	/// The resolution of the images contained in the sequence
	unsigned int m_ImageResolution[2];
};

} // end namespace ritk

#endif //RIMAGEFILEPLAYERWIDGET_H__
