#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "ant.h"
#include "ProcessRemodule.h"

NAMESPACE_POINT_BEGIN(NAMESPACE_POINT)
site::site(int id) 
	:m_id(id)
	,m_path_empty(false)
	,m_height(1.5)
	,m_ant_dist(0)
	,m_ant_dist_sum_new(0)
	,m_ant_dist_cnt_new(0)
{

}

void site::sort_path()
{
	if(m_ant[0][0][1]<m_ant[0][1][1])
		return;
	m_ant[0][0].swap(m_ant[0][1]);
	m_ant[1][0].swap(m_ant[1][1]);

}

sit_list::sit_list()
{

}
char *strtok_r(char *s, const char *delim, char **save_ptr) {  
	char *token;  

	if (s == NULL) s = *save_ptr;  

	/* Scan leading delimiters.  */  
	s += strspn(s, delim);  
	if (*s == '\0')   
		return NULL;  

	/* Find the end of the token.  */  
	token = s;  
	s = strpbrk(token, delim);  
	if (s == NULL)  
		/* This token finishes the string.  */  
			*save_ptr = strchr(token, '\0');  
	else {  
		/* Terminate the token and make *SAVE_PTR point past it.  */  
		*s = '\0';  
		*save_ptr = s + 1;  
	}  

	return token;  
}  
static int str_split(char*s,char**rc)
{
	char**o=rc;

	for(;*s;)
	{
		*o=strtok_r(s,",",&s);
		o++;
	}

	return o-rc;
}

void sit_list::init_sit_list(int32_t readerid,int32_t antid, double ax, double ay,double scale)
{
	if(readerid>(int)m_list.size()|| antid >= 2)
	{
		debug_print_syslog(0,"[lemon smooth Error_sit]:ReaderId is too long:%d or antid is too big antid:%d",readerid,antid);
		return;
	}
	debug_print_syslog(0,"[lemon smooth _sit]:ReaderId:%d  antid:%d,scale:%f",readerid,antid,scale);
	m_list[readerid].m_id=readerid;
	m_list[readerid].m_ant[antid].set(ax,-ay);
	m_list[readerid].m_scale = scale;
}
void sit_list::init_sit_list()
{
	for(auto&sit:m_list)
	{
		if(sit.m_id==-1)
			continue;

		if(sit.m_ant[0]==sit.m_ant[1])
		{
			//debug_print_syslog(0,"[lemon smooth Error_sit]:has the same point x,y"); 
		}

		sit.set( (sit.m_ant[0].x+sit.m_ant[1].x)/2,(sit.m_ant[0].y+sit.m_ant[1].y)/2);
	}
}
//1, 101, 1, '101-1', 4727, 75, 0, 0, '2017-08-29 10:21:14'
void sit_list::read_sit_list(const char*fname)
{
	FILE*fp=fopen(fname,"r");
	char buf[512];
	int t,id;
	char* s[20];
	while(fgets(buf,sizeof(buf),fp))
	{
		t=str_split(buf,&s[0]);
		if(t<8)
			continue;

		id=atoi(s[1]);
		if(id>(int)m_list.size())
			continue;

		int antid=atoi(s[2])-1;
		if(antid>=2)
			continue;

		m_list[id].m_id=id;
		m_list[id].m_ant[antid].set(atof(s[4]),-atof(s[5]));
	}

	for(auto&sit:m_list)
	{
		if(sit.m_id==-1)
			continue;

		if(sit.m_ant[0]==sit.m_ant[1])
		{
		//	printf("%d分站天线坐标相等.\n",sit.m_id);
		}

		sit.set( (sit.m_ant[0].x+sit.m_ant[1].x)/2,(sit.m_ant[0].y+sit.m_ant[1].y)/2);
	}

	fclose(fp);
}
//315, 1, 5541.65, 338, 0, NULL, -1
//315, 2, 5674.04, 379, 0, NULL, -1

void sit_list::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)
{
	if(readerid>(int)m_list.size())
	{
		debug_print_syslog(0,"[lemon smooth Error_ant]:ReaderId is too long:%d or antid is too big antid:%d",readerid,antid);
		return;
	}
	if(antid>=2)
		antid=1;
	m_list[readerid].m_ant[0][antid][1].set(ax,-ay);
	m_list[readerid].m_ant[1][antid][1].set(ax,-ay);
	int i = 0;
	while (b != e)
	{
		std::string bs = *b;
		std::string ns = *(++b);
		m_list[readerid].m_ant[0][antid][3+i>5?5:3+i].set(m_list[readerid].m_ant[0].dist(m_list[atoi(bs.c_str())]),atof(ns.c_str()));
		m_list[readerid].m_ant[1][antid][3+i>5?5:3+i].set(m_list[readerid].m_ant[1].dist(m_list[atoi(bs.c_str())]),atof(ns.c_str()));
		++b;
		++i;
	}
	
}
void sit_list::init_ant_path()
{
	for(auto&s:m_list)
	{
		if(s.m_id==-1)
			continue;

		if((s.m_path_empty=s.path(0).empty() && s.path(1).empty()))
			continue;

		s.sort_path();

		for(auto&a:s.m_ant)
			for(int i=0;i<2;i++)
			{
				double dx=s.path(i).x-s.x;
				double dy=s.path(i).y-s.y;
				double r=sqrt(dx*dx+dy*dy);

				if(r<1e-10)
				{
					//printf("empty path:sid=%d,path=%d\n",s.m_id,i);
					continue;
				}

				double cos=dx/r;
				double sin=dy/r;
				double d=s.m_ant[0].dist(s.m_ant[1])/2;

				double p_a=a.dist(s.path(i));

				double sign=p_a>r?-1:1;

				a[i][2].set(cos,sin);
				a[i][0].set(s.x+d*cos*sign,s.y+d*sin*sign);
			}
					line path(s.path(0),s.path(1));

		if(path.dist(s)<2)
		{
			s.m_line[0] =  line_v(s.path(0),s.path(1));
		}
		else
		{
			s.m_line[0] =  line_v(s.path(0),s);
			s.m_line[1] =  line_v(s.path(1),s);
		}
		//	s.m_line[0] = std::make_shared<line_v> (s.m_ant[0][0][1],s.m_ant[0][1][1]);
		//	if(!s.m_ant[0][2][1].empty())
		//		s.m_line[1] = std::make_shared<line_v>(s.m_ant[0][1][1],s.m_ant[0][2][1]);
	}
}
void sit_list::read_ant_path(const char*fname)
{
	FILE*fp=fopen(fname,"r");
	char buf[512],*p;
	int t,id,pid;
	char* s[20];
	while((p=fgets(buf,sizeof(buf),fp)))
	{
		t=str_split(buf,&s[0]);
		if(t<4)
			continue;

		id=atoi(s[0]);
		if(id>(int)m_list.size())
			continue;
		pid=atoi(s[1])-1;

		if(pid>=2)
			pid=1;

		m_list[id].m_ant[0][pid][1].set(atof(s[2]),-atof(s[3]));
		m_list[id].m_ant[1][pid][1].set(atof(s[2]),-atof(s[3]));

		for(int i = 0 ;i < (t-7)/2;i++)
		{
			m_list[id].m_ant[0][pid][3+i>5?5:3+i].set(m_list[id].m_ant[0].dist(m_list[atoi(s[7+i*2])]),atof(s[8+i*2]));
			m_list[id].m_ant[1][pid][3+i>5?5:3+i].set(m_list[id].m_ant[1].dist(m_list[atoi(s[7+i*2])]),atof(s[8+i*2]));
		}

	}
	fclose(fp);

	for(auto&s:m_list)
	{
		if(s.m_id==-1)
			continue;

		if((s.m_path_empty=s.path(0).empty() && s.path(1).empty()))
			continue;

		s.sort_path();

		for(auto&a:s.m_ant)
		for(int i=0;i<2;i++)
		{
			double dx=s.path(i).x-s.x;
			double dy=s.path(i).y-s.y;
			double r=sqrt(dx*dx+dy*dy);

			if(r<1e-10)
			{
			//	printf("empty path:sid=%d,path=%d\n",s.m_id,i);
				continue;
			}

			double cos=dx/r;
			double sin=dy/r;
			double d=s.m_ant[0].dist(s.m_ant[1])/2;

			double p_a=a.dist(s.path(i));

			double sign=p_a>r?-1:1;

			a[i][2].set(cos,sin);
			a[i][0].set(s.x+d*cos*sign,s.y+d*sin*sign);
		}

		line path(s.path(0),s.path(1));

		if(path.dist(s)<2)
		{
			s.m_line[0] =  line_v(s.path(0),s.path(1));
		}
		else
		{
			s.m_line[0] =  line_v(s.path(0),s);
			s.m_line[1] =  line_v(s.path(1),s);
		}
	}
}

const site& sit_list::operator[](int id) const
{
	return m_list[id];
}

NAMESPACE_POINT_END(NAMESPACE_POINT)