#include "GameUI.h"
#include "main.h"
#include "UiBubble.h"
#include "UiGameKey.h"
#include "Pathfinding.h"
GameUI::GameUI()
{
	for (auto& p : player1UI.SkillCDArr)
		p = 1;
	for (auto& p : player2UI.SkillCDArr)
		p = 1;
}

GameUI::~GameUI()
{
	Reset();
	for (auto& p : ui_player1Key)
		p->Destroy();
	ui_player1Key.clear();
	for (auto& p : ui_player2Key)
		p->Destroy();
	ui_player2Key.clear();
}

void GameUI::Init(MyDX11Renderer* pRenderer, MyView* pView, EntityRes* entityResCopy)
{
	this->pRenderer = pRenderer;
	this->pView = pView;
	entityRes.InitFrom(entityResCopy);
	entityRes.SetView(&uiView);
	bossHpBar.Init(pRenderer, pView);
	offY = 12;
	//初始化UI按键
	//玩家1
	for (int i = 0; i < _countof(keyArrPlayer1); i++)
	{
		auto e = std::make_shared<UiGameKey>();
		e->gameFunc = entityRes.GetGameFunc();
		e->hide = true;
		e->SetDisplay(0, i);
		if (!e->initCheck)
			e->Init(e);
		ui_player1Key.push_back(e);
		keyArrPlayer1[i] = e;//保存指针
	}
	//玩家2
	for (int i = 0; i < _countof(keyArrPlayer2); i++)
	{
		auto e = std::make_shared<UiGameKey>();
		e->gameFunc = entityRes.GetGameFunc();
		e->hide = true;
		e->SetDisplay(1, i);
		if (!e->initCheck)
			e->Init(e);
		ui_player2Key.push_back(e);
		keyArrPlayer2[i] = e;//保存指针
	}
}

void GameUI::Reset()
{
	for (auto& we : Ui)
		we->Destroy();
	Ui.clear();
	auto rst = PlayerUIData();

	auto& arr = rst.throwItem;
	/*arr.push_back(1);
	arr.push_back(1);
	arr.push_back(-1);
	arr.push_back(-1);
	arr.push_back(-1);*/

	for (int i = 0; i < _countof(rst.SkillArr); i++)
		rst.SkillArr[i] = -1;
	for (int i = 0; i < _countof(rst.SkillCDArr); i++)
		rst.SkillCDArr[i] = 1;
	for (int i = 0; i < _countof(rst.SkillDisable); i++)
		rst.SkillDisable[i] = false;
	rst.appearEffect.resize(100);
	rst.appearEffect_counter.resize(100);
	for (auto& p : rst.appearEffect_counter)
		p = 29;
	rst.disappearEffect.resize(100);
	rst.disappearEffect_counter.resize(100);
	for (auto& p : rst.disappearEffect_counter)
		p = 29;
	player1UI = player2UI = rst;
	bossHpBar.Reset();
	entityRes.Reset();
}

void GameUI::OnResetScale()
{
	if (pView)
	{
		uiView.window_w = pView->window_w;
		uiView.window_h = pView->window_h;
		uiView.scale = pView->scale;
	}
	entityRes.OnResetScale();
}

void GameUI::Step()
{
	auto wp2 = entityRes.GetMyChar_Player2().lock();
	//再设置
	if (wp2)
		showPlayer2UI = wp2->el.name != L"null";
	uiView = *pView;
	uiView.offX = uiView.offY = 0;
	//气泡效果
	BubbleStep();
	//运行界面实体
	entityRes.StepList(&Ui);
	//全部显示(按键可以运行)
	for (auto& e : ui_player1Key)
		e->hide = false;
	for (auto& e : ui_player2Key)
		e->hide = false;
	entityRes.StepList(&ui_player1Key);
	entityRes.StepList(&ui_player2Key);
	//全部隐藏
	for (auto& e : ui_player1Key)
		e->hide = true;
	for (auto& e : ui_player2Key)
		e->hide = true;
	//投掷物动画
	ThrowItemStep();
	//闪烁动画
	FlashStep();
	//Boss血条动画
	bossHpBar.Step();
	swap_counter_last = swap_counter;
	if (swap_counter > 0)
	{
		swap_counter -= 10;
		if (swap_counter < 0)
			swap_counter = 0;
	}
		
}

void GameUI::Draw(float deltaTime)
{
	if (!bVisiable)
		return;
	DrawPlayerBoard();
	DrawPlayer1UI();
	if (showPlayer2UI)
		DrawPlayer2UI();
	//界面实体
	for (auto& e : Ui)
	{
		e->DeltaTime(deltaTime);
		entityRes.DrawAddEntity(e, false);
	}
	entityRes.DrawEntity();
	//绘制按键
	for (int i = 14; i < _countof(keyArrPlayer1); i++)
	{
		auto we = keyArrPlayer1[i].lock();
		if (we)
		{
			we->hide = false;
			we->DeltaTime(deltaTime);
			entityRes.DrawAddEntity(we, false);
		}
	}
	auto wplayer2 = entityRes.GetMyChar_Player2().lock();
	if (wplayer2)
	{
		if (!wplayer2->enableAI)
		{
			if (showPlayer2UI)
			{
				for (int i = 14; i < _countof(keyArrPlayer2); i++)
				{
					auto we = keyArrPlayer2[i].lock();
					we->hide = false;
					we->DeltaTime(deltaTime);
					entityRes.DrawAddEntity(we, false);
				}
			}
		}
	}
	entityRes.DrawEntity();
	bossHpBar.Draw();
	offX = -lerp(swap_counter_last, swap_counter, deltaTime);
}

void GameUI::SetVisible(bool bVisiable)
{
	this->bVisiable = bVisiable;
}

PlayerUIData* GameUI::GetPlayerUIData(int playerIndex)
{
	switch (playerIndex)
	{
	default:
		return nullptr;
	case 0:
		return &player1UI;
	case 1:
		return &player2UI;
	}
}

UiBossHpBar* GameUI::GetBossHpBar()
{
	return &bossHpBar;
}

std::weak_ptr<Entity>* GameUI::GetPlayerKey(int playerIndex)
{
	if (playerIndex == 0)
		return keyArrPlayer1;
	else
		return keyArrPlayer2;
}

void GameUI::Swap()
{
	PlayerUIData temp = player1UI;
	player1UI = player2UI;
	player2UI = temp;
	swap_counter = swap_counter_last = swap_counter_max;
	PlaySound(L"CS_004_switchweapon");
}

void GameUI::DrawPlayerBoard()
{
	auto& tas_ui = *GetSysTexture(L"ui");
	pRenderer->SetTPenDraw(tas_ui.pSRV);
	MyView& view = *pView;
	MyRect src, dst;
	float srcX, srcY, srcW, srcH;
	float dstX, dstY, dstW, dstH;
	//Player1
	src.Set1(0, 0, 46, 9);
	dst.Set1((28 + offX) * view.scale, offY * view.scale, 46 * view.scale, 9 * view.scale);
	pRenderer->AddRenderCopy(&src, &dst);
	//投掷物
	srcW = srcH = 10;
	dstY = (30 + offY) * view.scale;
	dstW = dstH = 10 * view.scale;
	int i = 0;
	for (auto& p : player1UI.throwItem)
	{
		if (p == 0)
			continue;
		srcX = (abs(p) - 1) * 10.0f;
		srcY = 32.0f;
		srcY += (float)(player1UI.appearEffect_counter[i] / 6) * 10;
		if (p < 0)
			srcY += (float)(player1UI.disappearEffect_counter[i] / 6 + 1) * 10;
		dstX = (11 * i + 28 + offX) * view.scale;
		src.Set1(srcX, srcY, srcW, srcH);
		dst.Set1(dstX, dstY, dstW, dstH);
		pRenderer->AddRenderCopy(&src, &dst);
		i++;
	}
	if (!showPlayer2UI)
	{
		pRenderer->DrawRenderCopy();
		return;
	}
	//Player2
	auto wplayer2 = entityRes.GetMyChar_Player2().lock();
	if (!wplayer2)
		return;
	if (wplayer2->enableAI)
	{
		src.Set1(0, 18, 53, 9);
		dst.Set1(view.window_w - ((81 + offX) * view.scale), offY * view.scale, 53 * view.scale, 9 * view.scale);
	}
	else
	{
		src.Set1(0, 9, 46, 9);
		dst.Set1(view.window_w - ((74 + offX) * view.scale), offY * view.scale, 46 * view.scale, 9 * view.scale);
	}
	pRenderer->AddRenderCopy(&src, &dst);
	//Player2
	i = 0;
	for (auto& p : player2UI.throwItem)
	{
		if (p == 0)
			continue;
		srcX = (abs(p) - 1) * 10.0f;
		srcY = 32.0f;
		srcY += (float)(player2UI.appearEffect_counter[i] / 6) * 10;
		if (p < 0)
			srcY += (float)(player2UI.disappearEffect_counter[i] / 6 + 1) * 10;
		dstX = view.window_w - (11 * i + 38 + offX) * view.scale;
		src.Set1(srcX, srcY, srcW, srcH);
		dst.Set1(dstX, dstY, dstW, dstH);
		pRenderer->AddRenderCopy(&src, &dst);
		i++;
	}
	pRenderer->DrawRenderCopy();
}

void GameUI::DrawPlayer1UI()
{
	if (player1UI.uiName.length() == 0)
		return;
	auto& tas = *GetMcuiTexture(player1UI.uiName.c_str());
	pRenderer->SetTPenDraw(tas.pSRV);

	MyView& view = *pView;
	MyRect src, dst;
	float srcX, srcY, srcW, srcH;
	float dstX, dstY, dstW, dstH;
	//Player1UI
	src.Set1(0, 64, 272, 17);
	dst.Set1(offX * view.scale, (10 + offY) * view.scale, 272 * view.scale, 17 * view.scale);
	pRenderer->AddRenderCopy(&src, &dst);
	//Player1Face
	src.Set1(32.0f * player1UI.face, 0, 32, 32);
	dst.Set1((-5 + offX) * view.scale, (-5 + offY) * view.scale, 32 * view.scale, 32 * view.scale);
	pRenderer->AddRenderCopy(&src, &dst);
	//Player1Hp数字
	DrawAddNum(68, 102,
		38 + offX, offY + 12, player1UI.Hp);
	//Player1Mp数字
	DrawAddNum(68, 5.0f + 102,
		38 + offX, offY + 21, player1UI.Mp);
	//Player1 HPMPBar
	if (player1UI.Hp < 0)
		player1UI.Hp = 0;
	if (player1UI.Mp < 0)
		player1UI.Mp = 0;
	if (player1UI.HpMax < 1)
		player1UI.HpMax = 1;
	if (player1UI.MpMax < 1)
		player1UI.MpMax = 1;
	//绘制HP
	srcX = 0;
	srcY = 100.0f;
	srcW = 68 * (float)player1UI.Hp / player1UI.HpMax;
	srcH = 6;
	dstW = srcW * view.scale;
	dstH = srcH * view.scale;
	dstX = (54 + offX) * view.scale;
	dstY = (11 + offY) * view.scale;
	if (player1UI.HpBar_flash_counter > 0)
	{
		if (player1UI.HpBar_flash_counter / 2 % 2 == 0)
			src.Set1(srcX + 98, srcY, srcW, srcH);
		else
			src.Set1(srcX, srcY, srcW, srcH);
	}
	else
		src.Set1(srcX, srcY, srcW, srcH);
	dst.Set1(dstX, dstY, dstW, dstH);
	pRenderer->AddRenderCopy(&src, &dst);
	//绘制MP
	srcY += 6;
	srcW = 68 * (float)player1UI.Mp / player1UI.MpMax;
	dstY = (20 + offY) * view.scale;
	dstW = srcW * view.scale;
	if (player1UI.MpBar_flash_counter > 0)
	{
		if (player1UI.MpBar_flash_counter / 2 % 2 == 0)
			src.Set1(srcX + 98, srcY, srcW, srcH);
		else
			src.Set1(srcX, srcY, srcW, srcH);
	}
	else
		src.Set1(srcX, srcY, srcW, srcH);
	dst.Set1(dstX, dstY, dstW, dstH);
	pRenderer->AddRenderCopy(&src, &dst);
	//绘制技能
	int* skillArrPtr = player1UI.SkillArr;
	bool* skillDisablePtr = player1UI.SkillDisable;
	float* skillCDArrPtr = player1UI.SkillCDArr;
	if (player1UI.bShowChildMenu)
	{
		skillArrPtr = player1UI.SkillArr_ChildMenu;
		skillDisablePtr = player1UI.SkillDisable_ChildMenu;
		skillCDArrPtr = player1UI.SkillCDArr_ChildMenu;
	}
	srcW = srcH = 16;
	dstW = dstH = 16 * view.scale;
	for (int i = 0; i < 6; i++)
	{
		if (skillArrPtr[i] < 0)
			continue;
		srcX = skillArrPtr[i] * 16.0f;
		srcY = 112;
		if (skillDisablePtr[i])
			srcY += 32;
		srcH = 16;
		dstX = (124 + i * 17 + offX) * view.scale;
		dstY = (11 + offY) * view.scale;
		dstH = srcH * view.scale;
		//绘制冷却图标
		src.Set1(srcX, srcY + 16, srcW, srcH);
		dst.Set1(dstX, dstY, dstW, dstH);
		pRenderer->AddRenderCopy(&src, &dst);
		//绘制正常图标
		srcH = 16 * skillCDArrPtr[i];
		srcY = 112 + 16 - srcH;
		dstY = (11 + 16 - srcH + offY) * view.scale;
		if (skillDisablePtr[i])
			srcY += 32;
		dstH = srcH * view.scale;
		src.Set1(srcX, srcY, srcW, srcH);
		dst.Set1(dstX, dstY, dstW, dstH);
		pRenderer->AddRenderCopy(&src, &dst);
	}
	//绘制氧气值
	if (player1UI.o2_show)
	{
		float dx = (78 + offX);
		src.Set1(96, 176, 16, 16);
		dst.Set1((dx + 12 ) * view.scale, (-8 + offY) * view.scale, 16 * view.scale, 16 * view.scale);
		pRenderer->AddRenderCopy(&src, &dst);
		DrawAddOxygenNum(0, 177, dx, -7 + offY, player1UI.o2);
	}
	pRenderer->DrawRenderCopy();
	//技能按键位置
	int skillIndex = 0;
	for (int i = 14; i < _countof(keyArrPlayer1); i++)
	{
		auto we = keyArrPlayer1[i].lock();
		if (we)
		{
			we->last_x = we->x = 132 + skillIndex * 17.0f + offX;
			we->last_y = we->y = offY + 1;
		}
		skillIndex++;
	}
	
}

void GameUI::DrawPlayer2UI()
{
	if (player2UI.uiName.length() == 0)
		return;
	auto& tas = *GetMcuiTexture(player2UI.uiName.c_str());
	pRenderer->SetTPenDraw(tas.pSRV);

	MyView& view = *pView;
	MyRect src, dst;
	float srcX, srcY, srcW, srcH;
	float dstX, dstY, dstW, dstH;
	//Player2UI
	src.Set1(0, 81, 272, 17);
	dst.Set1(view.window_w - (272 + offX) * view.scale, (10 + offY) * view.scale, 272 * view.scale, 17 * view.scale);
	pRenderer->AddRenderCopy(&src, &dst);
	//Player2Face
	src.Set1(32.0f * player2UI.face, 32, 32, 32);
	dst.Set1(view.window_w - ((32 - 5 + offX) * view.scale), (-5 + offY) * view.scale, 32 * view.scale, 32 * view.scale);
	pRenderer->AddRenderCopy(&src, &dst);
	//Player2Hp数字
	DrawAddNum(68, 102,
		view.window_w / view.scale - (53 + offX), offY + 12, player2UI.Hp, true);
	//Player2Mp数字
	DrawAddNum(68, 5.0f + 102,
		view.window_w / view.scale - (53 + offX), offY + 21, player2UI.Mp, true);
	//Player2 HPMPBar
	if (player2UI.Hp < 0)
		player2UI.Hp = 0;
	if (player2UI.Mp < 0)
		player2UI.Mp = 0;
	if (player2UI.HpMax < 1)
		player2UI.HpMax = 1;
	if (player2UI.MpMax < 1)
		player2UI.MpMax = 1;
	//绘制HP
	srcX = 68 * ((float)player2UI.HpMax - player2UI.Hp) / player2UI.HpMax;
	srcY = 100.0f;
	srcW = 68 * (float)player2UI.Hp / player2UI.HpMax;
	srcH = 6;
	dstW = srcW * view.scale;
	dstH = srcH * view.scale;
	dstX = view.window_w - (122 - srcX + offX) * view.scale;
	dstY = (11 + offY) * view.scale;
	if (player2UI.HpBar_flash_counter > 0)
	{
		if (player2UI.HpBar_flash_counter / 2 % 2 == 0)
			src.Set1(srcX + 98, srcY, srcW, srcH);
		else
			src.Set1(srcX, srcY, srcW, srcH);
	}
	else
		src.Set1(srcX, srcY, srcW, srcH);
	dst.Set1(dstX, dstY, dstW, dstH);
	pRenderer->AddRenderCopy(&src, &dst);
	//绘制MP
	srcX = 68 * ((float)player2UI.MpMax - player2UI.Mp) / player2UI.MpMax;
	srcY += 6;
	srcW = 68 * (float)player2UI.Mp / player2UI.MpMax;
	dstX = view.window_w - (122 - srcX + offX) * view.scale;
	dstY = (20 + offY) * view.scale;
	dstW = srcW * view.scale;
	if (player2UI.MpBar_flash_counter > 0)
	{
		if (player2UI.MpBar_flash_counter / 2 % 2 == 0)
			src.Set1(srcX + 98, srcY, srcW, srcH);
		else
			src.Set1(srcX, srcY, srcW, srcH);
	}
	else
		src.Set1(srcX, srcY, srcW, srcH);
	dst.Set1(dstX, dstY, dstW, dstH);
	pRenderer->AddRenderCopy(&src, &dst);
	//绘制技能
	int* skillArrPtr = player2UI.SkillArr;
	bool* skillDisablePtr = player2UI.SkillDisable;
	float* skillCDArrPtr = player2UI.SkillCDArr;
	if (player2UI.bShowChildMenu)
	{
		skillArrPtr = player2UI.SkillArr_ChildMenu;
		skillDisablePtr = player2UI.SkillDisable_ChildMenu;
		skillCDArrPtr = player2UI.SkillCDArr_ChildMenu;
	}
	srcW = srcH = 16;
	dstW = dstH = 16 * view.scale;
	for (int i = 0; i < 6; i++)
	{
		if (skillArrPtr[i] < 0)
			continue;
		srcX = skillArrPtr[i] * 16.0f;
		srcY = 112;
		if (skillDisablePtr[i])
			srcY += 32;
		srcH = 16;
		src.Set1(srcX, srcY, srcW, srcH);
		dstX = view.window_w - (225 - i * 17 + offX) * view.scale;
		dstY = (11 + offY) * view.scale;
		dstH = srcH * view.scale;
		dst.Set1(dstX, dstY, dstW, dstH);
		//绘制冷却图标
		src.Set1(srcX, srcY + 16, srcW, srcH);
		pRenderer->AddRenderCopy(&src, &dst);
		//绘制正常图标
		srcH = 16 * skillCDArrPtr[i];
		srcY = 112 + 16 - srcH;
		dstY = (11 + 16 - srcH + offY) * view.scale;
		if (skillDisablePtr[i])
			srcY += 32;
		dstH = srcH * view.scale;
		src.Set1(srcX, srcY, srcW, srcH);
		dst.Set1(dstX, dstY, dstW, dstH);
		pRenderer->AddRenderCopy(&src, &dst);
	}
	//绘制氧气值
	if (player2UI.o2_show)
	{
		float dx = view.window_w / view.scale - (147 + offX);
		src.Set1(112, 176, 16, 16);
		dst.Set1((dx + 41) * view.scale, (-8 + offY) * view.scale, 16 * view.scale, 16 * view.scale);
		pRenderer->AddRenderCopy(&src, &dst);
		DrawAddOxygenNum(0, 177, dx, -7 + offY, player2UI.o2);
	}
	pRenderer->DrawRenderCopy();
	//技能按键位置
	int skillIndex = 0;
	for (int i = 14; i < _countof(keyArrPlayer2); i++)
	{
		auto we = keyArrPlayer2[i].lock();
		if(we)
		{
			we->last_x = we->x = 640 - (217 - skillIndex * 17.0f + offX);
			we->last_y = we->y = offY + 1;
		}
		skillIndex++;
	}
}

void GameUI::DrawAddNum(float srcX, float srcY, float dstX, float dstY, int num, bool order)
{
	MyView& view = *pView;
	MyRect src, dst;

	char numbuff[16];
	sprintf_s(numbuff, "%d", num);
	int len = (int)strlen(numbuff);
	int begin = (4 - len) * 4;
	int time = 0;
	if (order)
	{
		//正序
		begin = 0;
	}
	else
	{
		//倒序
		begin = (4 - len) * 4;
	}
	for (int i = 0; i < len; i++)
	{
		src.Set1(srcX + (numbuff[i] - '0') * 3, srcY, 3, 5);
		dst.Set1((dstX + time + begin) * view.scale,
			(dstY) * view.scale,
			3 * view.scale, 5 * view.scale);
		pRenderer->AddRenderCopy(&src, &dst);
		time += 4;
	}
}

void GameUI::DrawAddOxygenNum(float srcX, float srcY, float dstX, float dstY, int num, bool order)
{
	MyView& view = *pView;
	MyRect src, dst;
	int scale = 3;

	char numbuff[16];
	sprintf_s(numbuff, "%02d", min(num, 99));
	int len = (int)strlen(numbuff);
	int begin = (4 - len) * 4 * scale;
	int time = 0;
	if (order)
	{
		//正序
		begin = 0;
	}
	else
	{
		//倒序
		begin = (4 - len) * 4 * scale;
	}
	for (int i = 0; i < len; i++)
	{
		src.Set1(srcX + (numbuff[i] - '0') * 3 * scale, srcY, 3.0f * scale, 5.0f * scale);
		dst.Set1((dstX + time + begin) * view.scale,
			(dstY)*view.scale,
			3* scale * view.scale, 5* scale * view.scale);
		pRenderer->AddRenderCopy(&src, &dst);
		time += 4 * scale;
	}
}

void GameUI::BubbleStep()
{
	MyView& view = *pView;
	if (player1UI.o2_effect)
	{
		if (bubbleInterval > 0)
			bubbleInterval--;
		if (bubbleInterval == 0)
		{
			auto we = std::make_shared<UiBubble>();
			we->gameFunc = entityRes.GetGameFunc();
			we->x = (float)Random(0, 123);
			we->y = 48;
			if (!we->initCheck)
				we->Init(we);
			Ui.push_back(we);
			bubbleInterval = Random(0, 60);
		}
	}
	if (player2UI.o2_effect)
	{
		if (bubbleInterval > 0)
			bubbleInterval--;
		if (bubbleInterval == 0)
		{
			auto we = std::make_shared<UiBubble>();
			we->gameFunc = entityRes.GetGameFunc();
			we->x = (float)Random((int)(view.window_w / view.scale - 123), (int)(view.window_w / view.scale));
			we->y = 48;
			if (!we->initCheck)
				we->Init(we);
			Ui.push_back(we);
			bubbleInterval = Random(0, 60);
		}
	}
}

void GameUI::ThrowItemStep()
{
	PlayerUIData* pArr[2] = { &player1UI ,&player2UI };
	//ThrowItem
	for (auto& ui : pArr)
	{
		for (auto& p : ui->appearEffect_counter)
			if (p < 29)
				p++;
		for (int i = 0; i < ui->appearEffect.size(); i++)
		{
			//设置生成动画
			if (ui->appearEffect[i])
			{
				ui->appearEffect[i] = false;
				ui->appearEffect_counter[i] = 0;
			}
		}
		for (auto& p : ui->disappearEffect_counter)
			if (p < 29)
				p++;
		for (int i = 0; i < ui->disappearEffect.size(); i++)
		{
			//设置消失动画
			if (ui->disappearEffect[i])
			{
				ui->disappearEffect[i] = false;
				ui->disappearEffect_counter[i] = 0;
			}
		}
	}
}

void GameUI::FlashStep()
{
	PlayerUIData* pArr[2] = { &player1UI ,&player2UI };
	//Flash
	for (auto& ui : pArr)
	{
		if (ui->HpBar_flash_counter > 0)
			ui->HpBar_flash_counter--;
		if (ui->MpBar_flash_counter > 0)
			ui->MpBar_flash_counter--;
	}
}
