#include "CS_JackAni.h"
#include "CS_PeZzz.h"
#include <PeSmog.h>

CS_JackAni::CS_JackAni()
{
	ani.png = L"CS_CaveStoryMod";
	//启用碰撞
	cbRect.enableCbRect = true;
	cbRect.enableSoild = true;
	//设置碰撞框
	cbRect.left = cbRect.right = 5;
	cbRect.top = 6;
	cbRect.bottom = 8;
}

void CS_JackAni::Init(std::weak_ptr<Entity> self)
{
	stateGravity.Init(shared_from_this());
	stateSplash.Init(shared_from_this());
	Entity::Init(self);
}

void CS_JackAni::Step()
{
	//跟上移动平台
	Entity::BeginMovingPlatform();
	//图层动画
	AnimateStep();
	if (fishState)
	{
		switch (stateID)
		{
		default:
		case 0://眨眼
			//眨眼
			if (Random(0, 120) == 10)
			{
				wink_counter = 8;
			}
			if (wink_counter > 0)
			{
				wink_counter--;
				ani.image_index = 1;
			}
			else
			{
				ani.image_index = 0;
			}
			stateGravity.State();
			stateSplash.State();
			break;
		case 8:
			if (lr == 0)
				vx = -animation_moveSpeed;
			else
				vx = animation_moveSpeed;
			//重力
			stateGravity.State();
			stateSplash.State();
			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;
			break;
		case 10://水平直线游泳
			break;
		case 11://游向目标
			{
				auto wtarget = animation_target.lock();
				if (wtarget)
				{
					float dx = wtarget->x - x;
					float dy = wtarget->y - y;
					if (dx * dx + dy * dy > 12 * 12)
					{
						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;
					}
					else
					{
						vx = vy = 0;
					}
					ani.sprite_index = lr == 0 ? L"mc_jackfish_swim_l" : L"mc_jackfish_swim_r";
				}
			}
			break;
		case 12://环绕浮动 鱼状态下的
			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;
			break;
		case 13:
			if (vy < 0)
				stateGravity.SetGravityScale(0.4f);
			else
				stateGravity.SetGravityScale(1);
			if (cbRect.cbBottom && bSetLanding)
			{
				bSetLanding = false;
				vx = 0; vy = 0;
				ani.image_counter_speed = 1;
				SetPeSmog(shared_from_this(), x, y, 1, 1, 135);
				SetPeSmog(shared_from_this(), x, y, 1, 1, 45);
				SetState(201, lr);
				SetState(0, lr);
			}
			stateGravity.Step();
			break;
		}
	}
	else
	{
		stateGravity.Step();
		switch (stateID)
		{
		case 0://站立
			//眨眼
			if (Random(0, 120) == 10)
			{
				wink_counter = 8;
			}
			if (wink_counter > 0)
			{
				wink_counter--;
				ani.image_index = 1;
			}
			else
			{
				ani.image_index = 0;
			}
			break;
		case 2://徘徊
			if (wonder_counter > 0)
			{
				wonder_counter--;
				if (wonder_counter == 0)
				{
					lr = lr == 0 ? 1 : 0;
					wonder_counter = wonder_counter_max;
				}
			}
			if (lr == 0)
				vx = -animation_moveSpeed / 2;
			else
				vx = animation_moveSpeed / 2;
			ani.image_counter_speed = 0.5f;
			ani.sprite_index = lr == 0 ? L"mc_jack_move_l" : L"mc_jack_move_r";
			break;
		case 3://睡觉
			vx = 0;
			vy = 0;
			//产生zzz
			if (++act_wait > 100)
			{
				act_wait = 0;
				SetPeCS_Zzz(shared_from_this(), x, y);
			}
			break;
		case 4://躺下
			break;
		case 5://坐在椅子上
			vx = 0;
			vy = 0;
			//眨眼
			if (Random(0, 120) == 10)
			{
				wink_counter = 8;
			}
			if (wink_counter > 0)
			{
				wink_counter--;
				ani.image_index = 1;
			}
			else
			{
				ani.image_index = 0;
			}
			break;
		case 14://抛高庆祝目标
			{
				auto wanimation_target = animation_target.lock();
				if (wanimation_target)
				{
					if (wanimation_target->y < y - 8)
						ani.sprite_index = lr == 0 ? L"mc_jack_stand_lu" : L"mc_jack_stand_ru";
					else
						ani.sprite_index = lr == 0 ? L"mc_jack_stand_l" : L"mc_jack_stand_r";
				}
			}
			break;
		case 15://被击中
			if (cbRect.cbBottom)
			{
				ani.sprite_index = lr == 0 ? L"mc_jack_lie_l" : L"mc_jack_lie_r";
				stateID = 16;
			}
			break;
		case 16://趴在地上
			if (abs(vx) > 0.001f)
				vx /= 1.05f;
			break;
		case 17://被推动
			break;
		}
	}
	//跟上移动平台
	Entity::EndMovingPlatform();
	//跟上移动平台
	Entity::EndMovingPlatform();
	//清除最后一次碰撞结果
	Entity::ClearCollisionResult();
	//动画延迟一帧
	if (animation_delay)
		animation_delay = false;
	else
		Entity::Step();//执行运动
	//执行碰撞
	Entity::Collision();
	//维持在斜坡上
	Entity::KeepOnSlopes();
}

void CS_JackAni::SetState(int stateID, int lr)
{
	if (stateID < 200)
	{
		this->lr = lr;
		this->stateID = stateID;
		ani.image_counter_speed = 1;
		//设置动画
		switch (stateID)
		{
		case 0://站立
			vx = 0;
			if (fishState)
				ani.sprite_index = lr == 0 ? L"mc_jackfish_stand_l" : L"mc_jackfish_stand_r";
			else
				ani.sprite_index = lr == 0 ? L"mc_jack_stand_l" : L"mc_jack_stand_r";
			if (ud == -1)
				ani.sprite_index.append(L"u");
			break;
		case 1://走路
			{
				animation_delay = true;
				if (lr == 0)
					vx = -animation_moveSpeed;
				else
					vx = animation_moveSpeed;
				if (fishState)
					ani.sprite_index = lr == 0 ? L"mc_jackfish_swim_l" : L"mc_jackfish_swim_r";
				else
					ani.sprite_index = lr == 0 ? L"mc_jack_move_l" : L"mc_jack_move_r";
			}
			break;
		case 2://徘徊
			wonder_counter = wonder_counter_max;
			break;
		case 3://睡觉
			vx = 0;
			vy = 0;
			ani.sprite_index = lr == 0 ? L"mc_jack_sleep_l" : L"mc_jack_sleep_r";
			break;
		case 4://躺下
			vx = 0;
			ani.sprite_index = lr == 0 ? L"mc_jack_lie_l" : L"mc_jack_lie_r";
			break;
		case 5://坐在椅子上
			vx = 0;
			y -= 3;
			ani.sprite_index = lr == 0 ? L"mc_jack_sit_l" : L"mc_jack_sit_r";
			break;
		case 6://背对着
			ani.sprite_index = lr == 0 ? L"mc_jack_back_l" : L"mc_jack_back_r";
			break;
		case 7://跑步
			animation_delay = true;
			if (lr == 0)
				vx = -animation_moveSpeed * 2;
			else
				vx = animation_moveSpeed * 2;
			ani.sprite_index = lr == 0 ? L"mc_jack_move_l" : L"mc_jack_move_r";
			ani.image_counter_speed = 2;
			break;
		case 8://跳入水中
			vy = -0x400 / ts;
			vx = lr == 0 ? vx = -0x200 / ts : vx = 0x200 / ts;
			gameFunc->PlaySound(L"CS_fishjump");
			break;
		case 9://上下浮动 鱼状态下的
			floatSrcX = x;
			floatSrcY = y + Random(-8, 8);
			vy = 0x100 / ts;
			ani.image_counter_speed = 1;
			ani.sprite_index = lr == 0 ? L"mc_jackfish_swim_l" : L"mc_jackfish_swim_r";
			break;
		case 10://水平直线游泳
			animation_delay = true;
			vx = lr == 0 ? -animation_moveSpeed : animation_moveSpeed;
			vy = 0;
			ani.sprite_index = lr == 0 ? L"mc_jackfish_swim_l" : L"mc_jackfish_swim_r";
			break;
		case 11://游向目标
			break;
		case 12://环绕浮动 鱼状态下的
			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;
			ani.sprite_index = lr == 0 ? L"mc_jackfish_swim_l" : L"mc_jackfish_swim_r";
			break;
		case 13:
			vy = -0xc00 / ts - Random(0, 0x200) / ts;
			vx = lr == 0 ? vx = -animation_moveSpeed : vx = animation_moveSpeed;
			vx *= 1.5f;
			bSetLanding = true;
			break;
		case 14://抛高庆祝目标
			break;
		case 15://被击中
			vx = lr == 0 ? -0x200 / ts : 0x200 / ts;
			vy = -0x300 / ts;
			ani.sprite_index = lr == 0 ? L"mc_jack_hurt_l" : L"mc_jack_hurt_r";
			break;
		case 16://趴在地上
			break;
		case 17://被推动
			if (lr == 0)
				vx = -animation_moveSpeed / 4;
			else
				vx = animation_moveSpeed / 4;
			ani.sprite_index = lr == 0 ? L"mc_jack_bepush_l" : L"mc_jack_bepush_r";
			break;
		}
	}
	else
	{
		switch (stateID)
		{
		case 200://变成鱼
			this->stateID = stateID;
			fishState = true;
			cbRect.left = cbRect.right = 5;
			cbRect.top = 4;
			cbRect.bottom = 4;
			cbRect.fullWaterBlock = true;
			ani.sprite_index = this->lr == 0 ? L"mc_jackfish_stand_l" : L"mc_jackfish_stand_r";
			SetPeSmog(shared_from_this(), x, y, 3);
			ani.hideLayerList.clear();
			break;
		case 201://变回来
			fishState = false;
			cbRect.left = cbRect.right = 5;
			cbRect.top = 6;
			cbRect.bottom = 8;
			cbRect.fullWaterBlock = false;
			ani.sprite_index = lr == 0 ? L"mc_jack_stand_l" : L"mc_jack_stand_r";
			showGun = false;
			SetPeSmog(shared_from_this(), x, y, 3);
			break;
		}
	}
	//图层动画
	AnimateStep();
}

void CS_JackAni::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
	{
		if (stateName == L"normal")
			SetState(0, lr);
		else if (stateName == L"walk")
			SetState(1, lr);
		else if (stateName == L"wander")
			SetState(2, lr);
		else if (stateName == L"sleep")
			SetState(3, lr);
		else if (stateName == L"lie")
			SetState(4, lr);
		else if (stateName == L"sit_on_chair")
			SetState(5, lr);
		else if (stateName == L"back")
			SetState(6, lr);
		else if (stateName == L"run")
			SetState(7, lr);
		else if (stateName == L"jump_to_water")
			SetState(8, lr);
		else if (stateName == L"float")
		{
			this->lr = lr;
			if (stateID != 9)
				SetState(9, lr);
			else
				ani.sprite_index = lr == 0 ? L"mc_jackfish_swim_l" : L"mc_jackfish_swim_r";
		}
		else if (stateName == L"swim")
			SetState(10, lr);
		else if (stateName == L"set_target")
			bSetTarget = true;
		else if (stateName == L"swim_target")
			SetState(11, lr);
		else if (stateName == L"float_around")
		{
			this->lr = lr;
			if (stateID != 12)
				SetState(12, lr);
			else
				ani.sprite_index = lr == 0 ? L"mc_jackfish_swim_l" : L"mc_jackfish_swim_r";
		}
		else if (stateName == L"big_jump")
			SetState(13, lr);
		else if (stateName == L"cheer_target")
			SetState(14, lr);
		else if (stateName == L"be_hit")
			SetState(15, lr);
		else if (stateName == L"be_push")
			SetState(17, lr);
		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"transform_fish")
			SetState(200, lr);
		else if (stateName == L"transform_back")
			SetState(201, lr);
		else if (stateName == L"show_gun")
			showGun = true;
		else if (stateName == L"hide_gun")
			showGun = false;
		else if (stateName == L"dx")
			x += lr;
		else if (stateName == L"ud")
			ud = lr;
		else if (stateName == L"topdraw")
			topDraw = lr != 0;
		//图层动画
		AnimateStep();
	}
}

void CS_JackAni::AnimateStep()
{
	if (!fishState)
	{
		ani.hideLayerList.insert(0);
		ani.hideLayerList.insert(3);
		if (showGun)
		{
			ani.hideLayerList.erase(0);
			ani.hideLayerList.erase(3);
		}
	}
}

std::shared_ptr<Entity> CreateCS_JackAni()
{
	return std::make_shared<CS_JackAni>();
}
