#include "GameFade.h"
#include "MyView.h"
#include "Entity.h"
#include "main.h"
void GameFade::Init(MyDX11Renderer* pRenderer, MyView* pView, std::weak_ptr<Entity>* mychar_ptr)
{
	this->pRenderer = pRenderer;
	this->pView = pView;
	this->mychar_ptr = mychar_ptr;
}

void GameFade::Reset()
{
	fadelight = false;
	fadein = false;
	fadeout = false;
	fade_counter = 0;
	fade_direction = 0;
	alpha = 0xff;
}

void GameFade::Step()
{
	FadeStep();
	FadeStep2();
}

void GameFade::Draw()
{
	if (!fadein && !fadeout)
		return;
	MyView& view = *pView;
	float src_x, src_y, src_w, src_h;
	float dst_x, dst_y, dst_w, dst_h;
	MyRect src, dst;
	src_w = src_h = 16;
	dst_w = view.grid_w * view.scale;
	dst_h = view.grid_h * view.scale;
	auto& tas = *GetSysTexture(GAMEFADE_TEXTURE);
	pRenderer->SetTPenDraw(tas.pSRV);
	const int xMax = (int)(view.window_w / (view.grid_w * view.scale) + 1);
	const int yMax = (int)(view.window_h / (view.grid_h * view.scale) + 1);
	if (fadein)
	{
		src_y = 0;
		switch (fade_direction)
		{
		case 0://上
			for (int y = 0; y < yMax; y++)
			{
				dst_y = y * view.grid_h * view.scale;
				for (int x = 0; x < xMax; x++)
				{
					dst_x = x * view.grid_w * view.scale;
					if (fade_counter + y > 15)
						src_x = 15 * 16;
					else
						src_x = (float)((fade_counter + y) * 16);
					if (src_x < 0)
						continue;
					src.Set1(src_x, src_y, src_w, src_h);
					dst.Set1(dst_x, dst_y, dst_w, dst_h);
					pRenderer->AddRenderCopy(&src, &dst);
				}
			}
			break;
		case 1://右
			for (int y = 0; y < yMax; y++)
			{
				dst_y = y * view.grid_h * view.scale;
				for (int x = 0; x < xMax; x++)
				{
					dst_x = x * view.grid_w * view.scale;
					if (fade_counter + (xMax - x) > 15)
						src_x = 15 * 16;
					else
						src_x = (float)((fade_counter + (xMax - x)) * 16);
					if (src_x < 0)
						continue;
					src.Set1(src_x, src_y, src_w, src_h);
					dst.Set1(dst_x, dst_y, dst_w, dst_h);
					pRenderer->AddRenderCopy(&src, &dst);
				}
			}
			break;
		case 2://下
			for (int y = 0; y < yMax; y++)
			{
				dst_y = y * view.grid_h * view.scale;
				for (int x = 0; x < xMax; x++)
				{
					dst_x = x * view.grid_w * view.scale;
					if (fade_counter + (yMax - y) > 15)
						src_x = 15 * 16;
					else
						src_x = (float)((fade_counter + (yMax - y)) * 16);
					if (src_x < 0)
						continue;
					src.Set1(src_x, src_y, src_w, src_h);
					dst.Set1(dst_x, dst_y, dst_w, dst_h);
					pRenderer->AddRenderCopy(&src, &dst);
				}
			}
			break;
		case 3://左
			for (int y = 0; y < yMax; y++)
			{
				dst_y = y * view.grid_h * view.scale;
				for (int x = 0; x < xMax; x++)
				{
					dst_x = x * view.grid_w * view.scale;
					if (fade_counter + x > 15)
						src_x = 15 * 16;
					else
						src_x = (float)((fade_counter + x) * 16);
					if (src_x < 0)
						continue;
					src.Set1(src_x, src_y, src_w, src_h);
					dst.Set1(dst_x, dst_y, dst_w, dst_h);
					pRenderer->AddRenderCopy(&src, &dst);
				}
			}
			break;
		case 4://中
			{
				int r = max(xMax, yMax);
				int time = 0;
				auto& mychar = *mychar_ptr;
				auto wmychar = mychar.lock();
				if (wmychar)
				{
					for (int t = 0; t < r; t++)
					{
						if (fade_counter + t > 15)
							time = 15;
						else
							time = fade_counter + t;
						FadeDrawSq(wmychar->x, wmychar->y, t, time);
					}
				}
			}
			break;
		case 5://无方向
			for (int y = 0; y < yMax; y++)
			{
				dst_y = y * view.grid_h * view.scale;
				for (int x = 0; x < xMax; x++)
				{
					dst_x = x * view.grid_w * view.scale;
					src_x = (float)(fade_counter * 16);
					src.Set1(src_x, src_y, src_w, src_h);
					dst.Set1(dst_x, dst_y, dst_w, dst_h);
					pRenderer->AddRenderCopy(&src, &dst);
				}
			}
			break;
		case 6://电影
			for (int y = 0; y < yMax; y++)
			{
				dst_y = y * view.grid_h * view.scale;
				for (int x = 0; x < xMax; x++)
				{
					dst_x = x * view.grid_w * view.scale;
					src_x = 15 * 16;
					src.Set1(src_x, src_y, src_w, src_h);
					dst.Set1(dst_x, dst_y, dst_w, dst_h);
					pRenderer->AddRenderCopy(&src, &dst,RGBA(0xff,0xff,0xff, (BYTE)(255 * fade_counter / 16)));
				}
			}
			break;
		}
	}
	if (fadeout)
	{
		src_y = 0;
		switch (fade_direction)
		{
		case 0://上
			for (int y = 0; y < yMax; y++)
			{
				dst_y = y * view.grid_h * view.scale;
				for (int x = 0; x < xMax; x++)
				{
					dst_x = x * view.grid_w * view.scale;
					if (fade_counter - yMax + y > 15)
						src_x = 15 * 16;
					else
						src_x = (float)((fade_counter - yMax + y) * 16);
					if (src_x < 0)
						continue;
					src.Set1(src_x, src_y, src_w, src_h);
					dst.Set1(dst_x, dst_y, dst_w, dst_h);
					pRenderer->AddRenderCopy(&src, &dst);
				}
			}
			break;
		case 1://右
			for (int y = 0; y < yMax; y++)
			{
				dst_y = y * view.grid_h * view.scale;
				for (int x = 0; x < xMax; x++)
				{
					dst_x = x * view.grid_w * view.scale;
					if (fade_counter - x > 15)
						src_x = 15 * 16;
					else
						src_x = (float)((fade_counter - x) * 16);
					if (src_x < 0)
						continue;
					src.Set1(src_x, src_y, src_w, src_h);
					dst.Set1(dst_x, dst_y, dst_w, dst_h);
					pRenderer->AddRenderCopy(&src, &dst);
				}
			}
			break;
		case 2://下
			for (int y = 0; y < yMax; y++)
			{
				dst_y = y * view.grid_h * view.scale;
				for (int x = 0; x < xMax; x++)
				{
					dst_x = x * view.grid_w * view.scale;
					if (fade_counter - y > 15)
						src_x = 15 * 16;
					else
						src_x = (float)((fade_counter - y) * 16);
					if (src_x < 0)
						continue;
					src.Set1(src_x, src_y, src_w, src_h);
					dst.Set1(dst_x, dst_y, dst_w, dst_h);
					pRenderer->AddRenderCopy(&src, &dst);
				}
			}
			break;
		case 3://左
			for (int y = 0; y < yMax; y++)
			{
				dst_y = y * view.grid_h * view.scale;
				for (int x = 0; x < xMax; x++)
				{
					dst_x = x * view.grid_w * view.scale;
					if (fade_counter - xMax + x > 15)
						src_x = 15 * 16;
					else
						src_x = (float)((fade_counter - xMax + x) * 16);
					if (src_x < 0)
						continue;
					src.Set1(src_x, src_y, src_w, src_h);
					dst.Set1(dst_x, dst_y, dst_w, dst_h);
					pRenderer->AddRenderCopy(&src, &dst);
				}
			}
			break;
		case 4://中
			{
				int r = max(xMax, yMax);
				int time = 0;
				auto& mychar = *mychar_ptr;
				auto wmychar = mychar.lock();
				if (wmychar)
				{
					for (int t = 0; t < r; t++)
					{
						if (fade_counter - r + t > 15)
							time = 15;
						else
							time = fade_counter - r + t;
						FadeDrawSq(wmychar->x, wmychar->y, t, time);
					}
				}
			}
			break;
		case 5://无方向
			for (int y = 0; y < yMax; y++)
			{
				dst_y = y * view.grid_h * view.scale;
				for (int x = 0; x < xMax; x++)
				{
					dst_x = x * view.grid_w * view.scale;
					src_x = (float)(fade_counter * 16);
					src.Set1(src_x, src_y, src_w, src_h);
					dst.Set1(dst_x, dst_y, dst_w, dst_h);
					pRenderer->AddRenderCopy(&src, &dst);
				}
			}
			break;
		case 6://电影
			for (int y = 0; y < yMax; y++)
			{
				dst_y = y * view.grid_h * view.scale;
				for (int x = 0; x < xMax; x++)
				{
					dst_x = x * view.grid_w * view.scale;
					src_x = 15 * 16;
					src.Set1(src_x, src_y, src_w, src_h);
					dst.Set1(dst_x, dst_y, dst_w, dst_h);
					pRenderer->AddRenderCopy(&src, &dst, RGBA(0xff, 0xff, 0xff, (BYTE)(255 * fade_counter / 16)));
				}
			}
			break;
		}
	}
	pRenderer->DrawRenderCopy();
}

void GameFade::FAI(int direction)
{
	fadein = true;
	fade_counter = 15;
	fade_direction = direction;
}

void GameFade::FAO(int direction)
{
	fadeout = true;
	fade_counter = 0;
	fade_direction = direction;
}

bool GameFade::GetLight()
{
	return fadelight;
}

void GameFade::SetLight(bool bLight)
{
	fadelight = bLight;
}

bool GameFade::GetFadeIn()
{
	return fadein;
}

bool GameFade::GetFadeOut()
{
	return fadeout;
}

void GameFade::FadeStep()
{
	MyView& view = *pView;
	const int yMax = (int)(view.window_h / (view.grid_h * view.scale) + 1);
	const int xMax = (int)(view.window_w / (view.grid_w * view.scale) + 1);
	if (fadein)
	{
		switch (fade_direction)
		{
		case 0://上
			if (fade_counter + yMax > 0)
				fade_counter--;
			if (fade_counter + yMax == 0)
			{
				fadein = false;
				fadelight = true;
			}
			break;
		case 1://右
			if (fade_counter + xMax + 1 > 0)
				fade_counter--;
			if (fade_counter + xMax + 1 == 0)
			{
				fadein = false;
				fadelight = true;
			}
			break;
		case 2://下
			if (fade_counter + yMax + 1 > 0)
				fade_counter--;
			if (fade_counter + yMax + 1 == 0)
			{
				fadein = false;
				fadelight = true;
			}
			break;
		case 3://左
			if (fade_counter + xMax > 0)
				fade_counter--;
			if (fade_counter + xMax == 0)
			{
				fadein = false;
				fadelight = true;
			}
			break;
		case 4://中
			{
				int r = max(xMax, yMax);
				if (fade_counter + r > 0)
					fade_counter--;
				if (fade_counter + r == 0)
				{
					fadein = false;
					fadelight = true;
				}
			}
			break;
		case 5://无方向
			if (fade_counter > 0)
				fade_counter--;
			if (fade_counter == 0)
			{
				fadein = false;
				fadelight = true;
			}
			break;
		case 6://电影
			if (fade_counter > 0)
				fade_counter--;
			if (fade_counter == 0)
			{
				alpha = 0xff;
				fadein = false;
				fadelight = true;
			}
			break;
		}
	}
	if (fadeout)
	{
		switch (fade_direction)
		{
		case 0://上
			if (fade_counter - yMax < 16)
				fade_counter++;
			if (fade_counter - yMax == 16)
			{
				fadeout = false;
				fadelight = false;
			}
			break;
		case 1://右
			if (fade_counter - xMax < 16)
				fade_counter++;
			if (fade_counter - xMax == 16)
			{
				fadeout = false;
				fadelight = false;
			}
			break;
		case 2://下
			if (fade_counter - yMax < 16)
				fade_counter++;
			if (fade_counter - yMax == 16)
			{
				fadeout = false;
				fadelight = false;
			}
			break;
		case 3://左
			if (fade_counter - xMax < 16)
				fade_counter++;
			if (fade_counter - xMax == 16)
			{
				fadeout = false;
				fadelight = false;
			}
			break;
		case 4://中
			{
				int r = max(xMax, yMax);
				if (fade_counter - r < 16)
					fade_counter++;
				if (fade_counter - r == 16)
				{
					fadeout = false;
					fadelight = false;
				}
			}
			break;
		case 5://无方向
			if (fade_counter < 16)
				fade_counter++;
			if (fade_counter == 16)
			{
				fadeout = false;
				fadelight = false;
			}
			break;
		case 6://电影
			if (fade_counter < 16)
				fade_counter++;
			if (fade_counter == 16)
			{
				alpha = 0xff;
				fadeout = false;
				fadelight = false;
			}
			break;
		}
	}
}

void GameFade::FadeStep2()
{
	MyView& view = *pView;
	const int yMax = (int)(view.window_h / (view.grid_h * view.scale) + 1);
	const int xMax = (int)(view.window_w / (view.grid_w * view.scale) + 1);
	if (fadein)
	{
		switch (fade_direction)
		{
		case 0://上
			if (fade_counter + yMax > 0)
				fade_counter--;
			if (fade_counter + yMax == 0)
			{
				fadein = false;
				fadelight = true;
			}
			break;
		case 1://右
			if (fade_counter + xMax + 1 > 0)
				fade_counter--;
			if (fade_counter + xMax + 1 == 0)
			{
				fadein = false;
				fadelight = true;
			}
			break;
		case 2://下
			if (fade_counter + yMax + 1 > 0)
				fade_counter--;
			if (fade_counter + yMax + 1 == 0)
			{
				fadein = false;
				fadelight = true;
			}
			break;
		case 3://左
			if (fade_counter + xMax > 0)
				fade_counter--;
			if (fade_counter + xMax == 0)
			{
				fadein = false;
				fadelight = true;
			}
			break;
		case 4://中
			{
				int r = max(xMax, yMax);
				if (fade_counter + r > 0)
					fade_counter--;
				if (fade_counter + r == 0)
				{
					fadein = false;
					fadelight = true;
				}
			}
			break;
		case 5://无方向
			if (fade_counter == 0)
			{
				fadein = false;
				fadelight = true;
			}
			break;
		case 6://电影
			if (fade_counter == 0)
			{
				alpha = 0xff;
				fadein = false;
				fadelight = true;
			}
			break;
		}
	}
	if (fadeout)
	{
		switch (fade_direction)
		{
		case 0://上
			if (fade_counter - yMax < 16)
				fade_counter++;
			if (fade_counter - yMax == 16)
			{
				fadeout = false;
				fadelight = false;
			}
			break;
		case 1://右
			if (fade_counter - xMax < 16)
				fade_counter++;
			if (fade_counter - xMax == 16)
			{
				fadeout = false;
				fadelight = false;
			}
			break;
		case 2://下
			if (fade_counter - yMax < 16)
				fade_counter++;
			if (fade_counter - yMax == 16)
			{
				fadeout = false;
				fadelight = false;
			}
			break;
		case 3://左
			if (fade_counter - xMax < 16)
				fade_counter++;
			if (fade_counter - xMax == 16)
			{
				fadeout = false;
				fadelight = false;
			}
			break;
		case 4://中
			{
				int r = max(xMax, yMax);
				if (fade_counter - r < 16)
					fade_counter++;
				if (fade_counter - r == 16)
				{
					fadeout = false;
					fadelight = false;
				}
			}
			break;
		case 5://无方向
			if (fade_counter == 16)
			{
				fadeout = false;
				fadelight = false;
			}
			break;
		case 6://电影
			if (fade_counter == 16)
			{
				alpha = 0xff;
				fadeout = false;
				fadelight = false;
			}
			break;
		}
	}
}

void GameFade::FadeDrawSq(double x, double y, int r, int time)
{
	//以目标位置中心绘制fade
	MyView& view = *pView;
	float src_x, src_y, src_w, src_h;
	float dst_x, dst_y, dst_w, dst_h;
	MyRect src, dst;
	src_w = src_h = 16;
	dst_w = view.grid_w * view.scale;
	dst_h = view.grid_h * view.scale;
	src_x = (float)(time * 16);
	if (src_x < 0)
		return;
	src_y = 0;
	x -= 8;
	y -= 8;
	src.Set1(src_x, src_y, src_w, src_h);
	//绘制上下边
	for (int dx = -r; dx <= r; dx++)
	{
		dst_x = (float)((x + dx * 16) * view.scale - floorf(view.offX * view.scale));
		dst_y = (float)((y - r * 16) * view.scale - floorf(view.offY * view.scale));
		dst.Set1(dst_x, dst_y, dst_w, dst_h);
		pRenderer->AddRenderCopy(&src, &dst);
		dst_y = (float)((y + r * 16) * view.scale - floorf(view.offY * view.scale));
		dst.Set1(dst_x, dst_y, dst_w, dst_h);
		pRenderer->AddRenderCopy(&src, &dst);
	}
	//绘制左右边
	for (int dy = -r; dy <= r; dy++)
	{
		dst_y = (float)((y + dy * 16) * view.scale - floorf(view.offY * view.scale));
		dst_x = (float)((x - r * 16) * view.scale - floorf(view.offX * view.scale));
		dst.Set1(dst_x, dst_y, dst_w, dst_h);
		pRenderer->AddRenderCopy(&src, &dst);
		dst_x = (float)((x + r * 16) * view.scale - floorf(view.offX * view.scale));
		dst.Set1(dst_x, dst_y, dst_w, dst_h);
		pRenderer->AddRenderCopy(&src, &dst);
	}
}
