#include "GameMsgbox.h"
#include "MyView.h"
#include "GameInput.h"
#include "Entity.h"
#include "main.h"
#include "GameScript.h"

GameMsgbox::~GameMsgbox()
{
	if (textBuffer1.pSRV)
		textBuffer1.pSRV->Release();
	if (textBuffer1.pTexture)
		textBuffer1.pTexture->Release();
	if (textBuffer2.pSRV)
		textBuffer2.pSRV->Release();
	if (textBuffer2.pTexture)
		textBuffer2.pTexture->Release();
	if (pRTV_textBuffer1)
		pRTV_textBuffer1->Release();
	if (pRTV_textBuffer2)
		pRTV_textBuffer2->Release();
}

void GameMsgbox::Init(MyDX11Renderer* pRenderer, MyView* pView, void* pGameScript, std::weak_ptr<Entity>* mychar_ptr_Player1, std::weak_ptr<Entity>* mychar_ptr_Player2)
{
	this->pRenderer = pRenderer;
	this->pView = pView;
	this->pGameScript = pGameScript;
	this->mychar_ptr_Player1 = mychar_ptr_Player1;
	this->mychar_ptr_Player2 = mychar_ptr_Player2;
	std::vector<wchar_t> wbuff;
	UTF8ToUTF16(highQualityFont.c_str(), &wbuff);
	text_fontFamily_default = wbuff.data();
	text_fontFamily = text_fontFamily_default;
}

void GameMsgbox::Step()
{
	//文本滚动
	if (!bShow)
		return;
	MyView& view = *pView;
	//特殊模式
	if (sideMode == -1)
	{
		msgbox_x = view.window_w / 2 - msgbox_count_w * view.grid_w * view.scale - 4 * view.scale;
		msgbox_count_w = 19;
	}
	else if (sideMode == 0)
	{
		msgbox_x = (view.window_w - msgbox_count_w * view.grid_w * view.scale) / 2;
		msgbox_count_w = 24;
	}
	else if (sideMode == 1)
	{
		msgbox_x = view.window_w / 2 + 4 * view.scale;;
		msgbox_count_w = 19;
	}

	switch (msgbox_mode)
	{
	default:
	case 0://下方文本框
		msgbox_y = view.window_h - (msgbox_count_h * view.grid_h + 8) * view.scale;
		break;
	case 1://上方文本框
	case 2:
		msgbox_y = 8 * view.scale;
		break;
	}
	if (!textBuffer1.pTexture || !textBuffer1.pSRV ||
		!textBuffer2.pTexture || !textBuffer2.pSRV)
		return;
	//加速滚动文本显示
	bool accRolling = false;
	std::weak_ptr<Entity> players[2];
	players[0] = *mychar_ptr_Player1;
	players[1] = *mychar_ptr_Player2;
	for (auto i = 0; i < _countof(players); i++)
	{
		auto wplayer = players[i].lock();
		if (wplayer)
		{
			if (wplayer->input.GetOk() || wplayer->input.GetCancel())
				accRolling = true;
		}
	}
	do
	{
		dst_drawbuffer1_y_set_last = dst_drawbuffer1_y_set;
		dst_drawbuffer2_y_set_last = dst_drawbuffer2_y_set;
		if (bufferSwitch)
		{
			int index = (int)(text_cursorY2 - 2 * text_lineheight);

			if (index >= 0)
			{
				if (text_rolling_counter < index)
				{
					text_rolling = true;
					text_rolling_counter += text_rolling_speed;
					if(accRolling)
						text_rolling_counter += text_rolling_speed;
					if (text_rolling_counter >= index)
						text_rolling_counter = index;
				}
				else
					text_rolling = false;
				dst_drawbuffer2_y_set = msgbox_y - text_rolling_counter;
			}
			else
				dst_drawbuffer2_y_set = msgbox_y;
			dst_drawbuffer1_y_set = dst_drawbuffer2_y_set + 3 * text_lineheight;
		}
		else
		{
			int index = (int)(text_cursorY1 - 2 * text_lineheight);
			if (index >= 0)
			{
				if (text_rolling_counter < index)
				{
					text_rolling = true;
					text_rolling_counter += text_rolling_speed;
					if (accRolling)
						text_rolling_counter += text_rolling_speed;
					if(text_rolling_counter >= index)
						text_rolling_counter = index;
				}
				else
					text_rolling = false;
				dst_drawbuffer1_y_set = msgbox_y - text_rolling_counter;
			}
			else
				dst_drawbuffer1_y_set = msgbox_y;
			dst_drawbuffer2_y_set = dst_drawbuffer1_y_set + 3 * text_lineheight;
		}
	} while ((text_tur || text_tur_temp) && text_rolling);
	//渲染文本
	RenderText();
	//头像
	if (face_id.length() > 0)
	{
		face_counter_set_last = face_counter_set;
		if (face_counter_set > 0)
			face_counter_set -= text_rolling_speed * 2;
		if (face_counter_set < 0)
			face_counter_set = 0;
	}
	//光标
	if (text_nod_counter >= text_nod_counter_max)
		text_nod_counter = 0;
	text_nod_counter++;
}

void GameMsgbox::Draw(float deltaTime)
{
	if (!bShow)
		return;
	if (!msgbox_now.length())
		msgbox_now = L"default";
	//设置绘制点（水平居中文本框）
	if(msgbox_mode != 2)
		DrawFrame();
	//绘制文本
	DrawMsgboxText(deltaTime);
	//绘制光标
	if (!bShowYNJ)
		DrawCursor();
	//绘制头像
	DrawFace(deltaTime);
}

void GameMsgbox::OnResetScale()
{
	if (!pView)
		return;
	//等待文本滚动完毕
	while (text_rolling)
		Step();
	MyView& view = *pView;
	if (textBuffer1.pTexture)
		textBuffer1.pTexture->Release();
	if (textBuffer1.pSRV)
		textBuffer1.pSRV->Release();
	if (textBuffer2.pTexture)
		textBuffer2.pTexture->Release();
	if (textBuffer2.pSRV)
		textBuffer2.pSRV->Release();
	if (pRTV_textBuffer1)
		pRTV_textBuffer1->Release();
	if (pRTV_textBuffer2)
		pRTV_textBuffer2->Release();
	UINT w = (UINT)(msgbox_count_w * view.grid_w * view.scale);
	UINT h = (UINT)(msgbox_count_h * view.grid_h * view.scale);
	pRenderer->MyCreateTexture(&textBuffer1.pTexture, w, h,
		DXGI_FORMAT_R8G8B8A8_UNORM, D3D11_USAGE_DEFAULT,
		D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
	pRenderer->MyCreateShaderResourceView(&textBuffer1.pSRV, textBuffer1.pTexture);
	pRenderer->MyCreateRTV(&pRTV_textBuffer1, textBuffer1.pTexture);
	textBuffer1.w = w;
	textBuffer1.h = h;
	pRenderer->MyCreateTexture(&textBuffer2.pTexture, w, h,
		DXGI_FORMAT_R8G8B8A8_UNORM, D3D11_USAGE_DEFAULT,
		D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
	pRenderer->MyCreateShaderResourceView(&textBuffer2.pSRV, textBuffer2.pTexture);
	pRenderer->MyCreateRTV(&pRTV_textBuffer2, textBuffer2.pTexture);
	textBuffer2.w = w;
	textBuffer2.h = h;
	if (bShowDebug)
	{
		pRenderer->RenderClearRTV(pRTV_textBuffer1, 1.0f, 0, 0, 0.5f);
		pRenderer->RenderClearRTV(pRTV_textBuffer2, 0.0f, 0, 1.0f, 0.5f);
	}
	//设置默认值
	text_fontSize_default = 16;
	text_fontSize = text_fontSize_default;
	text_color = text_color_default;
	text_lineheight = (int)(23 * view.scale);
	text_rolling_speed = (int)(2 * view.scale);
	text_color_default.r = text_color_default.g = text_color_default.b = text_color_default.a = 0xff;
	text_color = text_color_default;
	face_offx = 66 * view.scale;
	//重绘文本
	int lastIndex = msg_index;
	msg_index = 0;
	text_nod_linecounter = 0;
	bufferOutSwitch = false;
	bufferSwitch = false;
	text_cursorX1 = text_cursorX2 = text_cursorY1 = text_cursorY2 = 0;
	scaleChanging = true;
	while (msg_index < lastIndex)
		Step();
	scaleChanging = false;
}

void GameMsgbox::MSG(const wchar_t* text, int mode)
{
	bShow = true;
	msgbox_mode = 0;
	CAT(text, mode);
}

void GameMsgbox::MS2(const wchar_t* text, int mode)
{
	bShow = true;
	msgbox_mode = 2;
	CAT(text, mode);
}

void GameMsgbox::MS3(const wchar_t* text, int mode)
{
	bShow = true;
	msgbox_mode = 1;
	CAT(text, mode);
}

void GameMsgbox::AutoMSG(const wchar_t* text, int mode, float entity_y)
{
	bShow = true;
	//判断这个对象在屏幕上方还是下方
	float screen_y = (entity_y) * pView->scale - floorf(pView->offY * pView->scale);
	if (screen_y > pView->window_h / 2)
		msgbox_mode = 1;//玩家在下方用上方文本框
	else
		msgbox_mode = 0;//上方
	CAT(text, mode);
}

void GameMsgbox::MSS(int speed)
{
	text_interval = speed;
}

void GameMsgbox::TUR(bool tur)
{
	text_tur = tur;
}

void GameMsgbox::NOD()
{
	auto script = (GameScript*)pGameScript;
	script->SetNOD(true);
	text_tur_temp = false;
	std::weak_ptr<Entity> players[2];
	players[0] = *mychar_ptr_Player1;
	players[1] = *mychar_ptr_Player2;
	for (auto i = 0; i < _countof(players); i++)
	{
		auto wplayer = players[i].lock();
		if (wplayer)
		{
			wplayer->inputLock.SetJump(true);
			wplayer->inputLock.SetOk(true);
		}
	}
}

void GameMsgbox::CAT(const wchar_t* text, int mode)
{
	switch (mode)
	{
	default:
	case 0://左对齐
		msg.append(text);
		break;
	case 1://右对齐
	case 2://居中
		{
			int spaceNum = CalcSpaceNum(text, mode);
			for (int i = 0; i < spaceNum; i++)
				msg.append(L" ");
			msg.append(text);
		}
		break;
	}
}

void GameMsgbox::CLR()
{
	ClearText();
}

void GameMsgbox::CLO()
{
	bShow = false;
	YNJEnd();
	face_id.clear();
	text_tur = false;
	text_tur_temp = false;
	ClearText();
}

void GameMsgbox::FAC(std::wstring faceID)
{
	if (faceID.length() == 0)
		face_id.clear();
	else if (faceID != face_id)
	{
		face_id = faceID;
		face_counter_set_last = face_counter_set = text_rolling_speed * 24.0f;
	}
	face_id = faceID;
}

void GameMsgbox::FNT(const wchar_t* fontFamily)
{
	text_fontFamily = fontFamily;
	auto iter = msg_format.find(msg_index);
	if (iter == msg_format.end())
	{
		CmdTextFormat fmt;
		fmt.text_fontFamily = text_fontFamily;
		fmt.text_color = text_color;
		fmt.text_fontSize = text_fontSize;
		msg_format.insert(std::make_pair(msg_index, fmt));
	}
	else
	{
		CmdTextFormat& fmt = iter->second;
		fmt.text_fontFamily = fontFamily;
	}
}

void GameMsgbox::FCL(BYTE r, BYTE g, BYTE b, BYTE a)
{
	text_color.r = r;
	text_color.g = g;
	text_color.b = b;
	text_color.a = a;
	auto iter = msg_format.find(msg_index);
	if (iter == msg_format.end())
	{
		CmdTextFormat fmt;
		fmt.text_fontFamily = text_fontFamily;
		fmt.text_color = text_color;
		fmt.text_fontSize = text_fontSize;
		msg_format.insert(std::make_pair(msg_index, fmt));
	}
	else
	{
		CmdTextFormat& fmt = iter->second;
		fmt.text_color = text_color;
	}
}

void GameMsgbox::FSZ()
{
	text_fontSize = text_fontSize_default;
	auto iter = msg_format.find(msg_index);
	if (iter == msg_format.end())
	{
		CmdTextFormat fmt;
		fmt.text_fontFamily = text_fontFamily;
		fmt.text_color = text_color;
		fmt.text_fontSize = text_fontSize;
		msg_format.insert(std::make_pair(msg_index, fmt));
	}
	else
	{
		CmdTextFormat& fmt = iter->second;
		fmt.text_fontSize = text_fontSize;
	}
}

void GameMsgbox::FSZ(int fontSize)
{
	MyView& view = *pView;
	text_fontSize = fontSize;
	auto iter = msg_format.find(msg_index);
	if (iter == msg_format.end())
	{
		CmdTextFormat fmt;
		fmt.text_fontFamily = text_fontFamily;
		fmt.text_color = text_color;
		fmt.text_fontSize = text_fontSize;
		msg_format.insert(std::make_pair(msg_index, fmt));
	}
	else
	{
		CmdTextFormat& fmt = iter->second;
		fmt.text_fontSize = text_fontSize;
	}
}

void GameMsgbox::STY(const wchar_t* msgboxStyle)
{
	msgbox_now = msgboxStyle;
}

void GameMsgbox::EndEvent()
{
	CLO();
	//设置默认值
	MyView& view = *pView;
	text_fontSize_default = 16;
	text_fontSize = text_fontSize_default;
	text_color = text_color_default;
	text_lineheight = (int)(23 * view.scale);
	text_rolling_speed = (int)(2 * view.scale);
	text_color_default.r = text_color_default.g = text_color_default.b = text_color_default.a = 0xff;
	text_color = text_color_default;
	face_offx = 66 * view.scale;
	text_tur = false;
	text_tur_temp = false;
}

void GameMsgbox::YNJ()
{
	bShowYNJ = true;
	text_tur_temp = false;
}

void GameMsgbox::JNYSetYesNo(bool bYes)
{
	bYesNo = bYes;
}

void GameMsgbox::YNJEnd()
{
	bShowYNJ = false;
	bYesNo = true;
}

const wchar_t* GameMsgbox::GetMsgBoxStyle()
{
	return msgbox_now.c_str();
}

void GameMsgbox::SetSideMode(int sideMode)
{
	this->sideMode = sideMode;
}

void GameMsgbox::DrawFrame()
{
	MyView& view = *pView;
	auto& tas = *GetMsgboxTexture(msgbox_now.c_str());
	float src_x, src_y;
	float dst_x, dst_y, dst_w, dst_h;
	const float msgbox_grid_w = 16;
	const float msgbox_grid_h = 16;
	dst_w = view.grid_w * view.scale;
	dst_h = view.grid_h * view.scale;

	MyRect src, dst;
	pRenderer->SetTPenDraw(tas.pSRV);
	//绘制文本框主体
	for (int Y = 0; Y < msgbox_count_h; Y++)
	{
		for (int X = 0; X < msgbox_count_w; X++)
		{
			if (X == 0)
				src_x = 0;
			else if (X == msgbox_count_w - 1)
				src_x = msgbox_grid_w * 2;
			else
				src_x = msgbox_grid_w;
			if (Y == 0)
				src_y = 0;
			else if (Y == msgbox_count_h - 1)
				src_y = msgbox_grid_h * 2;
			else
				src_y = msgbox_grid_h;
			dst_x = msgbox_x + X * view.grid_w * view.scale;
			dst_y = msgbox_y + Y * view.grid_h * view.scale;
			src.Set1(src_x, src_y, msgbox_grid_w, msgbox_grid_h);
			dst.Set1(dst_x, dst_y, dst_w, dst_h);
			pRenderer->AddRenderCopy(&src, &dst);
		}
	}
	//绘制YNJ选择框

	if (bShowYNJ)
	{
		const int ynj_count_h = 3;
		const int ynj_count_w = 7;
		for (int Y = 0; Y < ynj_count_h; Y++)
		{
			for (int X = 0; X < ynj_count_w; X++)
			{
				if (X == 0)
					src_x = 0;
				else if (X == ynj_count_w - 1)
					src_x = msgbox_grid_w * 2;
				else
					src_x = msgbox_grid_w;
				if (Y == 0)
					src_y = msgbox_grid_h * 3 + 0;
				else if (Y == ynj_count_h - 1)
					src_y = msgbox_grid_h * 3 + msgbox_grid_h * 2;
				else
					src_y = msgbox_grid_h * 3 + msgbox_grid_h;
				if (sideMode == -1)
					dst_x = msgbox_x + (X)*view.grid_w * view.scale;
				else if (sideMode == 0)
					dst_x = msgbox_x + (X + 17) * view.grid_w * view.scale;
				else if (sideMode == 1)
					dst_x = msgbox_x + (X + 12) * view.grid_w * view.scale;
				if (msgbox_mode == 0)
					dst_y = msgbox_y + ((Y - 3) * view.grid_h - 4) * view.scale;
				else
					dst_y = msgbox_y + ((Y + 5) * view.grid_h + 4) * view.scale;
				src.Set1(src_x, src_y, msgbox_grid_w, msgbox_grid_h);
				dst.Set1(dst_x, dst_y, dst_w, dst_h);
				pRenderer->AddRenderCopy(&src, &dst);
			}
		}
		if (bYesNo)
		{
			//选中Yes
			src.Set1(0, msgbox_grid_h * 6, 
				msgbox_grid_w * 3, msgbox_grid_h);
			if (msgbox_mode == 0)
				dst_y = msgbox_y + ((1 - 3) * view.grid_h - 4)* view.scale;
			else
				dst_y = msgbox_y + ((1 + 5) * view.grid_h + 4) * view.scale;

			if (sideMode == -1)
				dst.Set1(msgbox_x + 1 * view.grid_w * view.scale,
					dst_y,
					msgbox_grid_w * 3 * view.scale, msgbox_grid_h * view.scale);
			else if (sideMode == 0)
				dst.Set1(msgbox_x + 18 * view.grid_w * view.scale,
					dst_y,
					msgbox_grid_w * 3 * view.scale, msgbox_grid_h * view.scale);
			else if (sideMode == 1)
				dst.Set1(msgbox_x + 13 * view.grid_w * view.scale,
					dst_y,
					msgbox_grid_w * 3 * view.scale, msgbox_grid_h * view.scale);
		
			pRenderer->AddRenderCopy(&src, &dst);
			src.Set1(0, msgbox_grid_h * 9,
				msgbox_grid_w * 3, msgbox_grid_h);
			if (sideMode == -1)
				dst.Set1(msgbox_x + 4 * view.grid_w * view.scale,
					dst_y,
					msgbox_grid_w * 3 * view.scale, msgbox_grid_h * view.scale);
			else if (sideMode == 0)
				dst.Set1(msgbox_x + 21 * view.grid_w * view.scale,
					dst_y,
					msgbox_grid_w * 3 * view.scale, msgbox_grid_h * view.scale);
			else if (sideMode == 1)
				dst.Set1(msgbox_x + 16 * view.grid_w * view.scale,
					dst_y,
					msgbox_grid_w * 3 * view.scale, msgbox_grid_h * view.scale);
			pRenderer->AddRenderCopy(&src, &dst);
		}
		else
		{
			//选中No
			src.Set1(0, msgbox_grid_h * 7,
				msgbox_grid_w * 3, msgbox_grid_h);
			if (msgbox_mode == 0)
				dst_y = msgbox_y + ((1 - 3) * view.grid_h - 4) * view.scale;
			else
				dst_y = msgbox_y + ((1 + 5) * view.grid_h + 4) * view.scale;
			if (sideMode == -1)
				dst.Set1(msgbox_x + 1 * view.grid_w * view.scale,
					dst_y,
					msgbox_grid_w * 3 * view.scale, msgbox_grid_h * view.scale);
			else if (sideMode == 0)
				dst.Set1(msgbox_x + 18 * view.grid_w * view.scale,
					dst_y,
					msgbox_grid_w * 3 * view.scale, msgbox_grid_h * view.scale);
			else if (sideMode == 1)
				dst.Set1(msgbox_x + 13 * view.grid_w * view.scale,
					dst_y,
					msgbox_grid_w * 3 * view.scale, msgbox_grid_h * view.scale);
			pRenderer->AddRenderCopy(&src, &dst);
			src.Set1(0, msgbox_grid_h * 8,
				msgbox_grid_w * 3, msgbox_grid_h);
			if (sideMode == -1)
				dst.Set1(msgbox_x + 4 * view.grid_w * view.scale,
					dst_y,
					msgbox_grid_w * 3 * view.scale, msgbox_grid_h * view.scale);
			else if (sideMode == 0)
				dst.Set1(msgbox_x + 21 * view.grid_w * view.scale,
					dst_y,
					msgbox_grid_w * 3 * view.scale, msgbox_grid_h * view.scale);
			else if (sideMode == 1)
				dst.Set1(msgbox_x + 16 * view.grid_w * view.scale,
					dst_y,
					msgbox_grid_w * 3 * view.scale, msgbox_grid_h * view.scale);
			pRenderer->AddRenderCopy(&src, &dst);
		}
	}
	pRenderer->DrawRenderCopy();
}

void GameMsgbox::DrawMsgboxText(float deltaTime)
{
	if (!textBuffer1.pTexture || !textBuffer1.pSRV ||
		!textBuffer2.pTexture || !textBuffer2.pSRV)
		return;
	MyView& view = *pView;
	MyRect dst, clip;
	//设置剪切矩形
	clip.Set1(msgbox_x,
		msgbox_y + 6 * view.scale,
		msgbox_count_w * view.grid_w * view.scale,
		msgbox_count_h * view.grid_h * view.scale - 10 * view.scale);
	float dst_drawbuffer1_x = msgbox_x + 6 * view.scale;
	float dst_drawbuffer2_x = dst_drawbuffer1_x;
	if (face_id.length() > 0)//如果要绘制头像
	{
		dst_drawbuffer1_x += face_offx;
		dst_drawbuffer2_x += face_offx;
	}
	if (dst_drawbuffer1_y_set_last < dst_drawbuffer1_y_set)
		dst_drawbuffer1_y_set_last = dst_drawbuffer1_y_set;
	float dst_drawbuffer1_y = lerp(dst_drawbuffer1_y_set_last, dst_drawbuffer1_y_set, deltaTime);
	pRenderer->SetScissorRect(&clip);
	pRenderer->SetTPenDraw(textBuffer1.pSRV);
	dst.Set1(dst_drawbuffer1_x, dst_drawbuffer1_y + msgboxTextOffy * view.scale, (float)textBuffer1.w, (float)textBuffer1.h);
	pRenderer->AddRenderCopy(nullptr, &dst);
	pRenderer->DrawRenderCopy();

	if (dst_drawbuffer2_y_set_last < dst_drawbuffer2_y_set)
		dst_drawbuffer2_y_set_last = dst_drawbuffer2_y_set;
	float dst_drawbuffer2_y = lerp(dst_drawbuffer2_y_set_last, dst_drawbuffer2_y_set, deltaTime);
	pRenderer->SetTPenDraw(textBuffer2.pSRV);
	dst.Set1(dst_drawbuffer2_x, dst_drawbuffer2_y + msgboxTextOffy * view.scale, (float)textBuffer2.w, (float)textBuffer2.h);
	pRenderer->AddRenderCopy(nullptr, &dst);
	pRenderer->DrawRenderCopy();
	pRenderer->SetScissorRect();
}

void GameMsgbox::DrawCursor()
{
	auto script = (GameScript*)pGameScript;
	if (!script->GetNOD())
		return;
	MyView& view = *pView;
	if (text_nod_counter < text_nod_counter_max / 2)
	{
		MyRect dst;
		float dst_x, dst_y, dst_w, dst_h;
		dst_x = 0;
		dst_y = 0;
		dst_w = (float)text_fontSize * view.scale / 2;
		dst_h = (float)text_fontSize * view.scale;
		if (bufferOutSwitch)
		{
			dst_x += text_cursorX2 + text_fontSize * view.scale;
			dst_y += text_cursorY2 + 2 * view.scale + text_lineheight - dst_h;
		}
		else
		{
			dst_x += text_cursorX1 + text_fontSize * view.scale;
			dst_y += text_cursorY1 + 2 * view.scale + text_lineheight - dst_h;
		}
		if (text_nod_linecounter >= 3)
			dst_y = 2 * view.scale + text_lineheight * 3 - dst_h;
		if (face_id.length() > 0)
			dst_x += face_offx;
		dst_x += msgbox_x;
		dst_y += msgbox_y;
		dst.Set1(dst_x, dst_y, dst_w, dst_h);
		pRenderer->SetPenDraw();
		pRenderer->AddFillRect(&dst);
		pRenderer->DrawFillRect();
	}
}

void GameMsgbox::DrawFace(float deltaTime)
{
	if (face_id.length() == 0)
		return;
	MyView& view = *pView;
	MyRect dst, clip;
	auto iter_displayInfo = faceIDTable.find(face_id);
	if (iter_displayInfo == faceIDTable.end())
	{
		wchar_t wbuff[MAX_PATH];
		swprintf_s(wbuff, L"未定义的面孔ID：%s", face_id.c_str());
		MessageBox(hwnd, wbuff, L"资源错误", MB_ICONWARNING);
		face_id.clear();
		return;
	}
	FaceDisplayInfo& displayInfo = iter_displayInfo->second;
	auto iter_fileInfo = facefileTable.find(displayInfo.facefile);
	if (iter_fileInfo == facefileTable.end())
	{
		wchar_t wbuff[MAX_PATH];
		swprintf_s(wbuff, L"未定义的面孔文件：%s", displayInfo.facefile.c_str());
		MessageBox(hwnd, wbuff, L"资源错误", MB_ICONWARNING);
		face_id.clear();
		return;
	}
	bool bInterArea = iter_fileInfo->second;
	MyTextureAndSRV* tas = nullptr;
	float dst_x, dst_y, dst_w, dst_h;
	float clip_x, clip_y, clip_w, clip_h;
	const int count_w = 6;
	clip_x = msgbox_x + 1 * view.scale;
	clip_y = msgbox_y + 7 * view.scale;
	clip_x += 8 * view.scale;
	clip_y += 1 * view.scale;
	clip_w = view.grid_w * 4 * view.scale;
	clip_h = view.grid_h * 4 * view.scale;
	clip.Set1(clip_x, clip_y, clip_w, clip_h);
	float face_counter = lerp(face_counter_set_last, face_counter_set, deltaTime);
	dst_x = clip_x - face_counter;
	dst_y = clip_y;
	dst_w = clip_w;
	dst_h = clip_h;

	float scaleW = dst_w / displayInfo.src.GetWidth();
	float scaleH = dst_h / displayInfo.src.GetHeight();
	if (bInterArea)
		tas = GetFaceTextureInterArea(displayInfo.facefile.c_str(), scaleW, scaleH);
	else
		tas = GetFaceTexture(displayInfo.facefile.c_str());
	pRenderer->SetScissorRect(&clip);
	pRenderer->SetTPenDraw(tas->pSRV);
	dst.Set1(dst_x, dst_y, dst_w, dst_h);
	if (bInterArea)
	{
		MyRect srcRedir = displayInfo.src;
		srcRedir.left *= scaleW;
		srcRedir.right *= scaleW;
		srcRedir.top *= scaleH;
		srcRedir.bottom *= scaleH;
		pRenderer->AddRenderCopy(&srcRedir, &dst);
	}
	else
	{
		pRenderer->AddRenderCopy(&displayInfo.src, &dst);
	}
	pRenderer->DrawRenderCopy();
	pRenderer->SetScissorRect();
}

void GameMsgbox::RenderText()
{
	MyView& view = *pView;
	GameScript* script = (GameScript*)pGameScript;
	if (msg_index == msg.length())
		return;
	else if (!text_tur)
		script->SetWait(1);
	//快进文本
	if (!(text_tur || text_tur_temp))
	{
		bool accText = false;
		std::weak_ptr<Entity> players[2];
		players[0] = *mychar_ptr_Player1;
		players[1] = *mychar_ptr_Player2;
		for (auto i = 0; i < _countof(players); i++)
		{
			auto wplayer = players[i].lock();
			if (wplayer)
			{
				if (wplayer->input.GetOk() || wplayer->input.GetCancel())
					accText = true;
				if (wplayer->input.GetSwitchMc())
					text_tur_temp = true;
			}
		}
		if (accText)
		{
			script->SetNODBlock();
			text_interval_counter += text_interval;
		}
		if (text_interval_counter < text_interval)
		{
			text_interval_counter++;
			return;
		}
		text_interval_counter = 1;
		if (text_rolling)
			return;
	}
	do
	{
		if (msg_index == msg.length())
			return;
		else if (!(text_tur || text_tur_temp))
			script->SetWait(1);
		auto wc = msg.at(msg_index);
		if (wc == L'\n')
		{
			text_cursorY1 += text_lineheight;
			text_cursorY2 += text_lineheight;
			text_cursorX1 = 0;
			text_cursorX2 = 0;
			text_nod_linecounter++;
			if (!bufferOutSwitch && (text_cursorY1 >= 3 * text_lineheight))
			{
				bufferOutSwitch = true;
				text_cursorY2 = 0;
				bufferSwitch = false;
				text_rolling_counter = 0;
				if (bShowDebug)
					pRenderer->RenderClearRTV(pRTV_textBuffer2, 0.0f, 0, 1.0f, 0.5f);
				else
					pRenderer->RenderClearRTV(pRTV_textBuffer2);
			}
			if (bufferOutSwitch && (text_cursorY2 >= 3 * text_lineheight))
			{
				bufferOutSwitch = false;
				text_cursorY1 = 0;
				bufferSwitch = true;
				text_rolling_counter = 0;
				if (bShowDebug)
					pRenderer->RenderClearRTV(pRTV_textBuffer1, 1.0f, 0, 0, 0.5f);
				else
					pRenderer->RenderClearRTV(pRTV_textBuffer1);
			}
		}
		else
		{
			//读取记录的字体格式
			auto iter = msg_format.find(msg_index);
			if (iter != msg_format.end())
			{
				CmdTextFormat& fmt = iter->second;
				text_color = fmt.text_color;
				text_fontSize = fmt.text_fontSize;
				text_fontFamily = fmt.text_fontFamily;
			}
			//取字体
			UTF16ToUTF8(text_fontFamily.c_str(), &utf8);
			auto font = pRenderer->MyLoadFont(utf8.data(), (int)(text_fontSize * view.scale));
			auto s = TTF_RenderGlyph_Blended(font, msg[msg_index], text_color);
			TTF_CloseFont(font);
			ID3D11Texture2D* t = nullptr;
			ID3D11ShaderResourceView* pSRV = nullptr;
			pRenderer->MyCreateTextureFromSDLSurface(&t, s);
			pRenderer->MyCreateShaderResourceView(&pSRV, t);
			float dst_x, dst_y, dst_w, dst_h;
			MyRect dst;
			dst_w = (float)s->w;
			dst_h = (float)s->h;
			SDL_FreeSurface(s);
			if (bufferOutSwitch)
			{
				dst_x = text_cursorX2 + 8 * view.scale;
				dst_y = text_cursorY2 + 2 * view.scale + text_lineheight - dst_h;
				text_cursorX2 += dst_w;
				pRenderer->SetPenRTV(pRTV_textBuffer2);
			}
			else
			{
				dst_x = text_cursorX1 + 8 * view.scale;
				dst_y = text_cursorY1 + 2 * view.scale + text_lineheight - dst_h;
				text_cursorX1 += dst_w;
				pRenderer->SetPenRTV(pRTV_textBuffer1);
			}
			pRenderer->SetTPenDraw(pSRV);
			dst.Set1(dst_x, dst_y, dst_w, dst_h);
			pRenderer->AddRenderCopy(nullptr, &dst);
			pRenderer->DrawRenderCopy();
			pRenderer->SetPenRTV();
			if (t)
				t->Release();
			if (pSRV)
				pSRV->Release();
			TextSound();
		}
		msg_index++;
	} while (text_tur || text_tur_temp);
}

void GameMsgbox::ClearText()
{
	msg_index = 0;
	msg.clear();
	msg_format.clear();
	text_nod_linecounter = 0;
	bufferOutSwitch = false;
	bufferSwitch = false;
	text_rolling = false;
	text_rolling_counter = 0;
	text_cursorX1 = text_cursorX2 = text_cursorY1 = text_cursorY2 = 0;
	if (pRTV_textBuffer1)
		pRenderer->RenderClearRTV(pRTV_textBuffer1);
	if (pRTV_textBuffer2)
		pRenderer->RenderClearRTV(pRTV_textBuffer2);
}

int g_text_sound_channel = 0;
bool g_text_sound_channel_finshed = true;

void GameMsgbox::TextSound()
{
	Mix_ChannelFinished([](int channel)->void {if (channel == g_text_sound_channel)g_text_sound_channel_finshed = true; });
	if (!scaleChanging && g_text_sound_channel_finshed && !(text_tur || text_tur_temp))
	{
		auto iter = soundTable.find(text_soundName.c_str());
		if (iter != soundTable.end())
		{
			g_text_sound_channel = Mix_PlayChannel(-1, GetSoundByName(iter->second.c_str()), 0);
			g_text_sound_channel_finshed = false;
		}
	}
}

int GameMsgbox::CalcSpaceNum(const wchar_t* text, int mode)
{
	switch (mode)
	{
	default:
	case 0:
		return 0;
	case 1://计算右侧
		{
			//计算显示这段文本需要的像素宽度
			MyView& view = *pView;
			UTF16ToUTF8(text_fontFamily.c_str(), &utf8);
			auto font = pRenderer->MyLoadFont(utf8.data(), (int)(text_fontSize * view.scale));
			auto s_text = TTF_RenderUNICODE_Blended(font, (const Uint16*)text, text_color);
			auto s_space = TTF_RenderGlyph_Blended(font, ' ', text_color);
			TTF_CloseFont(font);
			int spaceNum = (int)(textBuffer1.w - 24 * view.scale - s_text->w) / s_space->w;
			SDL_FreeSurface(s_text);
			SDL_FreeSurface(s_space);
			return spaceNum;
		}
	case 2://计算居中
		{
			//计算显示这段文本需要的像素宽度
			MyView& view = *pView;
			UTF16ToUTF8(text_fontFamily.c_str(), &utf8);
			auto font = pRenderer->MyLoadFont(utf8.data(), (int)(text_fontSize * view.scale));
			auto s_text = TTF_RenderUNICODE_Blended(font, (const Uint16*)text, text_color);
			auto s_space = TTF_RenderGlyph_Blended(font, ' ', text_color);
			TTF_CloseFont(font);
			int spaceNum = (int)(textBuffer1.w - 24 * view.scale - s_text->w) / 2 / s_space->w;
			SDL_FreeSurface(s_text);
			SDL_FreeSurface(s_space);
			return spaceNum;
		}
	}
}
