/*---------------------------------------------------------------
	FILE: CSensorialFrame.h
	USE: Declares a class for storing a "sensorial frame", thus
	       a set of "observations" of the robot, taken exactly
		   from the same location.The "observations" can be of
		   many different kinds.

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

#include <MRPT/MRML/CObservation.h>
#include <MRPT/UTILS/CSerializable.h>
#include <MRPT/MRML/CPointsMap.h>

namespace MRML
{
	class	CSimplePointsMap;

	/** Declares a class for storing a "sensorial frame", thus
	 *      a set of "observations" of the robot, taken exactly
	 *	   from the same location.The "observations" can be of
	 *	   many different kinds.<br>
	  *  New observations can be added using:<br>
	  * \code
		  CObservation		*o = new XXX(...);
		  CSensorialFrame	sf;
		  sf.observations.push_back(o);
		\endcode
		Notice that observations objects are automatically deleted on
		Sensorial Frame destruction or clear.
	 * \sa CObservation
	 */
	class CSensorialFrame : public CSerializable
	{
		// This must be added to any CSerializable derived class:
		DEFINE_SERIALIZABLE( CSensorialFrame )
	private:
		CSimplePointsMap	*m_pointsMap;

	public:
		 /** Default constructor
		  */
		 CSensorialFrame();

		 /** Copy constructor
		  */
		 CSensorialFrame( const CSensorialFrame &);

		 /** Build (only on the first call), and return a simple points map built from the observations in the SF (options can be optionally provided to the map building process)
		   */
		 CSimplePointsMap	*buildAuxPointsMap( CPointsMap::TInsertionOptions	*ops = NULL );

		 /** Copy
		   */
		 void  operator =( const CSensorialFrame &o);

		 /** Destructor.
		  */
		 virtual ~CSensorialFrame();

		 /** Clear all current observations, also freeing them.
		  */
		 void		clear();

		 /** Dump all observations in a metric map. It calls CObservation::insertObservationInto for all stored observation.
		  * \param theMap The map where this observation is to be inserted: the map will be updated.
		  * \param robotPose The pose of the robot base for this observation, relative to the target metric map. Set to NULL (default) to use (0,0,0deg)
		  *
		  * \return Returns true if the map has been updated, or false if this observations
		  *			has nothing to do with a metric map (for example, a sound observation).
		  *
		  * \sa CObservation::insertObservationInto, CMetricMap::insertObservation
		  */
		 bool  insertObservationsInto( CMetricMap *theMap, const CPose3D *robotPose = NULL ) const;


		 /** You can use "sf1+=sf2;" to add observations in sf2 to sf1. Objects are copied, not referenced, thus the source can be safely deleted next.
		  */
		 void operator += (const CSensorialFrame &sf);

		 /** You can use "sf+=obs;" to add the observation "obs" to the "sf1". Objects are copied, not referenced, thus the source can be safely deleted next.
		  */
		 void operator += (const CObservation *obs);

		 /** An ID number, to be used by users.One possible use is to identify
		  *   sensorial frames in a graph.Default value is 0.
		  */
		 uint32_t			ID;

		 /** Returns the first observation of a given class (or of a descendant class), or NULL if there is no such observation in the array.
		   */
		 CObservation*	getObservationByClass( TRuntimeClassId	*classID );

		 /** The set of observations taken at the same time instant.
		  *  New observations can be added using:<br>
		  * \code
		      CObservation		*o = new XXX(...);
			  CSensorialFrame	sf;
			  sf.observations.push_back(o);
			\endcode
			Notice that observations objects are automatically deleted on
			Sensorial Frame destruction or clear.
		  */
		 std::deque<CObservation*>	observations;

	}; // End of class def.

} // End of namespace

#endif
