#include "PeLightTail.h"

PeLightTail::PeLightTail(std::weak_ptr<Entity> target, int section, float tail_width)
{
	this->target = target;
	this->section = section;
	this->tail_width = tail_width;
	track_finally.resize(section * 2);

	readyDestory_counter = section;
	//初始化图像
	//设置三角形网格
	triNum = (section - 1) * 2;//三角形数量
	fillList_set.resize(triNum * 3);
	fillList_set_last.resize(triNum * 3);
	drawBeforeOtherEntity = true;
	//颜色
	r = g = b = 0xff;
}

void PeLightTail::SetColor(UINT8 r, UINT8 g, UINT8 b)
{
	this->r = r;
	this->g = g;
	this->b = b;
}

void PeLightTail::SetAlphaDiv(float alphaDiv)
{
	this->alphaDiv = alphaDiv;
}

void PeLightTail::SetLeaveTimer(int disappearTime)
{
	disappear_time_counter = disappearTime;
}

void PeLightTail::SetLeaveFunc(bool(*LeaveFunc)(std::weak_ptr<Entity>))
{
	this->LeaveFunc = LeaveFunc;
}

void PeLightTail::SetAllAlpha(float alpha)
{
	this->allAlpha = alpha;
}

void PeLightTail::Leave()
{
	target.reset();
	readyDestory = true;
}

void PeLightTail::Step()
{
	auto wtarget = target.lock();
	if (wtarget)
	{
		if (wtarget->inUsing)
		{
			tailLastPos = XMVectorSet(wtarget->x, wtarget->y, 0, 0);
			while (track.size() < section)
				track.push_back(tailLastPos);
			HeadMoveNewPos(tailLastPos);
		}
		else
		{
			target.reset();
			readyDestory = true;
		}
	}
	else
	{
		HeadMoveNewPos(tailLastPos);
	}
	//函数消失
	if (wtarget && LeaveFunc)
	{
		if (LeaveFunc(target))
			Leave();
	}
	//计时器消失
	if (disappear_time_counter > 0)
	{
		disappear_time_counter--;
		if (disappear_time_counter == 0)
			Leave();
	}
	//销毁
	if (readyDestory)
	{
		if (readyDestory_counter > 0)
		{
			readyDestory_counter--;
		}
		else
		{
			Destroy();
		}
	}
	//绘制
	fillList_set_last.swap(fillList_set);
	int triIndex = 0;
	for (int i = 0; i < track_finally.size() - 2; i++)
	{
		auto a = (BYTE)floorf((((float)track_finally.size() - i) / track_finally.size()) * 0xff * allAlpha / alphaDiv);
		fillList_set.at(triIndex * 3 + 0).x = XMVectorGetX(track_finally.at(i));
		fillList_set.at(triIndex * 3 + 0).y = XMVectorGetY(track_finally.at(i));
		fillList_set.at(triIndex * 3 + 0).c = RGBA(r, g, b, a);

		fillList_set.at(triIndex * 3 + 1).x = XMVectorGetX(track_finally.at(i + 1));
		fillList_set.at(triIndex * 3 + 1).y = XMVectorGetY(track_finally.at(i + 1));
		fillList_set.at(triIndex * 3 + 1).c = RGBA(r, g, b, a);

		fillList_set.at(triIndex * 3 + 2).x = XMVectorGetX(track_finally.at(i + 2));
		fillList_set.at(triIndex * 3 + 2).y = XMVectorGetY(track_finally.at(i + 2));
		fillList_set.at(triIndex * 3 + 2).c = RGBA(r, g, b, a);
		triIndex++;
	}
}

void PeLightTail::DeltaTime(float deltaTime)
{
	//绘制位置
	if (fillList.size() < fillList_set_last.size())
		fillList.resize(fillList_set_last.size());
	for (int i = 0; i < fillList_set_last.size(); i++)
	{
		auto& dst = fillList[i];
		auto& src_last = fillList_set_last[i];
		auto& src = fillList_set[i];
		dst.x = lerp(src_last.x, src.x, deltaTime);
		dst.y = lerp(src_last.y, src.y, deltaTime);
		dst.c = src.c;
	}
	Entity::DeltaTime(deltaTime);
}

void PeLightTail::HeadMoveNewPos(XMVECTOR pos)
{
	//在头部加入一个新坐标，再把尾部的移除
	track.push_front(pos);
	track.pop_back();
	CalcPos();
}

void PeLightTail::CalcPos()
{
	//补到一定的长度
	while (track.size() < section)
		track.push_back(XMVectorZero());
	//计算向量
	trackVec.clear();
	XMVECTOR v;
	XMVECTOR c1, c2, cOut;
	//list转vector
	tempTrack.assign(track.begin(), track.end());
	for (size_t i = 0; i < tempTrack.size() - 1; i++)
	{
		v = tempTrack.at(i + 1) - tempTrack.at(i);
		trackVec.push_back(v);
	}
	trackVec.push_back(tempTrack.at(tempTrack.size() - 1));//加尾
	//list转vector
	tempTrackVec.assign(trackVec.begin(), trackVec.end());

	//向量平均化
	trackVecAverage.clear();
	trackVecAverage.push_back(tempTrackVec.at(0));
	for (size_t i = 0; i < trackVec.size() - 1; i++)
	{
		v = tempTrackVec.at(i) + tempTrackVec.at(i + 1);
		trackVecAverage.push_back(v);
	}
	//计算垂直向量
	verticalVec.clear();
	for (auto& vec : trackVecAverage)
	{
		c1 = XMVectorSet(XMVectorGetX(vec), XMVectorGetY(vec), 0, 0);
		c2 = XMVectorSet(0, 0, 1, 0);
		cOut = XMVector3Cross(c1, c2);
		v = XMVectorSet(XMVectorGetX(cOut), XMVectorGetY(cOut), 0, 0);
		verticalVec.push_back(XMVector2Normalize(v));
	}
	//list转vector
	tempVerticalVec.assign(verticalVec.begin(), verticalVec.end());
	//计算最终顶点坐标
	for (size_t i = 0; i < tempVerticalVec.size(); i++)
	{
		float w = 1;
		//float w =  ((float)tempVerticalVec.size() - i) / tempVerticalVec.size();
		auto r = tempVerticalVec.at(i) / 2 * tail_width * w;
		track_finally.at(i * 2) = tempTrack.at(i) - r;
		track_finally.at(i * 2 + 1) = tempTrack.at(i) + r;
	}
}
