#include "CMapEditorBrush.h"
#include "resource.h"
#include "CMapEditor.h"

IMPLEMENT_DYNAMIC(CMapEditorBrush, CDialog)

BEGIN_MESSAGE_MAP(CMapEditorBrush, CDialog)
	ON_COMMAND(IDOK, &CMapEditorBrush::OnEnterKey)
	ON_WM_SIZE()
	ON_WM_SHOWWINDOW()
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_WM_MOUSEWHEEL()
	ON_WM_MOUSEMOVE()
	ON_WM_VSCROLL()
	ON_WM_HSCROLL()
END_MESSAGE_MAP()

CMapEditorBrush::CMapEditorBrush(CWnd* pParent)
	: CDialog(IDD_CMAPEDITOR_BRUSH, pParent)
{
}

CMapEditorBrush::~CMapEditorBrush()
{
	if (tas.pSRV && tas.pSRV != tas_nullpxa.pSRV)
		tas.pSRV->Release();
	if (tas.pTexture && tas.pTexture != tas_nullpxa.pTexture)
		tas.pTexture->Release();
	if (tas_pxatype.pSRV)
		tas_pxatype.pSRV->Release();
	if (tas_pxatype.pTexture)
		tas_pxatype.pTexture->Release();
	if (tas_nullpxa.pSRV)
		tas_nullpxa.pSRV->Release();
	if (tas_nullpxa.pTexture)
		tas_nullpxa.pTexture->Release();
}

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

void CMapEditorBrush::Draw()
{
	auto parentEditor = (CMapEditor*)pParentEditor;
	pRenderer.RenderClear();
	if (parentEditor->Bk())
		view.DrawTransparentBk();
	if (tas.pSRV)
	{
		MyRect src, dst;
		pRenderer.GetRenderCopyDefaultRect(tas.pSRV, &src, nullptr);
		dst.Set1(-floorf(view.offX * view.scale),
			-floorf(view.offY * view.scale),
			src.GetWidth() * view.scale,
			src.GetHeight() * view.scale);
		pRenderer.SetTPenDraw(tas.pSRV);
		pRenderer.AddRenderCopy(nullptr, &dst);
		pRenderer.DrawRenderCopy();
	}
	if (parentEditor->Pxa())
		DrawPxa();
	view.DrawCursor();//绘制光标
	view.DrawBorderLine();
	pRenderer.RenderPresent();
}

void CMapEditorBrush::Load(CString pxaName)
{
	if (loadedPxaName.GetLength() != 0 &&
		tas.pTexture &&
		tas.pSRV &&
		loadedPxaName == pxaName)
		return;//不重新载入贴图，直接跳过
	loadedPxaName = pxaName;
	CPxaEditor::StaticLoad(pxaName, &pxaList, &tileW, &tileH);
	CString pngName;
	pngName.Format(L"./data/pxa/%s.png", pxaName.GetString());
	titleBaseName = pngName;
	//设置窗口标题
	UpdateWindowTitle();
	//载入贴图
	if (tas.pSRV &&
		tas.pSRV != tas_nullpxa.pSRV)
	{
		tas.pSRV->Release();
		tas.pSRV = nullptr;
	}
	if (tas.pTexture &&
		tas.pTexture != tas_nullpxa.pTexture)
	{
		tas.pTexture->Release();
		tas.pTexture = nullptr;
	}
	std::vector<char> pngName_utf8;
	UTF16ToUTF8(pngName.GetString(), &pngName_utf8);
	//确认文件是否存在
	FILE* fp;
	fopen_s(&fp, pngName_utf8.data(), "rb");
	if (fp)
	{
		fclose(fp);
		//文件存在
		pRenderer.MyLoadTexture(&tas.pTexture, pngName_utf8.data());
		pRenderer.MyCreateShaderResourceView(&tas.pSRV, tas.pTexture);
	}
	else
	{
		//文件不存在
		tas = tas_nullpxa;
	}
	view.grid_w = (float)tileW;
	view.grid_h = (float)tileH;
	//更新设置
	UpdateGrid();
	view.SetScrollBar();
}

void CMapEditorBrush::ResetContext()
{
	view.Reset();
	view.cursorX_selected = view.cursorY_selected = view.cursorW_selected = view.cursorH_selected = 0;
	RefreshImage();
	Draw();
	view.Reset();
}

void CMapEditorBrush::RefreshImage()
{
	if (tas.pSRV &&
		tas.pSRV != tas_nullpxa.pSRV)
	{
		tas.pSRV->Release();
		tas.pSRV = nullptr;
	}
	if (tas.pTexture &&
		tas.pTexture != tas_nullpxa.pTexture)
	{
		tas.pTexture->Release();
		tas.pTexture = nullptr;
	}
}

void CMapEditorBrush::UpdateWindowTitle()
{
	CString windowTitle, appendStr;
	windowTitle = titleBaseName;
	appendStr.Format(L" - (%d,%d)", view.cursorX, view.cursorY);
	windowTitle.Append(appendStr);
	SetWindowText(windowTitle);
}

BOOL CMapEditorBrush::PreTranslateMessage(MSG* pMsg)
{
	auto parentEditor = (CMapEditor*)pParentEditor;
	if (TranslateAccelerator(parentEditor->GetSafeHwnd(), parentEditor->hAccel, pMsg))
		return TRUE;
	return CDialog::PreTranslateMessage(pMsg);
}

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

BOOL CMapEditorBrush::OnInitDialog()
{
	CDialog::OnInitDialog();
	pRenderer.Init(m_hWnd);
	view.Init(this, &pRenderer);
	//载入资源
	LoadResourceTexture(&pRenderer, IDB_PXATYPE, &tas_pxatype.pTexture, &tas_pxatype.pSRV);
	LoadResourceTexture(&pRenderer, IDB_NULLPXA, &tas_nullpxa.pTexture, &tas_nullpxa.pSRV);
	return 0;
}

void CMapEditorBrush::OnCancel()
{
	ShowWindow(SW_HIDE);
}

void CMapEditorBrush::OnEnterKey()
{
}

void CMapEditorBrush::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 CMapEditorBrush::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CDialog::OnShowWindow(bShow, nStatus);
}

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

void CMapEditorBrush::OnLButtonDown(UINT nFlags, CPoint point)
{
	view.BeginSelect(point);
	Draw();
	pPreviewWnd->Draw();//更新预览笔刷窗口
	UpdateWindowTitle();
	CDialog::OnLButtonDown(nFlags, point);
}

void CMapEditorBrush::OnLButtonUp(UINT nFlags, CPoint point)
{
	CDialog::OnLButtonUp(nFlags, point);
	view.EndSelect();
	auto parentEditor = (CMapEditor*)pParentEditor;
	if (parentEditor->IsEditMapMode())
	{
		switch (parentEditor->GetPaintMode())
		{
		case 0://涂画模式
			//设置涂画笔的尺寸
			pDrawView->cursorW = view.cursorW_selected;
			pDrawView->cursorH = view.cursorH_selected;
			break;
		case 3://矩形模式
			pDrawView->cursorW = 1;
			pDrawView->cursorH = 1;
			break;
		}
	}
}

void CMapEditorBrush::OnRButtonDown(UINT nFlags, CPoint point)
{
	view.WindowBind_OnRButtonDown(point);
	CDialog::OnRButtonDown(nFlags, point);
}

void CMapEditorBrush::OnRButtonUp(UINT nFlags, CPoint point)
{
	view.WindowBind_OnRButtonUp();
	CDialog::OnRButtonUp(nFlags, point);
}

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

void CMapEditorBrush::OnMouseMove(UINT nFlags, CPoint point)
{
	view.Select(point);
	if (view.WindowBind_OnMouseMove(point))
	{
		UpdateWindowTitle();
		Draw();
		pPreviewWnd->Draw();//更新预览笔刷窗口
		if (pWallAdjust_Edit_w && pWallAdjust_Edit_h)
		{
			CString str;
			str.Format(L"%d", view.cursorW_selected);
			pWallAdjust_Edit_w->SetWindowTextW(str.GetString());
			str.Format(L"%d", view.cursorH_selected);
			pWallAdjust_Edit_h->SetWindowTextW(str.GetString());
		}	
	}
	CDialog::OnMouseMove(nFlags, point);
}

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

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

void CMapEditorBrush::UpdateGrid()
{
	if (!tas.pSRV)
		return;
	MyRect rc;
	pRenderer.GetRenderCopyDefaultRect(tas.pSRV, &rc, nullptr);
	float w = rc.GetWidth(), h = rc.GetHeight();
	view.count_w = (int)((int)w % (int)view.grid_w ? w / view.grid_w + 1 : w / view.grid_w);
	int count_h = (int)((int)h % (int)view.grid_h ? h / view.grid_h + 1 : h / view.grid_h);
	view.count_max = view.count_w * count_h;
	Draw();
}

void CMapEditorBrush::DrawPxa()
{
	if (!tas_pxatype.pSRV)
		return;
	auto& step = pxaList;
	MyViewDrawFor vFor;
	MyRect src, dst;
	vFor.Init(&view);
	int* pX = nullptr;
	int* pY = nullptr;
	pRenderer.SetTPenDraw(tas_pxatype.pSRV);
	for (vFor.DrawForYBegin(&pY); vFor.DrawForY(); vFor.DrawForYInc())
	{
		for (vFor.DrawForXBegin(&pX); vFor.DrawForX(&dst); vFor.DrawForXInc())
		{
			int& x = *pX;
			int& y = *pY;
			if (step.find(MAKELONG(x, y)) == step.end())
				continue;
			int pxa = step.at(MAKELONG(x, y));
			src.Set1((float)((pxa % 16) * 16),
				((float)(pxa / 16) * 16),
				16,
				16);
			pRenderer.AddRenderCopy(&src, &dst, RGBA(0xff, 0xff, 0xff, 0x80));
		}
	}
	pRenderer.DrawRenderCopy();
}
