#include "CPidEditorDraw.h"
#include "resource.h"
#include "CPidEditor.h"

IMPLEMENT_DYNAMIC(CPidEditorDraw, CDialog)

BEGIN_MESSAGE_MAP(CPidEditorDraw, CDialog)
	ON_WM_SIZE()
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_WM_MOUSEWHEEL()
	ON_WM_MOUSEMOVE()
	ON_WM_VSCROLL()
	ON_WM_HSCROLL()
END_MESSAGE_MAP()

CPidEditorDraw::CPidEditorDraw(CWnd* pParent)
	: CDialog(IDD_CPIDEDITOR_DRAW, pParent)
{
}

CPidEditorDraw::~CPidEditorDraw()
{
	if (pFont_sourcesun14)
		TTF_CloseFont(pFont_sourcesun14);
	for (auto& p : pFontMap70)
	{
		if (p.second.pTexture)
			p.second.pTexture->Release();
		if (p.second.pSRV)
			p.second.pSRV->Release();
	}
	if (tas.pSRV)
		tas.pSRV->Release();
	if (tas.pTexture)
		tas.pTexture->Release();
}

MyView* CPidEditorDraw::GetMyView()
{
	return &view;
}

void CPidEditorDraw::Draw()
{
	auto parentEditor = (CPidEditor*)pParentEditor;

	pRenderer.RenderClear();
	if (parentEditor->showBk)
		view.DrawTransparentBk();
	if (tas.pSRV)
		DrawPid();
	if (parentEditor->showGrid)
		view.DrawGrid();
	if (parentEditor->showID)
		DrawID();
	view.DrawBorderLine();
	view.DrawCursor();
	pRenderer.RenderPresent();
}

void CPidEditorDraw::Load(CString filename)
{
	//载入贴图
	if (tas.pSRV)
		tas.pSRV->Release();
	if (tas.pTexture)
		tas.pTexture->Release();
	std::vector<char> utf8_buff;
	UTF16ToUTF8(filename.GetString(), &utf8_buff);
	pRenderer.MyLoadTexture(&tas.pTexture, utf8_buff.data());
	pRenderer.MyCreateShaderResourceView(&tas.pSRV, tas.pTexture);
	Draw();
}

void CPidEditorDraw::ResetContext()
{
	view.Reset();
	if (tas.pSRV)
	{
		tas.pSRV->Release();
		tas.pSRV = nullptr;
	}
	if (tas.pTexture)
	{
		tas.pTexture->Release();
		tas.pTexture = nullptr;
	}
	Draw();
	view.Reset();
}

MyRect CPidEditorDraw::GetCopyRect()
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	auto& step = *parentEditor->GetStep();
	int i = view.cursorY * view.count_w + view.cursorX;
	if (i >= view.count_max)
		i = 0;
	return step[i];
}

void CPidEditorDraw::SetCopyRect(MyRect& rc)
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	auto& step = *parentEditor->GetStep();
	auto& undoRedo = *parentEditor->GetMyUndoRedo();
	undoRedo.BeginStep(CPIDEDITOR_DATATYPE_PID_STR);
	int i = view.cursorY * view.count_w + view.cursorX;
	if (i > 0 && i < view.count_max)
		step[i] = rc;
	undoRedo.EndStep();
}

BOOL CPidEditorDraw::PreTranslateMessage(MSG* pMsg)
{
	// 检查是否为鼠标双击消息
	if (pMsg->message == WM_LBUTTONDBLCLK)
	{
		// 将双击消息转换为单击消息
		pMsg->message = WM_LBUTTONDOWN;
	}
	// 继续默认的消息处理
	return CDialog::PreTranslateMessage(pMsg);
}

void CPidEditorDraw::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BOOL CPidEditorDraw::OnInitDialog()
{
	CDialog::OnInitDialog();
	//初始化渲染器
	pRenderer.Init(m_hWnd);
	view.Init(this, &pRenderer);
	pFont_sourcesun14 = pRenderer.MyLoadFont("SourceHanSansSC-Normal", 14);
	return 0;
}


void CPidEditorDraw::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);

	
	if (!view.pRenderer)
		return;
	view.window_w = (float)cx;
	view.window_h = (float)cy;
	pRenderer.OnSize(cx, cy, nType == SIZE_MINIMIZED);
}


void CPidEditorDraw::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	
	// 不为绘图消息调用 CDialog::OnPaint()
	Draw();
}

void CPidEditorDraw::OnLButtonDown(UINT nFlags, CPoint point)
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	int count_h = view.count_max % view.count_w ? view.count_max / view.count_w + 1 : view.count_max / view.count_w;
	if (view.cursorX >= 0 && view.cursorY >= 0 && view.cursorX < view.count_w && view.cursorY < count_h)
	{
		if (view.cursorY * view.count_w + view.cursorX >= view.count_max)
			return;
		view.cursorX_selected = view.cursorX;
		view.cursorY_selected = view.cursorY;
		if (!parentEditor->IsBrushWndShow() && parentEditor->IsAniWndShow())
		{
			auto& step = *parentEditor->GetStep();
			parentEditor->SetAni(view.cursorY_selected * view.count_w + view.cursorX_selected);
			parentEditor->UpdateWindowTitle();
		}
		parentEditor->Draw();
	}
	CDialog::OnLButtonDown(nFlags, point);
}

void CPidEditorDraw::OnRButtonDown(UINT nFlags, CPoint point)
{
	
	view.WindowBind_OnRButtonDown(point);
	rclick_last_pt = point;//保存右键点击坐标
	CDialog::OnRButtonDown(nFlags, point);
}


void CPidEditorDraw::OnRButtonUp(UINT nFlags, CPoint point)
{
	view.WindowBind_OnRButtonUp();
	if (abs(point.x - rclick_last_pt.x) <= 5 && abs(point.y - rclick_last_pt.y) <= 5)
	{
		// 加载弹出菜单
		CMenu m, * pm;
		CPoint pt = point;
		m.LoadMenu(IDR_CPIDEDITOR_DRAW_RMENU);
		pm = m.GetSubMenu(0);
		ClientToScreen(&pt);
		pm->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
			pt.x, pt.y, this);
	}
	CDialog::OnRButtonUp(nFlags, point);
}


BOOL CPidEditorDraw::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	
	if (view.WindowBind_OnMouseWheel(zDelta, pt))
		Draw();
	return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}


void CPidEditorDraw::OnMouseMove(UINT nFlags, CPoint point)
{
	
	if (view.WindowBind_OnMouseMove(point))
		Draw();
	CDialog::OnMouseMove(nFlags, point);
}


void CPidEditorDraw::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	
	if (view.WindowBind_OnVScroll(nSBCode, nPos))
		Draw();
	CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}


void CPidEditorDraw::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	
	if (view.WindowBind_OnHScroll(nSBCode, nPos))
		Draw();
	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CPidEditorDraw::DrawID()
{
	MyViewDrawFor vFor;
	MyRect rc;
	vFor.Init(&view);
	int* pX = nullptr;
	int* pY = nullptr;
	for (vFor.DrawForYBegin(&pY); vFor.DrawForY(); vFor.DrawForYInc())
	{
		for (vFor.DrawForXBegin(&pX); vFor.DrawForX(&rc); vFor.DrawForXInc())
		{
			int& x = *pX;
			int& y = *pY;
			if (y * view.count_w + x >= view.count_max)
				return;
			DrawNumber(rc.left, rc.top, y * view.count_w + x);
		}
	}
}

void CPidEditorDraw::DrawPid()
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	auto& step = *parentEditor->GetStep();

	MyViewDrawFor vFor;
	MyRect rc, adjust;
	vFor.Init(&view);
	int* pX = nullptr;
	int* pY = nullptr;
	pRenderer.SetPenDraw();
	for (vFor.DrawForYBegin(&pY); vFor.DrawForY(); vFor.DrawForYInc())
	{
		for (vFor.DrawForXBegin(&pX); vFor.DrawForX(&rc); vFor.DrawForXInc())
		{
			int& x = *pX;
			int& y = *pY;
			if (y * view.count_w + x >= view.count_max)
				goto CPidEditorDraw_DrawPid_1;
			int i = y * view.count_w + x;
			if (step[i].GetWidth() == 0 || step[i].GetHeight() == 0 || i == 0)
			{
				if (i == 0)
					pRenderer.AddFillRect(&rc, RGBA(0, 0, 0, 0xff));
				else
					pRenderer.AddFillRect(&rc, RGBA(0xff, 0x9f, 0xf5, 0x80));
			}
		}
	}
CPidEditorDraw_DrawPid_1:
	pRenderer.DrawFillRect();
	vFor.Init(&view);
	pRenderer.SetTPenDraw(tas.pSRV);
	for (vFor.DrawForYBegin(&pY); vFor.DrawForY(); vFor.DrawForYInc())
	{
		for (vFor.DrawForXBegin(&pX); vFor.DrawForX(&rc); vFor.DrawForXInc())
		{
			int& x = *pX;
			int& y = *pY;
			if (y * view.count_w + x >= view.count_max)
				goto CPidEditorDraw_DrawPid_2;
			int i = y * view.count_w + x;
			if (!(step[i].GetWidth() == 0 || step[i].GetHeight() == 0 || i == 0))
			{
				adjust = step[i];
				adjust.AdjustIn(rc);
				pRenderer.AddRenderCopy(&step[i], &adjust);
			}
		}
	}
CPidEditorDraw_DrawPid_2:
	pRenderer.DrawRenderCopy();
}

void CPidEditorDraw::DrawNumber(float x, float y, int num)
{
	CString str;
	str.Format(L"%d", num);
	float nextX = x;
	float nextY = y;
	pRenderer.DrawText_Unicode(&pFontMap70, pFont_sourcesun14, str.GetString(), x, &nextX, &nextY);
}
