#include "CS_ArowanaAni.h"
#include "CS_PeSmoke.h"
#include "CS_PeZzz.h"
#include <PeSmog.h>
CS_ArowanaAni::CS_ArowanaAni()
{
	ani.png = L"CS_CaveStoryMod";
	//启用碰撞
	cbRect.enableCbRect = true;
	cbRect.enableSoild = true;
	//设置碰撞框
	cbRect.left = 24;
	cbRect.right = 24;
	cbRect.bottom = cbRect.top = 8;
	drawBeforeOtherEntity = true;
}

void CS_ArowanaAni::Init(std::weak_ptr<Entity> self)
{
	stateGravity.Init(shared_from_this());
	stateSplash.Init(shared_from_this());
	stateTeleport.Init(self);
	auto wpeDizzy = std::make_shared<CS_PeDizzy>(shared_from_this());
	peDizzy = wpeDizzy;
	gameFunc->SetEntity(shared_from_this(), wpeDizzy);
	Entity::Init(self);
}

void CS_ArowanaAni::Step()
{
	switch (stateID)
	{
	default:
	case 0://正常
		cbRect.left = 24;
		cbRect.right = 24;
		cbRect.bottom = cbRect.top = 8;
		ani.sprite_index = lr == 0 ? L"ls_arowana_swim_l" : L"ls_arowana_swim_r";
		stateGravity.Step();
		break;
	case 1://倒下的
		cbRect.left = 8;
		cbRect.right = 8;
		cbRect.bottom = cbRect.top = 8;
		ani.sprite_index = lr == 0 ? L"ls_arowana_fallen_l" : L"ls_arowana_fallen_r";
		stateGravity.Step();
		break;
	case 2://站立的
		cbRect.left = 24;
		cbRect.right = 24;
		cbRect.bottom = cbRect.top = 8;
		ani.sprite_index = lr == 0 ? L"ls_arowana_stand_l" : L"ls_arowana_stand_r";
		stateGravity.Step();
		break;
	case 3://跳跃
		ani.sprite_index = lr == 0 ? L"ls_arowana_stand_l" : L"ls_arowana_stand_r";
		if (cbRect.cbBottom && bSetQuake)
		{
			bSetQuake = false;
			gameFunc->SetQuake(gameFunc->game, 30, 0);
			gameFunc->PlaySound(L"CS_026_quake");
		}
		stateGravity.Step();
		break;
	case 4://悠闲
		if (Random(0, 120) == 10)
		{
			wink_counter = 8;
		}
		if (wink_counter > 0)
		{
			wink_counter--;
			ani.sprite_index = lr == 0 ? L"ls_arowana_swim_l" : L"ls_arowana_swim_r";
		}
		else
		{
			ani.sprite_index = lr == 0 ? L"ls_arowana_stand_l" : L"ls_arowana_stand_r";
		}
		stateGravity.Step();
		break;
	case 5://睡觉
		ani.sprite_index = lr == 0 ? L"ls_arowana_stand_l" : L"ls_arowana_stand_r";
		vx = 0;
		vy = 0;
		//产生zzz
		if (++act_wait > 100)
		{
			act_wait = 0;
			SetPeCS_Zzz(shared_from_this(), x + (lr == 0 ? -16 : 16), y);
		}
		stateGravity.Step();
		break;
	case 6://装死
		ani.sprite_index = lr == 0 ? L"ls_arowana_playdead_l" : L"ls_arowana_playdead_r";
		stateGravity.Step();
		break;
	case 7://跳入水中
		if (vy < 0)
			stateGravity.SetGravityScale(0.4f);
		else
			stateGravity.SetGravityScale(1);
		ani.sprite_index = lr == 0 ? L"ls_arowana_jump_l" : L"ls_arowana_jump_r";
		stateGravity.Step();
		stateSplash.Step();
		break;
	case 8://移动
		ani.sprite_index = lr == 0 ? L"ls_arowana_swim_l" : L"ls_arowana_swim_r";
		stateGravity.Step();
		break;
	case 9://上下浮动
		vx = 0;
		if (floatSrcY < y)
			vy -= 8 / ts;
		if (floatSrcY > y)
			vy += 8 / ts;
		if (vy > 0x100)
			vy = 0x100;
		if (vy < -0x100)
			vy = -0x100;
		ani.sprite_index = lr == 0 ? L"ls_arowana_swim_l" : L"ls_arowana_swim_r";
		break;
	case 10:
		ani.sprite_index = lr == 0 ? L"ls_arowana_swim_l" : L"ls_arowana_swim_r";
		break;
	case 11://游向目标
		{
			auto wtarget = animation_target.lock();
			if (wtarget)
			{
				float vec_x = wtarget->x - x;
				float vec_y = wtarget->y - y;
				auto vec = XMVector2Normalize(XMVectorSet(vec_x, vec_y, 0, 0));
				float dir_vx = XMVectorGetX(vec);
				float dir_vy = XMVectorGetY(vec);
				vx = dir_vx * animation_moveSpeed;
				vy = dir_vy * animation_moveSpeed;
				lr = x > wtarget->x ? 0 : 1;
				ani.sprite_index = lr == 0 ? L"ls_arowana_swim_l" : L"ls_arowana_swim_r";
			}
		}
		break;
	case 12://冲撞
		{
			const float dashMaxSpeed = 0x900 / ts;
			const float dashAcc = 0x80 / ts;
			//加速直到撞到墙壁
			if (lr == 0)
			{
				if (vx - dashAcc > -dashMaxSpeed)
					vx -= dashAcc;
				else
					vx = -dashMaxSpeed;
			}
			else
			{
				if (vx + dashAcc < dashMaxSpeed)
					vx += dashAcc;
				else
					vx = dashMaxSpeed;
			}
		}
		break;
	case 13://环绕浮动 鱼状态下的
		if (floatSrcY < y)
			vy -= 8 / ts;
		if (floatSrcY > y)
			vy += 8 / ts;
		if (vy > 0x100)
			vy = 0x100;
		if (vy < -0x100)
			vy = -0x100;

		if (floatSrcX < x)
			vx -= 8 / ts;
		if (floatSrcX > x)
			vx += 8 / ts;
		if (vx > 0x100)
			vx = 0x100;
		if (vx < -0x100)
			vx = -0x100;
		ani.sprite_index = lr == 0 ? L"ls_arowana_swim_l" : L"ls_arowana_swim_r";
		break;
	case 14://大跳
		if (vy < 0)
			stateGravity.SetGravityScale(0.4f);
		else
			stateGravity.SetGravityScale(1);
		if (cbRect.cbBottom && bSetQuake)
		{
			bSetQuake = false;
			vx = 0; vy = 0;
			cbRect.enableSoild = true;
			gameFunc->SetQuake(gameFunc->game, 30, 0);
			gameFunc->PlaySound(L"CS_026_quake");
			SetPeSmog(shared_from_this(), x, y, 1, 1, 135);
			SetPeSmog(shared_from_this(), x, y, 1, 1, 45);
			SetState(2, lr);
		}
		ani.sprite_index = lr == 0 ? L"ls_arowana_jump_l" : L"ls_arowana_jump_r";
		stateGravity.Step();
		stateSplash.Step();
		break;
	case 15://被传送
		stateTeleport.Step();
		ani.sprite_index = lr == 0 ? L"ls_arowana_stand_l" : L"ls_arowana_stand_r";
		break;
	}
	//清除最后一次碰撞结果
	Entity::ClearCollisionResult();
	//执行运动
	Entity::Step();
	//执行碰撞
	Entity::Collision();
	//维持在斜坡上
	Entity::KeepOnSlopes();
	AnimateStep();
}

void CS_ArowanaAni::SetState(int stateID, int lr)
{
	if (stateID < 200)
	{
		this->lr = lr;
		this->stateID = stateID;
		switch (stateID)
		{
		default:
		case 0:
			ani.sprite_index = lr == 0 ? L"ls_arowana_swim_l" : L"ls_arowana_swim_r";
			AnimateStep();
			break;
		}
	}
}

void CS_ArowanaAni::SetState(std::wstring stateName, int lr)
{
	if (bSetTarget)
	{
		bSetTarget = false;
		auto& allRes = *gameFunc->GetLoadedEntity(gameFunc->entityRes);
		EntityLayer* eLayer = nullptr;
		for (auto& res : allRes)
		{
			if (res.first->layerType == 0)
			{
				eLayer = &res.second;
				break;
			}
		}
		if (eLayer)
		{
			bool bFound = false;
			//在全局实体里寻找
			auto& allPlayer = *gameFunc->GetGlobalEntityTable(gameFunc->game);
			for (auto& p : allPlayer)
			{
				auto wplayer = p.second.lock();
				if (wplayer && wplayer->el.name == stateName)
				{
					animation_target = wplayer;
					bFound = true;
					break;
				}
			}
			//在地图实体层里寻找
			if (!bFound)
			{
				for (auto& e : eLayer->Ls)
				{
					if (e->el.eventName == stateName)
					{
						animation_target = e;
						break;
					}
				}
			}
		}
	}
	else
	{
		this->lr = lr;
		if (stateName == L"normal")
		{
			stateID = 0;
			bShowDizzy = false;
			face = 0;
		}
		else if (stateName == L"dizzy")
		{
			stateID = 0;
			bShowDizzy = true;
			face = 2;
		}
		else if (stateName == L"fallen")
		{
			stateID = 1;
			bShowDizzy = true;
			face = 0;
		}
		else if (stateName == L"wake")
		{
			stateID = 1;
			bShowDizzy = false;
			face = 0;
		}
		else if (stateName == L"stand")
		{
			stateID = 2;
			bShowDizzy = false;
			face = 0;
		}
		else if (stateName == L"makeSmoke")
		{
			gameFunc->PlaySound(L"CS_071_little_crash");
			//创建云团
			SetCS_PeSmokeMedium(shared_from_this(), x, y);
		}
		else if (stateName == L"jump")
		{
			cbRect.cbBottom = false;
			stateID = 3;
			bSetQuake = true;
			vy = -2;
		}
		else if (stateName == L"angry")
		{
			face = 3;
		}
		else if (stateName == L"silk_ribbon")
		{
			bShowSilkRibbon = true;
		}
		else if (stateName == L"leisurely" || stateName == L"wink")
		{
			stateID = 4;
		}
		else if (stateName == L"sleep")
		{
			stateID = 5;
			face = 4;
		}
		else if (stateName == L"play_dead")
		{
			stateID = 6;
		}
		else if (stateName == L"ignoreMovePlatform")
			cbRect.ignoreMovePlatform = lr != 0;
		else if (stateName == L"no_gravity")
		{
			vy = 0;
			stateGravity.SetEnable(lr != 0);
		}
		else if (stateName == L"jump_to_water")
		{
			stateID = 7;
			vy = -0x400 / ts;
			vx = lr == 0 ? vx = -animation_moveSpeed : vx = animation_moveSpeed;
			cbRect.enableSoild = false;
		}
		else if (stateName == L"walk")
		{
			stateID = 8;
			vx = lr == 0 ? vx = -animation_moveSpeed : vx = animation_moveSpeed;
		}
		else if (stateName == L"float")
		{
			if (stateID != 9)
			{
				stateID = 9;
				floatSrcX = x;
				floatSrcY = y + Random(-8, 8);
				vy = 0x50 / ts;
				ani.image_counter_speed = 1;
			}
		}
		else if (stateName == L"swim")
		{
			stateID = 10;
			vx = lr == 0 ? vx = -animation_moveSpeed : vx = animation_moveSpeed;
			vy = 0;
		}
		else if (stateName == L"swim2")
		{
			stateID = 10;
			vx = lr == 0 ? vx = -animation_moveSpeed * 2 : vx = animation_moveSpeed * 2;
			vy = 0;
		}
		else if (stateName == L"set_target")
			bSetTarget = true;
		else if (stateName == L"swim_target")
			stateID = 11;
		else if (stateName == L"swim_back")
		{
			stateID = 10;
			vx = lr == 0 ? vx = animation_moveSpeed : vx = -animation_moveSpeed;
			vy = 0;
		}
		else if (stateName == L"dash")
		{
			vx = 0;
			vy = 0;
			stateID = 12;
			auto wlightTail = std::make_shared<PeLightTail>(shared_from_this(), 80, 16);
			lightTail = wlightTail;
			gameFunc->SetEntity(shared_from_this(), wlightTail);
		}
		else if (stateName == L"stop")
		{
			vx = 0;
			vy = 0;
			stateID = 10;
			auto wlightTail = lightTail.lock();
			if (wlightTail)
				wlightTail->Leave();
		}
		else if (stateName == L"float_around")
		{
			if (stateID != 13)
			{
				stateID = 13;
				floatSrcX = x + (lr == 0 ? Random(-8, 0) : Random(0, 8));
				floatSrcY = y + Random(-8, 8);
				vy = 0x80 / ts;
				vx = lr == 0 ? -0x80 / ts : 0x80 / ts;
				ani.image_counter_speed = 2;
			}
		}
		else if (stateName == L"big_jump")
		{
			stateID = 14;
			vy = -0xc00 / ts;
			vx = lr == 0 ? vx = -animation_moveSpeed : vx = animation_moveSpeed;
			cbRect.enableSoild = false;
			bSetQuake = true;
		}
		else if (stateName == L"teleport_out")
		{
			face = 5;
			stateTeleport.SetTeleportOut();
			SetState(15, lr);
		}
	}
}

void CS_ArowanaAni::Destroy()
{
	auto wpeDizzy = peDizzy.lock();
	if (wpeDizzy)
		wpeDizzy->Destroy();
	Entity::Destroy();
}

void CS_ArowanaAni::AnimateStep()
{
	auto wpeDizzy = peDizzy.lock();
	if (wpeDizzy)
		wpeDizzy->hide = !bShowDizzy;
	ani.hideLayerList.insert(0);
	ani.hideLayerList.insert(1);
	ani.hideLayerList.insert(2);
	ani.hideLayerList.insert(3);
	ani.hideLayerList.insert(4);
	ani.hideLayerList.insert(5);
	ani.hideLayerList.insert(6);
	
	ani.hideLayerList.insert(7);
	ani.hideLayerList.insert(8);
	ani.hideLayerList.insert(9);
	if (bShowSilkRibbon)
		ani.hideLayerList.erase(7);
	else
		ani.hideLayerList.insert(7);
	switch (face)
	{
	case 0://正常
		ani.hideLayerList.erase(4);
		ani.hideLayerList.erase(8);
		break;
	case 1://受伤
		ani.hideLayerList.erase(3);
		ani.hideLayerList.erase(9);
		break;
	case 2://眩晕
		ani.hideLayerList.erase(2);
		ani.hideLayerList.erase(9);
		break;
	case 3://生气
		ani.hideLayerList.erase(0);
		ani.hideLayerList.erase(1);
		ani.hideLayerList.erase(9);
		break;
	case 4://睡觉
		ani.hideLayerList.erase(5);
		ani.hideLayerList.erase(8);
		break;
	case 5://惊讶
		ani.hideLayerList.erase(6);
		ani.hideLayerList.erase(8);
		break;
	}
}

std::shared_ptr<Entity> CreateCS_ArowanaAni()
{
	return std::make_shared<CS_ArowanaAni>();
}
