#include "cardMgr.h" 
#include "bindmorecard.h"
#include "common.h"
#include"common_tool.h"

cardMgr::cardMgr()
:m_queue(2048)
	,m_bstop(false)
{
	m_pThread.reset(new std::thread(std::bind(&cardMgr::run,this)));
	m_cf[0] = std::make_shared<CloserCardFactory>(this);
	m_cf[1] = std::make_shared<RemoteCardFactory>(this);
}
void cardMgr::run()
{
	while(!m_bstop)	
	{
		Msg m;
		m_queue.get(m);
		onMessage(m);
	}
}
void cardMgr::onMessage(const Msg &m)
{
	switch(m.cmd)
	{
		case CMD_CLEAR:
			clear(m.cardid);
			break;
		case CMD_HANDLE:
			handleMessage(m);
			break;
		default:
			break;
	}
}
void cardMgr::clear(uint64_t cardid)
{
	auto v = m_cgraph.getcard(cardid);
	for(const auto & cid:v)
	{
		uint64_t id = MyHash{}(cardid,cid);
		erase(id);
		m_cgraph.remove_edge(cardid,cid);
	}
}
void cardMgr::handleMessage(const Msg &m)
{
	m_glist.update(m.x,m.y,m.cardid);
    if(tool_other::is_vehicle( m.type) ) return;
	std::vector<uint64_t> rc=m_glist.find_near(m.cardid,1);
	
	log_info("LemonHash+..%d,size:%d,(%d,%d)",m.cardid,rc.size(),m.x,m.y);
	std::map<uint64_t,std::string> map1;
	std::map<uint64_t,std::string> map2;
	for(int i = m_cf.size()-1;i>=0;i--)
	{
		map1.clear();map2.clear();
		map1=m_cf[i]->selectcard(rc,m.cardid);
		map2=m_cf[i]->setCT(m.cardid);
		std::copy(map1.begin(),map1.end(),std::inserter(map2,map2.end()));

		if (i == 1 && !map2.empty())
		  erase(map2);

		if (!map2.empty())
		{
			for(const auto x:map2)
				log_info("---LemonHash----[%s]%s",i?"Remote":"Closer",x.second.c_str());
			//m_owner->uwb_alarm(map2,i,c);
		}
		if (!rc.empty())
		{
			std::string s ;
			s = m_cf[i]->InfoMessage();
			log_info("---LemonHash----[%s]%s",i?"Remote":"Closer",s.c_str());
		}
	}
}
void cardMgr::erase(const std::map<uint64_t,std::string> &m)
{
	for(auto &p:m)
	  erase(p.first);
}
void cardMgr::erase(uint64_t id)
{
	for(const auto & t:m_cf)
	  t->erase(id);
}
cardMgr::~cardMgr()
{
	m_bstop = true;
	m_pThread->join();
}
cardMgr* cardMgr::instance()
{
	static cardMgr cd;
	return &cd;
}