#include "monkeycar_area.h"
#include "monkeycar_bus.h"
#include "monkeycar_person.h"
#include "card.h"
#include "log.h"
#include "common.h"

uint64_t monkey_area::m_startTime=time(NULL)*1000;

monkey_area::monkey_area(std::shared_ptr<db_area> dap,int area_id,int over_count_person,int over_time_person,double scale,int32_t mapid,int32_t type)
	:area(area_id,over_count_person,over_time_person,scale,mapid,type)
	,m_path(dap->m_point.begin(),dap->m_point.end())	
{
	log_info("monkeycar _area init ");
	std::shared_ptr<monkey_bus> bus = std::make_shared<monkey_bus>(dap->m_default_speed,NEGTIVE_DIRECTION);
	bus_.push_back(bus);

	bus = std::make_shared<monkey_bus>(dap->m_default_speed * -1.0,POSTIVE_DIRECTION);
	bus_.push_back(bus);
}


std::shared_ptr<monkey_person> monkey_area::find(uint32_t cardid)
{
	std::lock_guard<std::mutex> lk(m_mtx);
	auto it =  card_map_.find(cardid);
	if(it == card_map_.end())
		return nullptr;
	return it->second;
}

void monkey_area::on_hover(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c)
{
	area::on_hover(a,c);
	if(c->m_type != CT_PERSON)return;

	st_coord pt;
	pt.x_=c->x;
	pt.y_=c->y;
	pt.m_ct = c->m_ct;
	pt.gen_time_ = c->m_time-m_startTime;

	on_card_move(c->m_id,pt,c->m_type);


}
void monkey_area::on_enter(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c)
{
	area::on_enter(a,c);
	if(c->m_type != CT_PERSON)return;
	on_card_enter(c);

}
void monkey_area::on_leave(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c)
{
	area::on_leave(a,c);
	if(c->m_type != CT_PERSON)return;
	on_card_leave(c->m_id);

}
void monkey_area::on_card_leave(uint32_t cardid)
{
	log_info("[monkeycar on_card_leave]cardId:%d",cardid);
	std::lock_guard<std::mutex> lk(m_mtx);
	auto it = card_map_.find(cardid);
	if (it != card_map_.end())
	{
		if(auto tbus = it->second->getBus())
			tbus->getOffTheBus(it->second);
		card_map_.erase(it);
	}
	
}
void monkey_area::on_card_enter(const std::shared_ptr<card_location_base> &card)
{
	log_info("[monkeycar on_card_enter]cardId:%d",card->m_id);
	auto me = shared_from_this();

	std::shared_ptr<monkey_person> mp = std::make_shared<monkey_person>(me);

	card->reset(mp);

	std::lock_guard<std::mutex> lk(m_mtx);
	card_map_.insert(std::make_pair(card->m_id,mp));
}
void monkey_area::on_card_move(uint32_t cardid,const st_coord & st,uint64_t type)
{
	log_info("[monkeycar on_card_move]cardId:%d",cardid);
	//auto me = shared_from_this();
	auto mp=find(cardid);
	if (!mp)
	{
		//if not exist ,create it .because may be restart the system.then area has not changed.
		uint64_t id=type<<32|cardid;
		if(auto c=card_list::instance()->get(id))
			on_card_enter(c); 
		return ;
	}
	bool ret = mp->on_step_map(st);
	if (!ret)
		return;
	double speed=0;
	bool b=mp->fit_speed(&speed);
	if (!b || speed == DBL_MAX)
		return ;
	//on bus
	speed *= 1000;
	log_info("monkeycar speed :cardid:%d,speed:%.2f",cardid,speed);
	if(auto tbus = mp->getBus())
	{
		if(!tbus->test_get_off(mp,speed))
		{
			log_info("monkeycar get off id:%d",cardid);
			tbus->getOffTheBus(mp);	
		}
	}
	else
	{
		std::shared_ptr<monkey_bus> bus=bus_[speed>0?0:1];
		if(bus->test_get_on(speed))
		{
			log_info("monkeycar get onid:%d",cardid);
			bus->getOnTheBus(mp,bus);	
		}
	}
}