#ifndef __CAR_MANAGER__
#define __CAR_MANAGER__
#include "stdafx.h"
#include "car.h"
#include "bindmorecard.h"
#include "trafficLight.h"
#include "cacti/util/BoundedQueue.h"
class CYAServerDlg;
NAMESPACE_POINT_BEGIN(NAMESPACE_POINT)

struct MotionlessAlarm
{
	MotionlessAlarm(CarManager *cm);
	~MotionlessAlarm();
	bool find(std::shared_ptr<card_interface> &ci);
	void determine(std::shared_ptr<card_interface> &ci);
	void erase(std::shared_ptr<card_interface> &ci);
	void pushback(std::shared_ptr<card_interface> &ci);
	bool isMotionless(std::shared_ptr<card_interface> &ci);
private:
	CarManager *m_owner;
	bool m_bExit;
	std::thread *m_pTh;
	std::mutex m_mtx;
	std::list<std::shared_ptr<card_interface>> m_cardlist;
	void run();
};
class CarManager
{
public:
	CarManager(CYAServerDlg*);
	~CarManager();
	//--site--
	void init_sit_list(int32_t readerid,int32_t antid, double ax, double ay,double scale);
	void init_sit_list();
	void init_ant_path(int32_t readerid,int32_t antid, double ax, double ay,std::vector<std::string>::iterator& b,std::vector<std::string>::iterator& e);
	void init_ant_path();
	void init_cardpath();
	//--car--
	void put(std::string& cardid,const loc_info&li,std::shared_ptr<card_interface> &c,int32_t readerid);
	//------
	void erase(std::string cardid);
	loc_point getpoint(std::string cardid);
	//
	void update(int x,int y,std::string &cardid){m_g.update(x,y,cardid);}

	std::vector<std::string> find_near(int x,int y,int dist,std::string & c)
	{
		auto v = m_g.find_near(x,y,dist,c);
		return std::move(v);
	}
	std::shared_ptr<card_interface> getCard(const std::string &card_no)
	{
		auto card = m_cardList[card_no];
		if (card==nullptr)
			return nullptr;
		else
			return card->m_card;
	}
	void uwb_HandleMoreCard(std::shared_ptr<card_interface> &c);
	void erase(std::map<uint64_t,std::string> &m) ;
	void read_config();
	//
	std::vector<his_location> makeUpMorePoints(std::string & cardid,double x,double y, uint64_t ct,int32_t readerid);
	//
	void put(std::shared_ptr<TrafficLightGroup> t,int gid);
	std::shared_ptr<TrafficLightGroup> operator [](int gid)
	{
		auto it = m_Map.find(gid);
		if(it == m_Map.end())
			return nullptr;
		else
			return it->second;
	}
	std::shared_ptr<TrafficLightGroup> operator[](int gid) const
	{
		auto it = m_Map.find(gid);
		if(it == m_Map.end())
			return nullptr;
		else
			return it->second;
	}
	void showInfo();
	void initRule();
	void handleRule(std::shared_ptr<card_interface> c);
	std::shared_ptr<RunRedLight> check_run_red_light(std::shared_ptr<card_interface> c);
	void setManual(int gid,int lid,std::string name,int state);
	void cancelManual(int gid);
	void getSendLightInfo(std::vector<std::shared_ptr<TrafficLightGroup>>&& p,std::string s="");
	//////////
	void determineCard(std::shared_ptr<card_interface> & ci);
	void deal_alarm_card(std::shared_ptr<card_interface> & ci,bool flag);
	void erase(std::shared_ptr<card_interface> &ci);
	void push_back(std::shared_ptr<card_interface> &ci);
	std::map<int,std::shared_ptr<TrafficLightGroup>> m_Map;

	//add by zhuyf , 2018/11/05
	std::shared_ptr<TrafficLight> getTrafficLight(const uint32_t& light_id);			//获得灯号
	std::vector<uint32_t> getPhysicsTrafficLightId(const uint32_t& phy_light_id);		//获得物理灯号下所有灯号
	int getTrafficGroupId(const uint32_t& light_id);	//根据物理灯号获得灯组号
	bool resetTrafficGroup();
private:
	std::unique_ptr<sit_list> m_sites;
	base_card_list m_cardList;

	std::array<std::shared_ptr<CardFactory>,2> m_cf;
	geo_list m_g;
	CYAServerDlg* m_owner;

	std::array<std::shared_ptr<DecoratorRule>,2> m_dr;

	bool m_bExit;
	std::thread* m_pThread;
	MotionlessAlarm * m_ma;
	cacti::BoundedQueue<std::shared_ptr<TrafficLightGroup>> m_queue;
	double m_reddis;
private:
	void run();
};
NAMESPACE_POINT_END(NAMESPACE_POINT)
#endif