#include "landmark.h"
#include <cfloat>
#include "db_api/CDBSingletonDefine.h"
#include "log.h"


Landmark_list * Landmark_list::instance()
{
	static Landmark_list  lm_list;
	return &lm_list;
}
void Landmark_list::init_mapDirection()
{
	const char * sql = "select map_direction_id, map_id, north_angle from dat_map_direction;";
	std::string Error;
	YADB::CDBResultSet DBRes;
	sDBConnPool.Query(sql,DBRes,Error);
	int nCount = DBRes.GetRecordCount( Error );
	if (nCount > 0)
	{
		log_info( "init_map_direction. The record count=%d\n", nCount );

		while ( DBRes.GetNextRecod(Error) )
		{
			int map_id  = 0;
			DBRes.GetField( "map_id",map_id, Error );

			int north_angle = 0;
			DBRes.GetField( "north_angle",north_angle, Error );

			std::shared_ptr<map_direction> md = std::make_shared<map_direction>(map_id,north_angle);
			m_map.insert({map_id,md});
			log_info("map_direction.....mapid:%d,north:%d",map_id,north_angle);
		}
	}
}
void Landmark_list::init_from_db()
{
	init_landmarkInfo();
	init_mapDirection();
}

void Landmark_list::init_landmarkInfo()
{
	const char * sql = "select landmark_id, name, map_id, area_id, x, y, z from dat_landmark;";
	std::string Error;
	YADB::CDBResultSet DBRes;
	sDBConnPool.Query(sql,DBRes,Error);
	int nCount = DBRes.GetRecordCount( Error );
	if (nCount > 0)
	{
		log_info( "init_landmark_info. The record count=%d\n", nCount );

		while ( DBRes.GetNextRecod(Error) )
		{
			int landmark_id  = 0;
			DBRes.GetField( "landmark_id",landmark_id, Error );

			std::string name;
			DBRes.GetField( "name",name, Error );

			int map_id  = 0;
			DBRes.GetField( "map_id",map_id, Error );

			int area_id = 0;
			DBRes.GetField( "area_id",area_id, Error );

			double x = 0;
			DBRes.GetField( "x",x, Error );

			double y = 0;
			DBRes.GetField( "y",y, Error );

			double z = 0;
			DBRes.GetField( "z",z, Error );
			point p(x,y,z);
			std::shared_ptr<LandmarkInfo> landmark = std::make_shared<LandmarkInfo>(p,landmark_id,name,map_id,area_id);
			m_v.push_back(landmark);
			log_info("landmark ......id:%d,name:%s,mapid:%d,area_id:%d,x:%.2f,y:%.2f,z:%.2f",landmark_id,name.c_str(),map_id,area_id,x,y,z);
		}
	}

}

std::tuple<int,int,double> Landmark_list::get(int mapid ,int areaid,const point &pt)
{
	int32_t id = -1;
	double dis = DBL_MAX;
	point p;
	for(const auto &lm : m_v)	
	{
		if(lm->area_id == areaid)
		{
			double tmp = pt.dist(*lm);
			if(tmp < dis)
			{
				id = lm->landmark_id;
				dis=tmp;
				p=*lm;
			}
		}
	}
	if(id==-1)
	  return std::make_tuple(0,0,0);
	int dir = GetDirectionType(pt,p,mapid);
	return std::make_tuple(id,dir,dis);
}
DIRECTION_TYPE Landmark_list::GetDirectionType(point card_point, point landmark_point, int map_id)
{
	DIRECTION_TYPE direction = NODIRECTORY;
	int x_offset = 0;
	int y_offset = 0;
	int angle = 0;
	x_offset = card_point.x - landmark_point.x;
	y_offset = card_point.y - landmark_point.y;

	if(abs(x_offset) < 1)
		x_offset = 0;
	if(abs(y_offset) < 1)
		y_offset = 0;

	std::shared_ptr<map_direction> pMapDirectoryInfo = nullptr;
	auto it = m_map.find(map_id);		
	if(it == m_map.end())
	{
		return NODIRECTORY;
	}
	else
	{ 
		pMapDirectoryInfo = it->second;
	}

	if(0 == y_offset)
	{
		if(x_offset > 0)
			angle = pMapDirectoryInfo->north_angle + 0;
		if(x_offset < 0)
			angle = pMapDirectoryInfo->north_angle - 180;
	}
	else if(0 == x_offset)
	{
		if(y_offset < 0)
			angle = pMapDirectoryInfo->north_angle - 90;
		if(y_offset > 0)
			angle = pMapDirectoryInfo->north_angle + 90;
	}
	else if(abs(x_offset) >= abs(y_offset))
	{
		if(x_offset > 0)
			angle = pMapDirectoryInfo->north_angle + 0;
		if(x_offset < 0)
			angle = pMapDirectoryInfo->north_angle - 180;
	}
	else
	{
		if(y_offset < 0)
			angle = pMapDirectoryInfo->north_angle - 90;
		if(y_offset > 0)
			angle = pMapDirectoryInfo->north_angle + 90;
	}

	direction = (DIRECTION_TYPE)((angle % 360) / 90);
	if(angle % 360 == 0)
		direction = NORTH;
	if((0 == y_offset) && (0 == x_offset))
		direction = NODIRECTORY;

	return direction;
}