/*---------------------------------------------------------------
	FILE: CPointPDFParticles.h
	USE: See above.

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

#include <MRPT/MRML/CPointPDF.h>
#include <MRPT/UTILS/CMatrix.h>
#include <MRPT/UTILS/CProbabilityParticle.h>
#include <MRPT/UTILS/CParticleFilterData.h>

namespace MRML
{
	/** Data within each particle
	  */
	struct TSimple3DPoint
	{
		TSimple3DPoint(const TSimple3DPoint&o) : x(o.x),y(o.y),z(o.z)
		{
		}

		TSimple3DPoint() : x(0),y(0),z(0)
		{
		}

		TSimple3DPoint(const CPoint3D &v) : x(v.x),y(v.y),z(v.z)
		{
		}

		float	x,y,z;
	};

	/** A probability distribution of a 2D/3D point, represented as a set of random samples (particles).
     *
	 * \sa CPointPDF
	 */
	class CPointPDFParticles : public CPointPDF, public CParticleFilterData<TSimple3DPoint>
	{
		// This must be added to any CSerializable derived class:
		DEFINE_SERIALIZABLE( CPointPDFParticles )

		// This uses CParticleFilterData to implement some methods required for CParticleFilterCapable:
		IMPLEMENT_PARTICLE_FILTER_CAPABLE(TSimple3DPoint);

	 public:
		/** Default constructor
		  */
		CPointPDFParticles(size_t numParticles = 1);

		/** Copy constructor
		  */
		CPointPDFParticles(const CPointPDFParticles &obj);

		/** Assignament operator:
		  */
		void operator = (const CPointPDFParticles &obj);

		/** Destructor
		  */
		virtual ~CPointPDFParticles();

		/** Clear all the particles (free memory)
		  */
		void clear()  { setSize(0);	}

		/** Erase all the previous particles and change the number of particles, with a given initial value
		  */
		void setSize(size_t numberParticles, const CPoint3D &defaultValue = CPoint3D(0,0,0) );

		/** Returns the number of particles
		  */
		size_t size() const
		{
			return m_particles.size();
		}

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

		 /** Returns an estimate of the pose covariance matrix (3x3 cov.matrix  for x,y,phi 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, where each line is: X Y Z LOG_W
		 */
		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. Both the mean value and the covariance matrix are updated correctly.
		  */
		void  changeCoordinatesReference( const CPose3D &newReferenceBase );

		/** Compute the kurtosis of the distribution.
		  */
		double computeKurtosis();


	}; // End of class def.

} // End of namespace

#endif
