#include "CPidEditorBrush.h"
#include "resource.h"
#include "CPidEditor.h"
#include "CPidEditorBrushGrid.h"

IMPLEMENT_DYNAMIC(CPidEditorBrush, CDialog)

BEGIN_MESSAGE_MAP(CPidEditorBrush, CDialog)
	ON_COMMAND(IDOK, &CPidEditorBrush::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()
	ON_COMMAND(ID_SHOW_BK, &CPidEditorBrush::OnShowBk)
	ON_COMMAND(ID_SHOW_GRID, &CPidEditorBrush::OnShowGrid)
	ON_COMMAND(ID_BRUSH_SETTING, &CPidEditorBrush::OnBrushSetting)
END_MESSAGE_MAP()

CPidEditorBrush::CPidEditorBrush(CWnd* pParent)
	: CDialog(IDD_CPIDEDITOR_BRUSH, pParent)
{
}

CPidEditorBrush::~CPidEditorBrush()
{
	if (tas.pSRV)
		tas.pSRV->Release();
	if (tas.pTexture)
		tas.pTexture->Release();
}

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

void CPidEditorBrush::Draw()
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	pRenderer.RenderClear();
	if (showBk)
		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 (showGrid)
		view.DrawGrid();
	view.DrawBorderLine();//绘制边界线
	//绘制光标
	view.DrawCursor();
	DrawSelectedRect();
	pRenderer.RenderPresent();
}

void CPidEditorBrush::Load(CString filename)
{
	//设置窗口标题
	SetWindowTextW(filename.GetString());
	//载入贴图
	if (tas.pSRV)
		tas.pSRV->Release();
	if (tas.pTexture)
		tas.pTexture->Release();
	std::vector<char> gbk_buff;
	UTF16ToGBK(filename.GetString(), &gbk_buff);
	pRenderer.MyLoadTexture(&tas.pTexture, gbk_buff.data());
	pRenderer.MyCreateShaderResourceView(&tas.pSRV, tas.pTexture);
	//更新设置
	UpdateGrid();
	view.SetScrollBar();
}

void CPidEditorBrush::ResetContext()
{
	view.Reset();
	view.cursorX_selected = view.cursorY_selected = view.cursorW_selected = view.cursorH_selected = 0;
	if (tas.pSRV)
	{
		tas.pSRV->Release();
		tas.pSRV = nullptr;
	}
	if (tas.pTexture)
	{
		tas.pTexture->Release();
		tas.pTexture = nullptr;
	}
	Draw();
	view.Reset();
}

void CPidEditorBrush::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();
}

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

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

BOOL CPidEditorBrush::OnInitDialog()
{
	CDialog::OnInitDialog();
	pRenderer.Init(m_hWnd);
	view.Init(this, &pRenderer);
	view.drawSelectedCursor = false;
	//设置初始化
	showGrid = false;
	OnShowGrid();//启用网格
	showBk = false;
	OnShowBk();//启用透明背景
	return 0;
}

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

void CPidEditorBrush::OnEnterKey()
{
}

void CPidEditorBrush::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 CPidEditorBrush::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CDialog::OnShowWindow(bShow, nStatus);
	auto parentEditor = (CPidEditor*)pParentEditor;
	if (bShow)
		parentEditor->GetMenu()->GetSubMenu(CPIDEDITOR_MENUINDEX_WINDOW)->CheckMenuItem(ID_BRUSH_WND, MF_BYCOMMAND | MF_CHECKED);
	else
		parentEditor->GetMenu()->GetSubMenu(CPIDEDITOR_MENUINDEX_WINDOW)->CheckMenuItem(ID_BRUSH_WND, MF_BYCOMMAND | MF_UNCHECKED);
}

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

void CPidEditorBrush::OnLButtonDown(UINT nFlags, CPoint point)
{
	view.drawSelectedCursor = true;
	view.BeginSelect(point);
	Draw();
	CDialog::OnLButtonDown(nFlags, point);
}

void CPidEditorBrush::OnLButtonUp(UINT nFlags, CPoint point)
{
	CDialog::OnLButtonUp(nFlags, point);
	auto parentEditor = (CPidEditor*)pParentEditor;
	view.EndSelect();
	view.drawSelectedCursor = false;
	if (!parentEditor->IsLoaded())
		return;

	int index = pDrawWndView->cursorY_selected * pDrawWndView->count_w + pDrawWndView->cursorX_selected;
	if (index == 0)//0号不允许修改
		return;
	auto& undoRedo = *parentEditor->GetMyUndoRedo();
	undoRedo.BeginStep(CPIDEDITOR_DATATYPE_PID_STR);
	auto& step = *((CPIDEDITOR_DATATYPE_PID*)undoRedo.GetStep(CPIDEDITOR_DATATYPE_PID_STR));
	step[index].Set1(view.cursorX_selected * view.grid_w,
		view.cursorY_selected * view.grid_h,
		view.cursorW_selected * view.grid_w,
		view.cursorH_selected * view.grid_h);
	undoRedo.EndStep();
	parentEditor->Draw();
	parentEditor->UpdateWindowTitle();
	parentEditor->UpdateMenuState();
}

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


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


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

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

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

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

void CPidEditorBrush::OnShowBk()
{
	if (showBk)
	{
		showBk = false;
		GetMenu()->GetSubMenu(CPIDEDITOR_BRUSH_MENUINDEX_OPTION)->CheckMenuItem(ID_SHOW_BK, MF_BYCOMMAND | MF_UNCHECKED);
	}
	else
	{
		showBk = true;
		GetMenu()->GetSubMenu(CPIDEDITOR_BRUSH_MENUINDEX_OPTION)->CheckMenuItem(ID_SHOW_BK, MF_BYCOMMAND | MF_CHECKED);
	}
	Draw();
}

void CPidEditorBrush::OnShowGrid()
{
	if (showGrid)
	{
		showGrid = false;
		GetMenu()->GetSubMenu(CPIDEDITOR_BRUSH_MENUINDEX_OPTION)->CheckMenuItem(ID_SHOW_GRID, MF_BYCOMMAND | MF_UNCHECKED);
	}
	else
	{
		showGrid = true;
		GetMenu()->GetSubMenu(CPIDEDITOR_BRUSH_MENUINDEX_OPTION)->CheckMenuItem(ID_SHOW_GRID, MF_BYCOMMAND | MF_CHECKED);
	}
	Draw();
}

void CPidEditorBrush::OnBrushSetting()
{
	CPidEditorBrushGrid dlg;
	dlg.outBrushW = (int)view.grid_w;
	dlg.outBrushH = (int)view.grid_h;
	if (dlg.DoModal() != IDOK)
		return;
	view.grid_w = (float)dlg.outBrushW;
	view.grid_h = (float)dlg.outBrushH;
	UpdateGrid();
	Draw();
}

void CPidEditorBrush::DrawSelectedRect()
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	if (!parentEditor->IsLoaded())
		return;
	auto& undoRedo = *parentEditor->GetMyUndoRedo();
	auto& step = *((CPIDEDITOR_DATATYPE_PID*)undoRedo.GetStep(CPIDEDITOR_DATATYPE_PID_STR));
	int index = pDrawWndView->cursorY_selected * pDrawWndView->count_w + pDrawWndView->cursorX_selected;
	MyRect rc = step[index];
	float x, y, w, h;
	x = (rc.left) * view.scale - floorf(view.offX * view.scale);
	y = (rc.top) * view.scale - floorf(view.offY * view.scale);
	w = rc.GetWidth() * view.scale;
	h = rc.GetHeight() * view.scale;
	rc.Set1(x, y, w, h);
	pRenderer.SetPenDraw();
	pRenderer.AddRect(&rc, RGBA(0xff, 0xff, 0, 0xff));
	rc.left--;
	rc.right++;
	rc.top--;
	rc.bottom++;
	pRenderer.AddRect(&rc, RGBA(0xff, 0xff, 0, 0xff));
	pRenderer.DrawLine();
}

