#include "Entity.h"
#include <process.h>
#include <Quadtree.hpp>
Rect<float>& GetRectEntity::operator()(Entity* e) const
{
	return (Rect<float>&)e->cbRect.qtRect;
}

void EntityDll::Load(const wchar_t* dllName)
{
	wchar_t wbuff[MAX_PATH];
	swprintf_s(wbuff, L"./data/entity/%s.dll", dllName);
	if (dll)
		FreeLibrary(dll);
	dll = LoadLibraryW(wbuff);
	if (!dll)
	{
		wchar_t err[MAX_PATH];
		swprintf_s(err, L"载入%s失败", wbuff);
		MessageBoxW(nullptr, err, L"载入dll文件失败", MB_ICONWARNING);
		exit(0);
	}
	_GameCreateEntity = (void (*)(const wchar_t*, std::shared_ptr<Entity>*))GetProcAddress(dll, "GameCreateEntity");
	if (!_GameCreateEntity)
	{
		wchar_t err[MAX_PATH];
		swprintf_s(err, L"载入%s失败", wbuff);
		MessageBoxW(nullptr, L"GameCreateEntity函数失败", err, MB_ICONWARNING);
		exit(0);
	}
	_GetEntityCount = (int (*)())GetProcAddress(dll, "GetEntityCount");
	if (!_GetEntityCount)
	{
		wchar_t err[MAX_PATH];
		swprintf_s(err, L"载入%s失败", wbuff);
		MessageBoxW(nullptr, L"GetEntityCount函数失败", err, MB_ICONWARNING);
		exit(0);
	}
	_GetEntityName = (const wchar_t* (*)(int))GetProcAddress(dll, "GetEntityName");
	if (!_GetEntityName)
	{
		wchar_t err[MAX_PATH];
		swprintf_s(err, L"载入%s失败", wbuff);
		MessageBoxW(nullptr, L"GetEntityName函数失败", err, MB_ICONWARNING);
		exit(0);
	}
}
/*--------------------------UI实体使用----------------------------*/

Entity::Entity()
{
	ZeroMemory(axis, sizeof(axis));
}

Entity::Entity(int type)
{
	this->type = type;
	ZeroMemory(axis, sizeof(axis));
}

void Entity::Init(std::weak_ptr<Entity> self)
{
	initCheck = true;
	this->self = self;
	last_x = draw_x = x;
	last_y = draw_y = y;
}

void Entity::Step()
{
	bool bHighSpeedX = false;
	bool bHighSpeedY = false;
	const float max_speed = 4;
	last_x = x;
	last_y = y;
	//防止穿墙
	//x方向
	if (vx < -max_speed)
	{
		bHighSpeedX = true;
		int times = (int)floorf(abs(vx) / max_speed);
		for (int i = 0; i < times; i++)
		{
			x -= max_speed;
			Entity::Collision();
			if (vx == 0)
				break;
		}
		if (vx != 0)
			x -= abs(vx) - times * max_speed;
		Entity::Collision();
	}
	if (vx > max_speed)
	{
		bHighSpeedX = true;
		int times = (int)floorf(abs(vx) / abs(max_speed));
		for (int i = 0; i < times; i++)
		{
			x += max_speed;
			Entity::Collision();
			if (vx == 0)
				break;
		}
		if (vx != 0)
			x += abs(vx) - times * max_speed;
		Entity::Collision();
	}
	//y方向
	if (vy < -max_speed)
	{
		bHighSpeedY = true;
		int times = (int)floorf(abs(vy) / max_speed);
		for (int i = 0; i < times; i++)
		{
			y -= max_speed;
			Entity::Collision();
			if (vy == 0)
				break;
		}
		if (vy != 0)
			y -= abs(vy) - times * max_speed;
		Entity::Collision();
	}
	if (vy > max_speed)
	{
		bHighSpeedY = true;
		int times = (int)floorf(abs(vy) / abs(max_speed));
		for (int i = 0; i < times; i++)
		{
			y += max_speed;
			Entity::Collision();
			if (vy == 0)
				break;
		}
		if (vy != 0)
			y += abs(vy) - times * max_speed;
		Entity::Collision();
	}
	if (!bHighSpeedX)
		x += vx;
	if (!bHighSpeedY)
		y += vy;
	//无视尖刺时间
	if (ignoreTrap_counter > 0)
		ignoreTrap_counter--;
	//无视抓取时间
	if (ignoreCaught_counter > 0)
		ignoreCaught_counter--;
	//晃动时间
	if (shock_counter > 0)
		shock_counter--;
	//攻击状态重置
	if (type == 2 && attackState_reset_counter_max != -1)
	{
		if (attackState_reset_counter == -1)
			attackState_reset_counter = attackState_reset_counter_max;
		if (attackState_reset_counter == 0 && !attackState)
		{
			attackState = true;
			attackState_reset_counter = attackState_reset_counter_max;
		}
		if (attackState_reset_counter > 0)
			attackState_reset_counter--;
	}
}

void Entity::SetState(int stateID, int lr)
{
}

void Entity::SetState(std::wstring stateName, int lr)
{
	this->lr = lr;
}

void Entity::DeltaTime(float deltaTime)
{
	draw_x = lerp(last_x, x, deltaTime);
	draw_y = lerp(last_y, y, deltaTime);
}

void Entity::Collision()
{
	if (cbRect.Collision && cbRect.pxmArr)
		cbRect.Collision(shared_from_this(), cbRect.pxmArr, cbRect.pxaArr, cbRect.updatedPxmArr, cbRect.pxmArr_w, cbRect.pxaArr_w);
}

void Entity::ClearCollisionResult()
{
	if (cbRect.Collision && cbRect.pxmArr)
	{
		cbRect.cbTop = cbRect.cbBottom = cbRect.cbLeft = cbRect.cbRight = false;
		cbRect.onSlopeL = cbRect.onSlopeR = false;
		cbRect.onSlopeLSide = cbRect.onSlopeRSide = false;
		cbRect.onTrap = false;
		cbRect.inWater = false;
		cbRect.inWind = false;
		cbRect.inLava = false;
		cbRect.pxaLeft = cbRect.pxaRight = cbRect.pxaTop = cbRect.pxaBottom = 0;
		cbRect.movingPlatformLeft.reset();
		cbRect.movingPlatformRight.reset();
		cbRect.movingPlatformTop.reset();
		cbRect.movingPlatformBottom.reset();
	}
}

void Entity::BeginMovingPlatform()
{
	auto movingPlatformLeft = cbRect.movingPlatformLeft.lock();
	if (movingPlatformLeft)
	{
		vx -= movingPlatformLeft->vx;
		vy -= movingPlatformLeft->vy;
	}
	/*if (cbRect.movingPlatformTop)
	{
		vx -= cbRect.movingPlatformTop->vx;
		vy -= cbRect.movingPlatformTop->vy;
	}*/
	auto movingPlatformRight = cbRect.movingPlatformRight.lock();
	if (movingPlatformRight)
	{
		vx -= movingPlatformRight->vx;
		vy -= movingPlatformRight->vy;
	}
	auto movingPlatformBottom = cbRect.movingPlatformBottom.lock();
	if (movingPlatformBottom)
	{
		vx -= movingPlatformBottom->vx;
		vy -= movingPlatformBottom->vy;
	}
}

void Entity::EndMovingPlatform()
{
	auto movingPlatformLeft = cbRect.movingPlatformLeft.lock();
	auto movingPlatformRight = cbRect.movingPlatformRight.lock();
	auto movingPlatformBottom = cbRect.movingPlatformBottom.lock();
	auto movingPlatformTop = cbRect.movingPlatformTop.lock();

	if (movingPlatformLeft)
	{
		vx += movingPlatformLeft->vx;
		vy += movingPlatformLeft->vy;
	}
	/*if (cbRect.movingPlatformTop)
	{
		vx += cbRect.movingPlatformTop->vx;
		vy += cbRect.movingPlatformTop->vy;
	}*/
	if (movingPlatformRight)
	{
		vx += movingPlatformRight->vx;
		vy += movingPlatformRight->vy;
	}

	if (movingPlatformBottom)
	{
		vx += movingPlatformBottom->vx;
		vy += movingPlatformBottom->vy;
	}
	//附着平台移动
	if (movingPlatformTop && movingPlatformTop->vy < 0)
	{
		y += movingPlatformTop->vy;
	}
	if (movingPlatformBottom && movingPlatformBottom->vy > 0)
	{
		y += movingPlatformBottom->vy;
	}
	if (movingPlatformLeft && movingPlatformLeft->vx < 0 && !cbRect.cbBottom)
	{
		x += movingPlatformLeft->vx;
	}
	if (movingPlatformRight && movingPlatformRight->vx > 0 && !cbRect.cbBottom)
	{
		x += movingPlatformRight->vx;
	}
}

void Entity::LoadSaveData()
{
}

void Entity::WriteSaveData()
{
}

bool Entity::Touch(std::weak_ptr<Entity> e)
{
	auto we = e.lock();
	if (!we)
		return false;
	float src_l = x - cbRect.left;
	float src_r = x + cbRect.right;
	float src_t = y - cbRect.top;
	float src_b = y + cbRect.bottom;
	float dst_l = we->x - we->cbRect.left;
	float dst_r = we->x + we->cbRect.right;
	float dst_t = we->y - we->cbRect.top;
	float dst_b = we->y + we->cbRect.bottom;
	if (src_r <= dst_l || src_l >= dst_r ||
		src_b <= dst_t || src_t >= dst_b)
		return false;
	return true;
}

bool Entity::DeathByMovingPlatform()
{
	auto movingPlatformLeft = cbRect.movingPlatformLeft.lock();
	auto movingPlatformRight = cbRect.movingPlatformRight.lock();
	auto movingPlatformBottom = cbRect.movingPlatformBottom.lock();
	auto movingPlatformTop = cbRect.movingPlatformTop.lock();

	bool bLR = (cbRect.cbLeft && movingPlatformRight && movingPlatformRight->cbRect.enableMovePlatform && movingPlatformRight->vx < 0) ||
		(cbRect.cbRight && movingPlatformLeft && movingPlatformLeft->cbRect.enableMovePlatform && movingPlatformLeft->vx > 0) ||
		(movingPlatformRight && movingPlatformRight->cbRect.enableMovePlatform && movingPlatformLeft && movingPlatformLeft->cbRect.enableMovePlatform &&
			(movingPlatformRight->vx < 0 || movingPlatformLeft->vx > 0));

	bool bUD = (cbRect.cbTop && movingPlatformBottom && movingPlatformBottom->cbRect.enableMovePlatform && movingPlatformBottom->vy < 0) ||
		(cbRect.cbBottom && movingPlatformTop && movingPlatformTop->cbRect.enableMovePlatform && movingPlatformTop->vy > 0) ||
		(movingPlatformBottom && movingPlatformBottom->cbRect.enableMovePlatform && movingPlatformTop && movingPlatformTop->cbRect.enableMovePlatform &&
			(movingPlatformBottom->vy < 0 || movingPlatformTop->vy > 0));
	return bLR || bUD;
}

bool Entity::Pathfinding(float targetX, float targetY, float* outDirX, float* outDirY)
{
	XMVECTOR dir = XMVectorZero();
	bool bBlock = false;//巡航是否起效
	if (gameFunc->LineTest(shared_from_this(), (x - cbRect.left) / 16, (y - cbRect.top) / 16, targetX / 16, targetY / 16))
		bBlock = true;
	if (gameFunc->LineTest(shared_from_this(), (x + cbRect.right) / 16, (y - cbRect.top) / 16, targetX / 16, targetY / 16))
		bBlock = true;
	if (gameFunc->LineTest(shared_from_this(), (x - cbRect.left) / 16, (y + cbRect.bottom) / 16, targetX / 16, targetY / 16))
		bBlock = true;
	if (gameFunc->LineTest(shared_from_this(), (x + cbRect.right) / 16, (y + cbRect.bottom) / 16, targetX / 16, targetY / 16))
		bBlock = true;
	//有障碍则寻路
	if (bBlock)
	{
		auto cell_lu = gameFunc->GetPath(shared_from_this(), targetX / 16, targetY / 16, (x - cbRect.left) / 16, (y - cbRect.top) / 16);
		auto cell_ru = gameFunc->GetPath(shared_from_this(), targetX / 16, targetY / 16, (x + cbRect.right) / 16, (y - cbRect.top) / 16);
		auto cell_ld = gameFunc->GetPath(shared_from_this(), targetX / 16, targetY / 16, (x - cbRect.left) / 16, (y + cbRect.bottom) / 16);
		auto cell_rd = gameFunc->GetPath(shared_from_this(), targetX / 16, targetY / 16, (x + cbRect.right) / 16, (y + cbRect.bottom) / 16);
		float cellVx = cell_lu->vec1_x + cell_ru->vec1_x + cell_ld->vec1_x + cell_rd->vec1_x;
		float cellVy = cell_lu->vec1_y + cell_ru->vec1_y + cell_ld->vec1_y + cell_rd->vec1_y;
		//巡航时，会把坐标往格子中心靠拢
		float centerX = x + (cbRect.right - cbRect.left) / 2;
		float centerY = y + (cbRect.bottom - cbRect.top) / 2;
		float adjustSpeed = 0.25f;
		if (abs(vy) > abs(vx))
		{
			//往x的中心靠
			float cLR = centerX - floorf(centerX / 16.0f) * 16.0f - 8.0f;
			float dx = floorf(centerX / 16.0f) * 16.0f + 8.0f - (cbRect.right - cbRect.left) / 2;
			if (abs(x - dx) >= 1)
			{
				//往左靠
				if (cLR > 0)
				{
					cellVx -= adjustSpeed;
				}
				//往右靠
				else
				{
					cellVx += adjustSpeed;
				}
			}
		}
		if (abs(vx) > abs(vy))
		{
			//往y的中心靠
			float cUD = centerY - floorf(centerY / 16.0f) * 16.0f - 8.0f;
			float dy = floorf(centerY / 16.0f) * 16.0f + 8.0f - (cbRect.bottom - cbRect.top) / 2;
			if (abs(y - dy) >= 1)
			{
				////往上靠
				if (cUD > 0)
				{
					cellVy -= adjustSpeed;
				}
				//往下靠
				else
				{
					cellVy += adjustSpeed;
				}
			}
		}
		dir = XMVector2Normalize(XMVectorSet(cellVx, cellVy, 0, 0));
	}
	//如果方向上无障碍则直接追击
	else
	{
		dir = XMVector2Normalize(XMVectorSet(targetX - x, targetY - y, 0, 0));
	}
	*outDirX = XMVectorGetX(dir);
	*outDirY = XMVectorGetY(dir);
	return bBlock;
}

int Entity::GetMapPxa(int x, int y)
{
	if (!cbRect.pxmArr)
		return 0;
	int pxmArrW = cbRect.pxmArr_w;
	int pxmArrH = (int)cbRect.pxmArr->size() / pxmArrW;
	if (x >= 0 && y >= 0 && x < pxmArrW && y < pxmArrH)
	{
		auto& pxmArr = *cbRect.pxmArr;
		LONG pxm = pxmArr[y * pxmArrW + x];
		auto& pxaArr = *cbRect.pxaArr;
		return pxaArr[pxm];
	}
	return 0;
}

float Entity::GetShootingAngle()
{
	float dx = 0, dy = 0;
	//上
	if (input.GetUp() || axis[0] < 0)
	{
		if (axis[0] < 0)
			dy += axis[0];
		else
			dy += -1;
	}
	//下
	else if (input.GetDown() || axis[1] > 0)
	{
		if (axis[1] > 0)
			dy += axis[1];
		else
			dy += 1;
	}
	//左
	if (input.GetLeft() || axis[2] < 0)
	{
		if (axis[2] < 0)
			dx += axis[2];
		else
			dx += -1;
	}
	//右
	else if (input.GetRight() || axis[3] > 0)
	{
		if (axis[3] > 0)
			dx += axis[3];
		else
			dx += 1;
	}
	if (dx == 0 && dy == 0)
	{
		if (lr == 0)
			dx = -1;
		else
			dx = 1;
	}
	auto angle = XMConvertToDegrees(XMVectorGetX(XMVector2AngleBetweenVectors(XMVectorSet(1, 0, 0, 0), XMVectorSet(dx, dy, 0, 0))));
	if (dy < 0)
		angle = 360 - angle;
	return angle;
}

void Entity::KeepOnSlopes()
{
	if (cbRect.onSlopeL && vx > 0 || cbRect.onSlopeR && vx < 0)
		vy = abs(vx);
	if ((cbRect.cbBottom) && !(cbRect.onSlopeL || cbRect.onSlopeR))
	{
		if (cbRect.onSlopeLSide && vx > 0 || cbRect.onSlopeRSide && vx < 0)
			vy = 2;
	}
}

void Entity::GetCameraPos(float* outX, float* outY)
{
	*outX = x;
	*outY = y;
}

void Entity::ImmUpdate()
{
}

void Entity::KeepInMap()
{
	if (!cbRect.pxmArr)
		return;
	int mapW, mapH;
	gameFunc->GetMapSize(gameFunc->mapSizeGetter, &mapW, &mapH);
	if (x < 8)
		x = 8;
	if (x > mapW * 16 - 8)
		x = mapW * 16.0f - 8;
}

bool Entity::IsOutOfMap(int r)
{
	if (!cbRect.pxmArr)
		return false;
	int mapW, mapH;
	gameFunc->GetMapSize(gameFunc->mapSizeGetter, &mapW, &mapH);
	return x < -r || y < -r || x > mapW * 16 + r || y > mapH * 16 + r;
}

void Entity::GetIcon(std::wstring& png, std::wstring& sprite_index, int& image_index, std::set<int>& hideLayerList)
{
	png.clear();
	sprite_index.clear();
	image_index = 0;
}

void Entity::Wind()
{
	if (!cbRect.inWind)
		return;
	bool u = false;
	bool d = false;
	bool l = false;
	bool r = false;
	switch (cbRect.windDir)
	{
	case 7:
		u = true;
		l = true;
		break;
	case 8:
		u = true;
		break;
	case 9:
		u = true;
		r = true;
		break;
	case 4:
		l = true;
		break;
	case 6:
		r = true;
		break;
	case 1:
		l = true;
		d = true;
		break;
	case 2:
		d = true;
		break;
	case 3:
		r = true;
		d = true;
		break;
	}
	if (u)
	{
		if (vy - 0x80 / ts > -0x5FF / ts)
			vy -= 0x80 / ts;
	}
	if (d)
	{
		if (vy + 0x55 / ts < 0x5FF / ts)
			vy += 0x55 / ts;
	}
	if (l)
	{
		if (vx - 0x88 / ts > -0x5FF / ts)
			vx -= 0x88 / ts;
	}
	if (r)
	{
		if (vx + 0x88 / ts < 0x5FF / ts)
			vx += 0x88 / ts;
	}
}

void Entity::Destroy()
{
	inUsing = false;
}

void Entity::CopyFrom(std::shared_ptr<Entity>& another)
{
	//复制基本变量
	gameFunc = another->gameFunc;
	x = another->x;
	y = another->y;
	draw_x = another->draw_x;
	draw_y = another->draw_y;
	last_x = another->last_x;
	last_y = another->last_y;
	vx = another->vx;
	vy = another->vy;
	lr = another->lr;
	ud = another->ud;
	initCheck = another->initCheck;
	speedDir = another->speedDir;
	noDir = another->noDir;
	cbRect = another->cbRect;
	ani = another->ani;
	inUsing = another->inUsing;
	hide = another->hide;
	drawBeforeOtherEntity = another->drawBeforeOtherEntity;
	drawAfterPlayer = another->drawAfterPlayer;
	topDraw = another->topDraw;
	el = another->el;
	type = another->type;
	color = another->color;
	input = another->input;
	inputLock = another->inputLock;
	enableAI = another->enableAI;
	aiName = another->aiName;
	memcpy_s(axis, sizeof(axis), another->axis, sizeof(axis));
	coyote_counter = another->coyote_counter;
	coyote_max = another->coyote_max;
	isItem = another->isItem;
	inCheckingEvent = another->inCheckingEvent;
	faceToBackEnd = another->faceToBackEnd;
	blockJump = another->blockJump;
	initCollision = another->initCollision;
	hp = another->hp;
	hp_max = another->hp_max;
	dropExp = another->dropExp;
	mp = another->mp;
	mp_max = another->mp_max;
	ignoreTrap = another->ignoreTrap;
	ignoreTrap_counter = another->ignoreTrap_counter;
	shock_counter = another->shock_counter;
	damaged = another->damaged;
	attackState = another->attackState;
	attackState_reset_counter_max = another->attackState_reset_counter_max;
	attackState_reset_counter = another->attackState_reset_counter;
	damaged_counter = another->damaged_counter;
	damaged_limit = another->damaged_limit;
	damage_reset_counter = another->damage_reset_counter;
	attackParent = another->attackParent;
	isTrap = another->isTrap;
	caughtDifficulty = another->caughtDifficulty;
	ignoreCaught = another->ignoreCaught;
	ignoreCaught_counter = another->ignoreCaught_counter;
	touchList = another->touchList;
	mapLayer = another->mapLayer;
	entityLayer = another->entityLayer;
	lineList = another->lineList;
	fillList = another->fillList;
	shader = another->shader;
	light = another->light;
}

void Entity::GetAnimateOffset(float& outDx, float& outDy)
{
	outDx = 0;
	outDy = 0;
}

bool Entity::Hurt(std::weak_ptr<Entity> src, int getDamage, float angle, bool bTakedown, int elemType, float shockForce, float heavy, int* outRealDamage)
{
	return false;
}

void Entity::Attack(std::weak_ptr<Entity> dst, int* outDamage, float* outAngle, bool* outTakedown, int* outElemType, float* outShockForce, float* outHeavy)
{
	*outDamage = 0;
	*outAngle = lr == 0 ? 180.0f : 0;
	*outTakedown = false;
	*outElemType = 0;
	*outShockForce = 0;
	*outHeavy = 0;
}

void Entity::Feedback(std::weak_ptr<Entity> target)
{
}

void Entity::AttackEffectObject(std::weak_ptr<Entity> target, float centerX, float centerY, int realDamage)
{
}

void Entity::AddDamagedEntity(Entity* e)
{
	damaged.insert(std::make_pair(e, damage_reset_counter));
}

std::weak_ptr<Entity> Entity::BeginCaught(std::weak_ptr<Entity> e)
{
	return std::weak_ptr<Entity>();
}

void Entity::EndCaught(std::weak_ptr<Entity> e)
{
}

void Entity::GridTouch(EntityLayer* targetLayer)
{
	touchList.clear();
	gameFunc->GridTouch(gameFunc->entityRes, shared_from_this(), targetLayer);
}

void Entity::AddTouchList(std::weak_ptr<Entity> e)
{
	touchList.push_back(e);
}

bool Entity::Item(std::weak_ptr<Entity> src)
{
	return false;
}

void Entity::Gain(std::weak_ptr<Entity> item)
{
}

void Entity::ReloadLanguage()
{
}

int Entity::AddLine(std::vector<PenVertex>& lineList, int index, float x1, float y1, DWORD c1, float x2, float y2, DWORD c2)
{
	if (lineList.size() < index + 2)
		lineList.resize(index + 2);
	auto& v1 = lineList[index + 0]; v1.x = x1; v1.y = y1; v1.c = c1;
	auto& v2 = lineList[index + 1]; v2.x = x2; v2.y = y2; v2.c = c2;
	return 2;
}

int Entity::AddRect(std::vector<PenVertex>& lineList, int index, float left, float top, float right, float bottom,
	DWORD c_lu, DWORD c_ru, DWORD c_ld, DWORD c_rd)
{
	if (lineList.size() < index + 8)
		lineList.resize(index + 8);
	auto& v1 = lineList[index + 0]; v1.x = left; v1.y = top; v1.c = c_lu;
	auto& v2 = lineList[index + 1]; v2.x = right; v2.y = top; v2.c = c_ru;
	auto& v3 = lineList[index + 2]; v3.x = right; v3.y = top; v3.c = c_ru;
	auto& v4 = lineList[index + 3]; v4.x = right; v4.y = bottom; v4.c = c_rd;
	auto& v5 = lineList[index + 4]; v5.x = right; v5.y = bottom; v5.c = c_rd;
	auto& v6 = lineList[index + 5]; v6.x = left; v6.y = bottom; v6.c = c_ld;
	auto& v7 = lineList[index + 6]; v7.x = left; v7.y = bottom; v7.c = c_ld;
	auto& v8 = lineList[index + 7]; v8.x = left; v8.y = top; v8.c = c_lu;
	return 8;
}

int Entity::AddArc(std::vector<PenVertex>& lineList, int index, float r, float startAngle, float endAngle, DWORD c_start, DWORD c_end)
{
	int iStartAngle = (int)startAngle;
	int iEndAngle = (int)endAngle;
	int vertexNum = min(360, iEndAngle - iStartAngle) * 2;
	if (lineList.size() < index + vertexNum)
		lineList.resize(index + vertexNum);
	for (int i = 0; i < vertexNum / 2; i++)
	{
		auto& v1 = lineList[index + i * 2 + 0];
		v1.x = r * cosf((i + iStartAngle) * deg2rad);
		v1.y = r * sinf((i + iStartAngle) * deg2rad);
		v1.c = c_start;
		auto& v2 = lineList[index + i * 2 + 1];
		v2.x = r * cosf((i + iStartAngle + 1) * deg2rad);
		v2.y = r * sinf((i + iStartAngle + 1) * deg2rad);
		v2.c = c_end;
	}
	return vertexNum;
}

int Entity::AddFillRect(std::vector<PenVertex>& fillList, int index, float left, float top, float right, float bottom,
	DWORD c_lu, DWORD c_ru, DWORD c_ld, DWORD c_rd)
{
	if (fillList.size() < index + 6)
		fillList.resize(index + 6);
	auto& v1 = fillList[index + 0]; v1.x = left; v1.y = top; v1.c = c_lu;
	auto& v2 = fillList[index + 1]; v2.x = right; v2.y = top; v2.c = c_ru;
	auto& v3 = fillList[index + 2]; v3.x = right; v3.y = bottom; v3.c = c_rd;
	auto& v4 = fillList[index + 3]; v4.x = left; v4.y = top; v4.c = c_lu;
	auto& v5 = fillList[index + 4]; v5.x = right; v5.y = bottom; v5.c = c_rd;
	auto& v6 = fillList[index + 5]; v6.x = left; v6.y = bottom; v6.c = c_ld;
	return 6;
}

int Entity::AddFillLine(std::vector<PenVertex>& fillList, int index, float x1, float y1, DWORD c1, float x2, float y2, DWORD c2, float width)
{
	// 计算向量
	XMVECTOR start = XMVectorSet(x1, y1, 0.0f, 0.0f);
	XMVECTOR end = XMVectorSet(x2, y2, 0.0f, 0.0f);

	// 方向向量和垂直向量
	XMVECTOR dir = XMVector2Normalize(XMVectorSubtract(end, start));
	XMVECTOR perp = XMVectorSet(-XMVectorGetY(dir), XMVectorGetX(dir), 0.0f, 0.0f);

	// 半宽向量
	XMVECTOR halfWidthVec = XMVectorReplicate(width * 0.5f);
	perp = XMVectorMultiply(perp, halfWidthVec);

	// 计算四个角点
	auto lu = XMVectorSubtract(start, perp); // 左上
	auto ru = XMVectorAdd(start, perp);     // 右上
	auto ld = XMVectorSubtract(end, perp);  // 左下
	auto rd = XMVectorAdd(end, perp);       // 右下

	if (fillList.size() < index + 6)
		fillList.resize(index + 6);
	auto& v1 = fillList[index + 0]; v1.x = XMVectorGetX(lu); v1.y = XMVectorGetY(lu); v1.c = c1;
	auto& v2 = fillList[index + 1]; v2.x = XMVectorGetX(ru); v2.y = XMVectorGetY(ru); v2.c = c1;
	auto& v3 = fillList[index + 2]; v3.x = XMVectorGetX(rd); v3.y = XMVectorGetY(rd); v3.c = c2;
	auto& v4 = fillList[index + 3]; v4.x = XMVectorGetX(lu); v4.y = XMVectorGetY(lu); v4.c = c1;
	auto& v5 = fillList[index + 4]; v5.x = XMVectorGetX(rd); v5.y = XMVectorGetY(rd); v5.c = c2;
	auto& v6 = fillList[index + 5]; v6.x = XMVectorGetX(ld); v6.y = XMVectorGetY(ld); v6.c = c2;
	return 6;
}

int Entity::AddFillFadeCircle(std::vector<PenVertex>& fillList, int index, float radius, float featherSize, DWORD c)
{
	const int segments = 40;
	int vertexNum = segments * 9;
	if (fillList.size() < index + vertexNum)
		fillList.resize(index + vertexNum);
	float innerRadius = radius - featherSize;
	for (int i = 0; i < segments; i++)
	{
		float angle1 = static_cast<float>(i) / static_cast<float>(segments) * 2.0f * XM_PI;
		float angle2 = static_cast<float>(i + 1) / static_cast<float>(segments) * 2.0f * XM_PI;
		// 内部圆形的顶点（完全不透明）
		auto& v1 = fillList[index + i * 9 + 0]; v1.x = 0; v1.y = 0; v1.c = c;
		auto& v2 = fillList[index + i * 9 + 1]; v2.x = innerRadius * cosf(angle1); v2.y = innerRadius * sinf(angle1); v2.c = c;
		auto& v3 = fillList[index + i * 9 + 2]; v3.x = innerRadius * cosf(angle2); v3.y = innerRadius * sinf(angle2); v3.c = c;
		// 边缘羽化区域的顶点
		auto& v4 = fillList[index + i * 9 + 3]; v4.x = innerRadius * cosf(angle1); v4.y = innerRadius * sinf(angle1); v4.c = c;
		auto& v5 = fillList[index + i * 9 + 4]; v5.x = radius * cosf(angle1); v5.y = radius * sinf(angle1); v5.c = c & RGBA(0xff, 0xff, 0xff, 0);
		auto& v6 = fillList[index + i * 9 + 5]; v6.x = innerRadius * cosf(angle2); v6.y = innerRadius * sinf(angle2); v6.c = c;
		auto& v7 = fillList[index + i * 9 + 6]; v7.x = radius * cosf(angle1); v7.y = radius * sinf(angle1); v7.c = c & RGBA(0xff, 0xff, 0xff, 0);
		auto& v8 = fillList[index + i * 9 + 7]; v8.x = radius * cos(angle2); v8.y = radius * sin(angle2); v8.c = c & RGBA(0xff, 0xff, 0xff, 0);
		auto& v9 = fillList[index + i * 9 + 8]; v9.x = innerRadius * cos(angle2); v9.y = innerRadius * sin(angle2); v9.c = c;
	}
	return vertexNum;
}

int Entity::AddFillFadeRect(std::vector<PenVertex>& fillList, int index, float left, float top, float right, float bottom, float featherSize, DWORD c_lu, DWORD c_ru, DWORD c_ld, DWORD c_rd)
{
	if (fillList.size() < index + 30)
		fillList.resize(index + 30);
	// 内部矩形（完全不透明）
	float innerLeft = left + featherSize;
	float innerTop = top + featherSize;
	float innerRight = right - featherSize;
	float innerBottom = bottom - featherSize;

	//不透明
	auto& v1 = fillList[index + 0]; v1.x = innerLeft; v1.y = innerTop, v1.c = c_lu;//左上
	auto& v2 = fillList[index + 1]; v2.x = innerRight; v2.y = innerTop, v2.c = c_ru;//右上
	auto& v3 = fillList[index + 2]; v3.x = innerLeft; v3.y = innerBottom, v3.c = c_ld;//左下

	auto& v4 = fillList[index + 3]; v4.x = innerRight; v4.y = innerTop, v4.c = c_ru;//右上
	auto& v5 = fillList[index + 4]; v5.x = innerRight; v5.y = innerBottom, v5.c = c_rd;//右下
	auto& v6 = fillList[index + 5]; v6.x = innerLeft; v6.y = innerBottom, v6.c = c_ld;//左下

	// 边缘羽化区域
	// 顶部边缘
	auto& v7 = fillList[index + 6]; v7.x = left; v7.y = top, v7.c = c_lu & RGBA(0xff, 0xff, 0xff, 0);//左上外
	auto& v8 = fillList[index + 7]; v8.x = right; v8.y = top, v8.c = c_ru & RGBA(0xff, 0xff, 0xff, 0);//右上外
	auto& v9 = fillList[index + 8]; v9.x = innerLeft; v9.y = innerTop, v9.c = c_lu;//左上内

	auto& v10 = fillList[index + 9]; v10.x = right; v10.y = top, v10.c = c_ru & RGBA(0xff, 0xff, 0xff, 0);//右上外
	auto& v11 = fillList[index + 10]; v11.x = innerRight; v11.y = innerTop, v11.c = c_ru;//右上内
	auto& v12 = fillList[index + 11]; v12.x = innerLeft; v12.y = innerTop, v12.c = c_lu;//左上内

	// 底部边缘
	auto& v13 = fillList[index + 12]; v13.x = left; v13.y = bottom, v13.c = c_ld & RGBA(0xff, 0xff, 0xff, 0);//左下外
	auto& v14 = fillList[index + 13]; v14.x = innerLeft; v14.y = innerBottom, v14.c = c_ld;//左下内
	auto& v15 = fillList[index + 14]; v15.x = right; v15.y = bottom, v15.c = c_rd & RGBA(0xff, 0xff, 0xff, 0);//右下外

	auto& v16 = fillList[index + 15]; v16.x = right; v16.y = bottom, v16.c = c_rd & RGBA(0xff, 0xff, 0xff, 0);//右下外
	auto& v17 = fillList[index + 16]; v17.x = innerLeft; v17.y = innerBottom, v17.c = c_ld;//左下内
	auto& v18 = fillList[index + 17]; v18.x = innerRight; v18.y = innerBottom, v18.c = c_rd;//右下内

	//左侧边缘
	auto& v19 = fillList[index + 18]; v19.x = left; v19.y = top, v19.c = c_lu & RGBA(0xff, 0xff, 0xff, 0);//左上外
	auto& v20 = fillList[index + 19]; v20.x = innerLeft; v20.y = innerTop, v20.c = c_lu;//左上内
	auto& v21 = fillList[index + 20]; v21.x = left; v21.y = bottom, v21.c = c_ld & RGBA(0xff, 0xff, 0xff, 0);//左下外

	auto& v22 = fillList[index + 21]; v22.x = left; v22.y = bottom, v22.c = c_ld & RGBA(0xff, 0xff, 0xff, 0);//左下外
	auto& v23 = fillList[index + 22]; v23.x = innerLeft; v23.y = innerTop, v23.c = c_lu;//左上内
	auto& v24 = fillList[index + 23]; v24.x = innerLeft; v24.y = innerBottom, v24.c = c_ld;//左下内

	//右侧边缘
	auto& v25 = fillList[index + 24]; v25.x = right; v25.y = top, v25.c = c_ru & RGBA(0xff, 0xff, 0xff, 0);//右上外
	auto& v26 = fillList[index + 25]; v26.x = right; v26.y = bottom, v26.c = c_rd & RGBA(0xff, 0xff, 0xff, 0);//右下外
	auto& v27 = fillList[index + 26]; v27.x = innerRight; v27.y = innerTop, v27.c = c_ru;//右上内

	auto& v28 = fillList[index + 27]; v28.x = right; v28.y = bottom, v28.c = c_rd & RGBA(0xff, 0xff, 0xff, 0);//右下外
	auto& v29 = fillList[index + 28]; v29.x = innerRight; v29.y = innerTop, v29.c = c_ru;//右上内
	auto& v30 = fillList[index + 29]; v30.x = innerRight; v30.y = innerBottom, v30.c = c_rd;//右下内
	return 30;
}
