#include "CAniEditorDraw.h"
#include "resource.h"
#include "CAniEditor.h"
IMPLEMENT_DYNAMIC(CAniEditorDraw, CDialog)

BEGIN_MESSAGE_MAP(CAniEditorDraw, CDialog)
	ON_WM_SIZE()
	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()

CAniEditorDraw::CAniEditorDraw(CWnd* pParent)
	: CDialog(IDD_CANIEDITOR_DRAW, pParent)
{
}

CAniEditorDraw::~CAniEditorDraw()
{
	//载入贴图
	if (tas.pSRV)
		tas.pSRV->Release();
	if (tas.pTexture)
		tas.pTexture->Release();
}

void CAniEditorDraw::Draw()
{
	pRenderer.RenderClear();
	if (showBk)
	{
		if (isDark)
			view.DrawTransparentBk(RGBA(0x20, 0x20, 0x20, 0xff), RGBA(0x30, 0x30, 0x30, 0xff));
		else
			view.DrawTransparentBk();
	}
	if (showLine)
		view.DrawBorderLine(true);
	if (showEntity)
		DrawEntityRect();
	DrawFrame();
	pRenderer.RenderPresent();
}

void CAniEditorDraw::Load(CString filename)
{
	//载入贴图
	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);
}

void CAniEditorDraw::ResetContext()
{
	ViewToCenter();
}

void CAniEditorDraw::ViewToCenter()
{
	int count_h = view.count_max / view.count_w;
	view.offX = (view.count_w * view.grid_w - view.window_w / view.scale) / 2;
	view.offY = (count_h * view.grid_h - view.window_h / view.scale) / 2;
}

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

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

BOOL CAniEditorDraw::OnInitDialog()
{
	CDialog::OnInitDialog();
	//初始化渲染器
	pRenderer.Init(m_hWnd);
	view.Init(this, &pRenderer);
	view.count_max = 256;
	view.count_w = 16;
	return 0;
}

void CAniEditorDraw::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;
	if (onceSetViewCenter)
	{
		ViewToCenter();
		onceSetViewCenter = false;
	}
	pRenderer.OnSize(cx, cy, nType == SIZE_MINIMIZED);
}


void CAniEditorDraw::OnPaint()
{
	CPaintDC dc(this);
	// 不为绘图消息调用 CDialog::OnPaint()
	Draw();
}

void CAniEditorDraw::OnLButtonDown(UINT nFlags, CPoint point)
{
	
	CDialog::OnLButtonDown(nFlags, point);
	CAniEditor* parentEditor = (CAniEditor*)pParentEditor;
	if (!parentEditor || !parentEditor->IsLoaded() ||
		!tas.pTexture || !tas.pSRV)
		return;
	//防止编辑已经隐藏的图层
	auto& hideIDTable = *parentEditor->GetHideTable();
	auto index = parentEditor->GetSelectedLayerIndex();
	if (hideIDTable.find(index) != hideIDTable.end())
		return;
	drag = true;
	moveStartPosL = point;
	auto& undoRedo = *parentEditor->GetMyUndoRedo();
	undoRedo.BeginStep(CANIEDITOR_DATATYPE_ANI_STR);
	std::vector<MyAniFrame*> frames;
	parentEditor->GetSelectAniFrame(&frames);
	dragFrameList.clear();
	for (auto& p : frames)
		dragFrameList.push_back(*p);
}

void CAniEditorDraw::OnLButtonUp(UINT nFlags, CPoint point)
{
	CDialog::OnLButtonUp(nFlags, point);
	CAniEditor* parentEditor = (CAniEditor*)pParentEditor;
	if (!parentEditor || !parentEditor->IsLoaded() ||
		!tas.pTexture || !tas.pSRV)
		return;
	drag = false;
	auto& undoRedo = *parentEditor->GetMyUndoRedo();
	undoRedo.EndStep();
	parentEditor->UpdateMenuState();
	parentEditor->UpdateWindowTitle();
}

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


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


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


void CAniEditorDraw::OnMouseMove(UINT nFlags, CPoint point)
{
	
	bool draw = false;
	if (drag)
	{
		CAniEditor* parentEditor = (CAniEditor*)pParentEditor;
		if (!parentEditor || !parentEditor->IsLoaded() ||
			!tas.pTexture || !tas.pSRV)
			return;
		std::vector<MyAniFrame*> pFrameList;
		parentEditor->GetSelectAniFrame(&pFrameList);
		
		CPoint mov = moveStartPosL - point;
		auto iter2 = dragFrameList.begin();
		float xScale = 16.0f / *parentEditor->pPid_tile_w;
		float yScale = 16.0f / *parentEditor->pPid_tile_h;
		
		for (auto iter = pFrameList.begin(); iter != pFrameList.end(); iter++, iter2++)
		{
			MyAniFrame& frameSrc = **iter;
			MyAniFrame& frameDst = *iter2;
			frameSrc.offx = frameDst.offx - floorf((float)mov.x / view.scale / xScale)* xScale;
			frameSrc.offy = frameDst.offy - floorf((float)mov.y / view.scale / yScale)* yScale;
		}
		draw = true;
	}
	if (view.WindowBind_OnMouseMove(point))
		draw = true;
	if(draw)
		Draw();
	CDialog::OnMouseMove(nFlags, point);
}


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


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

void CAniEditorDraw::DrawEntityRect()
{
	CAniEditor* parentEditor = (CAniEditor*)pParentEditor;
	float incX = (float)(view.count_w / 2) * view.grid_w;
	float incY = (float)(view.count_max / view.count_w / 2) * view.grid_h;
	MyRect rc;
	rc.Set1((incX - 8) * view.scale - floorf(view.offX * view.scale),
		(incY - 8) * view.scale - floorf(view.offY * view.scale),
		16 * view.scale,
		16 * view.scale);
	pRenderer.SetPenDraw();
	pRenderer.AddRect(&rc, RGBA(0, 0xff, 0, 0xff));
	//绘制贴图边界
	MyAniSet* as = nullptr;
	parentEditor->GetSelectAniInfo(&as);
	if (as)
	{
		rc.Set1((incX - as->texture_left) * view.scale - floorf(view.offX * view.scale),
			(incY - as->texture_up) * view.scale - floorf(view.offY * view.scale),
			(as->texture_left + as->texture_right) * view.scale,
			(as->texture_up + as->texture_down) * view.scale);
		pRenderer.AddRect(&rc, RGBA(0xff, 0, 0, 0xff));
	}
	pRenderer.DrawLine();
}

void CAniEditorDraw::DrawFrame()
{
	CAniEditor* parentEditor = (CAniEditor*)pParentEditor;
	if (!parentEditor || !parentEditor->IsLoaded() || 
		!tas.pTexture || !tas.pSRV)
		return;

	std::list<MyAniFrame> frameList;
	parentEditor->GetAniFrame(&frameList);
	pRenderer.SetTPenDraw(tas.pSRV);
	MyRect src, dst;
	float incX = (float)(view.count_w / 2) * view.grid_w;
	float incY = (float)(view.count_max / view.count_w / 2) * view.grid_h;
	for (auto& p : frameList)
	{
		parentEditor->AniIDSetRect(p.id, &src);
		float xScale = 16.0f / *parentEditor->pPid_tile_w;
		float yScale = 16.0f / *parentEditor->pPid_tile_h;
		dst.Set1((incX - 8 + p.offx) * view.scale - floorf(view.offX * view.scale),
			(incY - 8 + p.offy) * view.scale - floorf(view.offY * view.scale),
			src.GetWidth() * view.scale * xScale,
			src.GetHeight() * view.scale * yScale);
		pRenderer.AddRenderCopy(&src, &dst);
	}
	pRenderer.DrawRenderCopy();
}
