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

Program:		Range Imaging Toolkit (RITK)
Module:			ritkOpenGLVisualizationWidget.h
Version:		$Revision: 1761 $
Date:			$Date: 2011-09-23 17:25:41 +0200 (Fri, 23 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 OPENGLVISUALIZATIONWIDGET_H__
#define OPENGLVISUALIZATIONWIDGET_H__

#include "ritkVisualization.h"

#include <QtOpenGL>
#include <QGLWidget>
#include <QMutex>

#include "ritkOpenGLEntity.h"
#include "ritkOpenGLCamera.h"

namespace ritk
{

/**	@ingroup	Visualization
 *	@class		OpenGLVisualizationWidget
 *	@author		Jakob Wasza
 *	@brief		A visualization widget that uses OpenGL
 *
 *	@details
 */
class VISUALIZATION_EXPORT OpenGLVisualizationWidget : public QGLWidget
{
	Q_OBJECT

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

	/**	@name	Camera */
	//@{
	typedef OpenGLCamera				CameraType;
	typedef CameraType::Pointer			CameraPointer;
	typedef CameraType::ConstPointer	CameraConstPointer;
	void SetCamera(CameraPointer Camera);
	CameraPointer GetCamera();
	CameraConstPointer GetCamera() const;
	//@}

	/**	Add/remove entities */
	//@{
	bool AddEntity(OpenGLEntity *e);
	bool RemoveEntity(OpenGLEntity *e);
	//@}

public slots:
	/// Will update (i.e. paint) the widget
	void Update();

signals:
	/// Signal to establish communication with the ResetCamera method
	void ResetCameraSignal();

protected:
	/**	@name	Does the OpenGL part */
	//@{
	void initializeGL();
	void resizeGL(int width, int height);
	void paintGL();
	void closeGL();
	//@}

	/**	@name	Intercept mouse events */
	//@{
	void mouseMoveEvent(QMouseEvent *e);
	void mousePressEvent(QMouseEvent *e);
	void wheelEvent(QWheelEvent*);
	//@}

	/**	@name	Keyboard events */
	//@{
	void keyPressEvent(QKeyEvent *e);
	//@}

protected slots:
	/// Reset the camera
	void ResetCamera();

protected:
	/// Flag that indicates whether this widget (in particular the OpenGL extensions are initialized)
	bool m_InitFlag;

	/**	@name  Width and height of the drawing area */
	//@{
	int m_Width;
	int m_Height;
	//@}

	/// draw wireframe or faces
	bool m_DrawWire;

	/// Our camera
	CameraPointer m_Camera;

	/// Managed entities
	std::list<OpenGLEntity*> m_Entities;

	/// Last mouse point
	QPoint m_LastMousePos;

	/// Mutex used to synchronize rendering and data update
	QMutex m_Mutex;
};

} // end namespace ritk

#endif // OPENGLVISUALIZATIONWIDGET_H__
