#ifndef __MONKEYCAR_BUS__
#define __MONKEYCAR_BUS__

#include <numeric>
#include "base_data.h"
#include <thread>
#include <mutex>

#define K_MEANS_X1 0.5
#define K_MEANS_X2 1.8
#define K_MEANS_x3 3.0

#define ON_BUS_SPEED_LIMIT 0.95
#define ON_BUS_SPEED_MAX_LIMIT 2
#define OFF_BUS_SPEED_LIMIT 0.67

#define ADJUST_DISTANCE_TIMEVAL (5 * 60 * 1000)

#define PERSON_SEND_TIME_INTERVAL (2 * 1000) // 2s intervel
#define GROUPING_PERSON_DISTANCE 20   // 60/map_scale  now is 60m
#define GROUPING_PERSON_NUMBER   5
#define FIT_COUNT_LIMIT (ADJUST_DISTANCE_TIMEVAL/PERSON_SEND_TIME_INTERVAL)*6.0/10

#define LONG_TIME_NO_DATA (1*60*1000)  //1 min no data recv. 
enum DIRECTION{
	NO_DIRECTION = 0,
	POSTIVE_DIRECTION,
	NEGTIVE_DIRECTION
};
struct monkey_person;
struct monkey_bus
{
	monkey_bus(double speed, int direct);
	~monkey_bus()
	{
		m_stop = true;
		m_thread->join();
	}

	bool test_get_on(double speed);
	
	/********************************/
	/*Decide whether to get off or not*/
	/******************************/
	bool test_get_off(std::shared_ptr<monkey_person> mp,double speed);
	//get the average speed 
	void Set_AverageSpeed(double speed);
	//get off the bus 
	void getOffTheBus(std::shared_ptr<monkey_person> mp);
	//get on the bus
	void getOnTheBus(std::shared_ptr<monkey_person> mp,std::shared_ptr<monkey_bus> bus);

	//get step length
	inline double getNextStep_Distance(double time_val)
	{
		return m_speed * time_val;
	}
private:
	std::vector<std::shared_ptr<monkey_person>> person_list_;
	double m_speed;
	int    m_direct;
	std::unique_ptr<std::thread> m_thread;
	std::mutex m_mtx;
	void adjust_monkeyperson_distance();
	bool m_stop;
};
#endif
