#include "stdafx.h"
#include "monkeycar_bus.h"

#ifndef WIN32
#include <unistd.h>
#endif
monkey_bus::monkey_bus(double speed, int direct)
	:m_speed(speed)
	,m_direct(direct)
	,m_stop(false)
{
	//m_time_stamp = cacti::Timestamp::getNowTime().getAsMilliseconds();
}
void monkey_bus::start()
{
	//start a thread.
	m_thread.start(this,&monkey_bus::adjust_monkeyperson_distance);
}
void monkey_bus::adjust_monkeyperson_distance()
{
	bool cflag = false;
	std::vector<std::shared_ptr<monkey_person>> v;
	static u64 s_time=0;
	while (!m_stop)
	{
		v.clear();
		u64 nowTime = cacti::Timestamp::getNowTime().getAsMilliseconds();
		{
			ScopedLock lk(m_monitor);
			std::for_each(person_list_.begin(),person_list_.end(),[&](const std::shared_ptr<monkey_person> mp){
				if (nowTime - mp->m_adjustDis_timeval >= ADJUST_DISTANCE_TIMEVAL/2 && !cflag)
				{
					mp->setCompensationSpeed(0);
					cflag = true;
				}
				if (nowTime - mp->m_adjustDis_timeval >= ADJUST_DISTANCE_TIMEVAL)
				{
					mp->m_adjustDis_timeval = nowTime;
					mp->handle_monkeycar_fit(1.*(nowTime-m_Start_time)/1000.0);
					cflag = false;
				}
			});
			std::for_each(person_list_.begin(),person_list_.end(),[&](const std::shared_ptr<monkey_person> mp){
				if (nowTime-mp->m_timestamp > LONG_TIME_NO_DATA)
					v.push_back(mp);
			});
		}
		std::for_each(v.begin(),v.end(),[&](const std::shared_ptr<monkey_person>& mp){
			getOffTheBus(mp);
		});
		if (nowTime-s_time > 1000)
		{
			s_time = nowTime;
		}
#ifndef WIN32
		usleep(100*1000);
#else 
		Sleep(100);
#endif // WIN32

		
	}
}

bool monkey_bus::test_get_on(std::shared_ptr<monkey_person> mp,double speed)
{
	//debug_print_syslog(0,"[lemon the second choice false]cardId:%s,v:%f",mp->getCardId().c_str(),speed);
	if (fabs(speed) >= fabs(m_speed) * ON_BUS_SPEED_LIMIT && fabs(speed) <fabs(m_speed) * ON_BUS_SPEED_MAX_LIMIT)
	{
		//debug_print_syslog(0,"[lemon the second choice GetOn]cardId:%s",mp->getCardId().c_str());
		return true;
	}
	return false;
}
/*******************************
/*判断人是否下猴车
/******************************/
bool monkey_bus::test_get_off(std::shared_ptr<monkey_person> mp,double speed)
{
	bool ret = false;
	//Get The AverageSpeed
	//Set_AverageSpeed(abs(speed));
	//判断其方向
	ret = (speed > ZERO_ ? NEGTIVE_DIRECTION:POSTIVE_DIRECTION) == m_direct ;
	//----------------------------------------
	if (ret)
	{
		if (fabs(speed) < fabs(m_speed) * OFF_BUS_SPEED_LIMIT)
		{
			//debug_print_syslog(0,"[lemon the second choice true]cardId:%s,v:%f",mp->getCardId().c_str(),speed);

			if(mp->Judge_OffIndex())
			{
				ret = false;
			}
		}
		else
		{
			mp->resetOffIndex();
		}
	}
	debug_print_syslog(0,"[lemon the second choice true___]cardId:%s,v:%f,state:%s",mp->getCardId().c_str(),speed,ret?"ON":"OFF");

	return ret;
}
void monkey_bus::Set_AverageSpeed(double speed)
{
	m_speed = m_speed * 0.99 + speed * 0.01;
	//m_AverageSpeed.push_back(speed);
	//if(m_AverageSpeed.size()%2000 == 0)
	//{
	//	//get Speed k-means
	//	m_speed = my_k_means_algo(K_MEANS_X1,K_MEANS_X2,K_MEANS_x3);
	//	//
	//	m_speed = (m_direct == NEGTIVE_DIRECTION) ? m_speed : m_speed * -1.0;
	//	debug_print_syslog(0,"[lemon the second choice AverageSpeed]v:%f",m_speed);
	//}
}
void monkey_bus::getOffTheBus(std::shared_ptr<monkey_person> mp)
{
	//can not free here .
	mp->GetOffTheBus();
	ScopedLock lk(m_monitor);
	auto it = std::find(person_list_.begin(),person_list_.end(),mp);
	if (it != person_list_.end())
	{
		person_list_.erase(it);

	}
}
void monkey_bus::getOnTheBus(std::shared_ptr<monkey_person> mp,std::shared_ptr<monkey_bus> bus)
{
	mp->GetOnTheBus(bus,m_speed);
	ScopedLock lk(m_monitor);
	person_list_.push_back(mp);
}
void monkey_bus::updata_position() 
{
	for(auto person:person_list_)
	{
		person->updata_position();
	}

}
