#ifndef _LOC_CORE_LOCALIZATION_H_INCLUDED_
#define _LOC_CORE_LOCALIZATION_H_INCLUDED_
#include <ros/ros.h>
#include <tf2_ros/buffer.h>
#include <tf/tf.h>
#include <memory>
#include <geometry_msgs/PoseStamped.h>
#include <geometry_msgs/Pose2D.h>
// #include <loc_core/common.h>

namespace loc_core
{
	enum slam_state_en
	{
		Mapping,
		Localization,
		Calibrations,
		Ready,
		Error
	};

	/**
	 * @class BaseLocalization
	 * @brief Provides an interface for locazation
	 * @brief All package written as plugins for the localization stack must adhere to this interface.
	*/
	class BaseLocalization
	{
	public:
		using Ptr = std::shared_ptr<BaseLocalization>;

		/**
		 * @brief  Virtual destructor for the interface
		 */
		virtual ~BaseLocalization() {}

		/**
		 * @brief Initialization function for loc base
		 * @param nh  A Node handle
		 * 
		*/
		virtual void initialize(ros::NodeHandle nh, std::shared_ptr<tf2_ros::Buffer> tf) = 0;

		/**
		 * @brief Loading a Activate Map File name 
		 * @param activated_map_filename The Map File name 
		 * @return True if activated_map_filename is exsits, else Fasle
		 */
		virtual bool loadActivateMapFileName(std::string& activated_map_filename) = 0;

		/**
		 * @brief Saving a Activate Map File name 
		 * @param activated_map_filename The Map File name 
		 * @return True if activated_map_filename is exsits, else Fasle
		 */
		virtual bool saveActivateMapFileName(const std::string& activated_map_filename) = 0;

		/**
		 * @brief Create any files to a folder of the path
		 * @param path The path where is be saved any files (png, yaml ...)
		 * @param map_name The name folder and files
		 */
		virtual bool createStaticMap(const std::string map_name) = 0;

		/**
		* @brief Load a map given a path to a yaml file
		* @param filename The file name
		* @return True/False If load map succesed or not done
		*/
		virtual bool changeStaticMap(const std::string filename) = 0;

		/**
		* @brief Load a virtual walls map given a path to a yaml file
		* @param filename The file name
		* @return True/False If load map succesed or not done
		*/
		virtual bool changeVirtualWallsMap(const std::string filename) = 0;

		/**
		* @brief Get the list of map folder in the workingdirection
		* @param directories The list map name
		*/
		virtual void listMapFiles(std::stringstream &directories) = 0;

		/**
		 * @brief Start the mapping process.
		 * 				When the state variable 'SlamState' is 'Ready', this function can be called.
		 * 				Upon successful invocation, the state variable 'SlamState' will change to 'Mapping'.
		 * @return True/False Call fucntion is successed/failed.
		 */
		virtual bool startMapping() = 0;

		/**
		 * @brief Turn off the Localization mode.
		 * 				At this point, the robot's coordinate information will not be updated.
		 * 				If called successfully, the 'SlamState' variable will change to 'Ready'.
		 * @return True/False Call fucntion is successed/failed
		 */
		virtual bool stopMapping() = 0;

		/**
		 * @brief Set the initial position of the robot on the map.
		 *        The condition to call the function is that the 'SlamState' is 'Localization'.
		 *        When the function is called successfully, the 'SlamState' will change to 'Calibrations'.
		 *        When the 'Calibrations' process ends, the 'SlamState' will change back to 'Localization'.
		 * @return True/False Call fucntion is successed/failed
		 */
		virtual bool startLocalization() = 0;

		/**
		 * @brief Turn off the Localization mode.
		 * 				At this point, the robot's coordinate information will not be updated.
		 * 				If called successfully, the 'SlamState' variable will change to 'Ready'.
		 * @return True/False Call fucntion is successed/failed
		 */
		virtual bool stopLocalization() = 0;

		/**
		 * @brief Get State of Loc Base
		 */
		virtual loc_core::slam_state_en getState() = 0;

		std::string activated_map_filename_;
		std::string working_dir_;
		std::string map_topic_;

	protected:
		/**
		 * @brief  Constructor for the interface
		 */
		BaseLocalization() {};
	}; // class BaseLocalization

} // namespace loc_core

#endif // _LOC_CORE_LOCALIZATION_H_INCLUDED_