/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2024, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */
#pragma once

#include <mrpt/maps/CLandmarksMap.h>
#include <mrpt/maps/COccupancyGridMap2D.h>
#include <mrpt/system/CObserver.h>
#include <mrpt/vision/CFeatureExtraction.h>

namespace mrpt::slam
{
/**  A class for detecting features from occupancy grid maps.
 *   The main method is "COccupancyGridMapFeatureExtractor::extractFeatures()",
 * which makes use
 *    of an advanced cache mechanism to avoid redoing work when applied several
 * times on the same
 *    occupancy grid maps (unless they changed in the meanwhile).
 *
 *  For an uncached version (which is a static method that can be called
 * without instantiating COccupancyGridMapFeatureExtractor)
 *  see COccupancyGridMapFeatureExtractor::uncached_extractFeatures()
 *
 * \ingroup mrpt_slam_grp
 */
class COccupancyGridMapFeatureExtractor : public mrpt::system::CObserver
{
 public:
  /** Computes a set of distinctive landmarks from an occupancy grid, and
   * store them (previous content is not erased!) into the given landmarks
   * map.
   *   Landmarks type can be any declared in
   * mrpt::vision::CFeatureExtraction::TOptions
   *
   * \note See the paper "..."
   * \sa uncached_extractFeatures
   */
  void extractFeatures(
      const mrpt::maps::COccupancyGridMap2D& grid,
      mrpt::maps::CLandmarksMap& outMap,
      size_t number_of_features,
      const mrpt::vision::TDescriptorType descriptors,
      const mrpt::vision::CFeatureExtraction::TOptions& feat_options);

  /** Computes a set of distinctive landmarks from an occupancy grid, and
   * store them (previous content is not erased!) into the given landmarks
   * map.
   *   Landmarks type can be any declared in
   * mrpt::vision::CFeatureExtraction::TOptions
   *
   * \note See the paper "..."
   * \sa uncached_extractFeatures
   */
  static void uncached_extractFeatures(
      const mrpt::maps::COccupancyGridMap2D& grid,
      mrpt::maps::CLandmarksMap& outMap,
      size_t number_of_features,
      const mrpt::vision::TDescriptorType descriptors,
      const mrpt::vision::CFeatureExtraction::TOptions& feat_options);

 protected:
  /** This will receive the events from maps in order to purge the cache. */
  void OnEvent(const mrpt::system::mrptEvent& e) override;
  using TCache = std::map<const mrpt::maps::COccupancyGridMap2D*, mrpt::maps::CLandmarksMap::Ptr>;
  /** A cache of already computed maps. */
  TCache m_cache;

};  // End of class def.

}  // namespace mrpt::slam
