/*---------------------------------------------------------------
	FILE: CBeacon.h
	USE: See doc above

   Part of the MRPT Library
   ISA - Universidad de Malaga - http://www.isa.uma.es
  ---------------------------------------------------------------*/
#ifndef CBeacon_H
#define CBeacon_H

#include <MRPT/UTILS/CSerializable.h>
#include <MRPT/UTILS/CMatrix.h>
#include <MRPT/UTILS/SystemUtils.h>
#include <MRPT/UTILS/CStringList.h>
#include <MRPT/MRML/CPoint3D.h>
#include <MRPT/MRML/CPointPDFParticles.h>
#include <MRPT/MRML/CPointPDFGaussian.h>
#include <MRPT/MRML/CPointPDFSOG.h>

namespace MRML
{
	/** The class for storing individual "beacon landmarks" under a variety of 3D position PDF distributions.
	  *  This class is used for storage within the class CBeaconMap.
	  *  The class implements the same methods than the interface "CPointPDF", and invoking them actually becomes
	  *   a mapping into the methods of the current PDF representation of the beacon, selectable by means of "m_typePDF"
	  * \sa CBeaconMap, CPointPDFSOG
	  */
	class CBeacon : public CPointPDF
	{
		// This must be added to any CSerializable derived class:
		DEFINE_SERIALIZABLE( CBeacon )

	public:
		/** The type for the IDs of landmarks.
		  */
		typedef	uint64_t TBeaconID;

		/** See m_typePDF
		  */
		enum TTypePDF { pdfMonteCarlo = 0, pdfGauss, pdfSOG };

		/** Which one of the different 3D point PDF is currently used in this object: montecarlo, gaussian, or a sum of gaussians.
		  * \sa m_location
		  */
		TTypePDF	m_typePDF;

		/** The individual PDF, if m_typePDF=pdfMonteCarlo (publicly accesible for ease of use, but the CPointPDF interface is also implemented in CBeacon).
		  */
		CPointPDFParticles	m_locationMC;

		/** The individual PDF, if m_typePDF=pdfGauss (publicly accesible for ease of use, but the CPointPDF interface is also implemented in CBeacon).
		  */
		CPointPDFGaussian	m_locationGauss;

		/** The individual PDF, if m_typePDF=pdfSOG (publicly accesible for ease of use, but the CPointPDF interface is also implemented in CBeacon).
		  */
		CPointPDFSOG		m_locationSOG;

		/** An ID for the landmark (see details next...)
		  *  This ID was introduced in the version 3 of this class (21/NOV/2006), and its aim is
		  *  to provide a way for easily establishing correspondences between landmarks detected
		  *  in sequential image frames. Thus, the management of this field should be:
		  *		- In 'servers' (classes/modules/... that detect landmarks from images): A different ID must be assigned to every landmark (e.g. a sequential counter), BUT only in the case of being sure of the correspondence of one landmark with another one in the past (e.g. tracking).
		  *		- In 'clients': This field can be ignored, but if it is used, the advantage is solving the correspondence between landmarks detected in consequentive instants of time: Two landmarks with the same ID <b>correspond</b> to the same physical feature, BUT it should not be expected the inverse to be always true.
		  *
		  * Note that this field is never fill out automatically, it must be set by the programmer if used.
		  */
		TBeaconID			m_ID;

		/** Default constructor
		  */
		CBeacon();

		/** Virtual destructor
		  */
		virtual ~CBeacon();

		 /** Returns an estimate of the point, (the mean, or mathematical expectation of the PDF)
		  */
		CPoint3D  getEstimatedPoint() const;

		 /** Returns an estimate of the point covariance matrix (3x3 cov.matrix for x,y,z variables)
		  */
		CMatrix  getEstimatedCovariance() const ;

		/** Copy operator, translating if necesary (for example, between particles and gaussian representations)
		  */
		void  copyFrom(const CPointPDF &o);

		/** Save PDF's particles to a text file. See derived classes for more information about the format of generated files.
		 */
		void  saveToTextFile(char *file) const;

		/** This can be used to convert a PDF from local coordinates to global, providing the point (newReferenceBase) from which
		  *   "to project" the current pdf. Result PDF substituted the currently stored one in the object.
		  */
		void  changeCoordinatesReference( const CPose3D &newReferenceBase );

		/** Saves a 3D representation of the beacon into a given OpenGL scene
		  */
		void  getAs3DObject( UTILS::OPENGL::CSetOfObjects	&outObj ) const;

		/** Gets a set of MATLAB commands which draw the current state of the beacon:
		  */
		void getAsMatlabDrawCommands( UTILS::CStringList &out_Str ) const;


	}; // End of class definition


} // End of namespace

#endif
