/* +---------------------------------------------------------------------------+
   |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
   |                                                                           |
   |                   http://mrpt.sourceforge.net/                            |
   |                                                                           |
   |   Copyright (C) 2005-2008  University of Malaga                           |
   |                                                                           |
   |    This software was written by the Perception and Robotics               |
   |      research group, University of Malaga (Spain).                        |
   |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
   |                                                                           |
   |  This file is part of the MRPT project.                                   |
   |                                                                           |
   |     MRPT is free software: you can redistribute it and/or modify          |
   |     it under the terms of the GNU General Public License as published by  |
   |     the Free Software Foundation, either version 3 of the License, or     |
   |     (at your option) any later version.                                   |
   |                                                                           |
   |   MRPT 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 the         |
   |     GNU General Public License for more details.                          |
   |                                                                           |
   |     You should have received a copy of the GNU General Public License     |
   |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
   |                                                                           |
   +---------------------------------------------------------------------------+ */
#ifndef  CDisplayWindowPlots_H
#define  CDisplayWindowPlots_H

#include <MRPT/UTILS/utils_defs.h>
#include <MRPT/config.h>
#include <MRPT/UTILS/SYNCH.h>
#include <MRPT/UTILS/CMatrixTemplateNumeric.h>
#include <MRPT/UTILS/safe_pointers.h>

/*---------------------------------------------------------------
	Class
  ---------------------------------------------------------------*/
namespace UTILS
{
	/** Create a GUI window and display plots with MATLAB-like interfaces and commands.
	 *   See CDisplayWindowPlots::plot
	 */
	class CDisplayWindowPlots
	{
    public:
		/** This semaphore will be signaled when the wx window is built and ready.
		  */
		SYNCH::CSemaphore 	m_semThreadReady;

		/** This semaphore will be signaled when the wx window is destroyed.
		  */
		SYNCH::CSemaphore 	m_semWindowDestroyed;


		/** Read-only access to the wxDialog object.
		  */
		void * getWxObject() { return m_hwnd.get(); }

		/** Called by wx main thread to set m_hwnd to NULL.
		  */
		void notifyChildWindowDestruction();

	protected:
		/** The caption of the window:
		  */
		std::string		m_caption;

		/** The window's handle
		  */
		void_ptr_noncopy m_hwnd;

		/** Auxiliary
		  */
		volatile bool	m_keyPushed;

	public:
		/** Constructor
		 */
		CDisplayWindowPlots(
			const std::string &windowCaption = std::string(),
			unsigned int initialWidth = 350,
			unsigned int initialHeight = 300 );

		/** Destructor
		 */
		~CDisplayWindowPlots();

		/** Returns false if the user has already closed the window.
		  */
		bool isOpen();

		/** Resizes the window, stretching the image to fit into the display area.
		 */
		void  resize( unsigned int width, unsigned int height );

		/** Changes the position of the window on the screen.
		 */
		void  setPos( int x, int y );

		/** Waits for any key to be pushed on the image
		  */
		void  waitForKey( );

		/** Changes the window title text.
		  */
		void  setWindowTitle( const std::string &str );

		/** Enable/disable the feature of pan/zoom with the mouse (default=enabled)
		*/
		void  enableMousePanZoom( bool enabled );

		/** Adds a new layer with a 2D plot based on two vectors of X and Y points, using a MATLAB-like syntax.
		  *  Each call to this function creates a new plot, unless the plot name coincides with an already existing plot: in this case the X & Y points are used to update this existing layer (this also applies to using the default plot name).
		  *  The lineFormat string is a combination of the following characters:
		  * - Line styles:
		  *		- '.': One point for each data point
		  *		- '-': A continuous line
		  *		- ':': A dashed line
		  * - Colors:
		  *		- k: black
		  *		- r: red
		  *		- g: green
		  *		- b: blue
		  *		- m: magenta
		  *		- c: cyan
		  * - Line width:
		  *		- '1' to '9': The line width (default=1)
		  *
		  *  Examples:
		  *   - 'r.' -> red points.
		  *   - 'k3' or 'k-3' -> A black line with a line width of 3 pixels.
		  * \sa axis, axis_equal, axis_fit
		  */
		void plot(
			const vector_float &x,
			const vector_float &y,
			const std::string  &lineFormat,
			const std::string  &plotName = std::string("plotXY") );

		/** Adds a new layer with a 2D plot based on two vectors of X and Y points, using a MATLAB-like syntax.
		  *  Each call to this function creates a new plot, unless the plot name coincides with an already existing plot: in this case the X & Y points are used to update this existing layer (this also applies to using the default plot name).
		  *  The lineFormat string is a combination of the following characters:
		  * - Line styles:
		  *		- '.': One point for each data point
		  *		- '-': A continuous line
		  *		- ':': A dashed line
		  * - Colors:
		  *		- k: black
		  *		- r: red
		  *		- g: green
		  *		- b: blue
		  *		- m: magenta
		  *		- c: cyan
		  * - Line width:
		  *		- '1' to '9': The line width (default=1)
		  *
		  *  Examples:
		  *   - 'r.' -> red points.
		  *   - 'k3' or 'k-3' -> A black line with a line width of 3 pixels.
		  * \sa axis, axis_equal, axis_fit
		  */
		void plot(
			const vector_double &x,
			const vector_double &y,
			const std::string  &lineFormat = std::string("b-"),
			const std::string  &plotName = std::string("plotXY") );

		/** Set the view area according to the passed coordinated.
		  */
		void axis( float x_min, float x_max, float y_min, float y_max, bool aspectRatioFix = false );

		/** Enable/disable the fixed X/Y aspect ratio fix feature (default=disabled).
		  */
		void axis_equal(bool enable=true);

		/** Fix automatically the view area according to existing graphs.
		  */
		void axis_fit(bool aspectRatioFix=false);

		/** Plots a 2D ellipse given its mean, covariance matrix, and
		  *  Each call to this function creates a new plot, unless the plot name coincides with an already existing plot: in this case the new values are used to update this existing layer (this also applies to using the default plot name).
		  *  For a description of lineFormat see CDisplayWindowPlots::plot.
		  *  The "quantiles" value determines the confidence interval for the ellipse:
		  *     - 1 : 68.27% confidence interval
		  *     - 2 : 95.45%
		  *     - 3 : 99.73%
		  *     - 4 : 99.994%
		  */
		void plotEllipse(
			const float &mean_x,
			const float &mean_y,
			const CMatrixTemplateNumeric<float> &cov22,
			const float &quantiles,
			const std::string  &lineFormat = std::string("b-"),
			const std::string  &plotName = std::string("plotEllipse") );


	}; // End of class def.

} // End of namespace

#endif
