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

BEGIN_MESSAGE_MAP(CAniEditorTimeLine, 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()

CAniEditorTimeLine::CAniEditorTimeLine(CWnd* pParent)
	: CDialog(IDD_CANIEDITOR_TIMELINE, pParent)
{
}

CAniEditorTimeLine::~CAniEditorTimeLine()
{
	if (pFont_sourcesun70)
		TTF_CloseFont(pFont_sourcesun70);
	for (auto& p : pFontMap70)
	{
		if (p.second.pTexture)
			p.second.pTexture->Release();
		if (p.second.pSRV)
			p.second.pSRV->Release();
	}
	if (pFont_sourcesun14)
		TTF_CloseFont(pFont_sourcesun14);
	for (auto& p : pFontMap14)
	{
		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();
}

void CAniEditorTimeLine::Draw()
{
	if (isDark)
		pRenderer.RenderClear();
	else
		pRenderer.RenderClear(1.0f,1.0f,1.0f);
	if (view.count_w)
	{
		float prepOffX = view.offX;
		float prepOffY = view.offY;
		view.offX -= view.grid_w;
		view.offY -= view.grid_h;
		if (showBk)
		{
			if (isDark)
				view.DrawTransparentBk(RGBA(0x20, 0x20, 0x20, 0xff), RGBA(0x30, 0x30, 0x30, 0xff));
			else
				view.DrawTransparentBk();
		}
		if (isDark)
			view.DrawGrid(RGBA(0x50, 0x50, 0x50, 0xff));
		else
			view.DrawGrid(RGBA(0x50, 0x50, 0x50, 0xff));
		DrawAni();
		view.DrawCursor();
		DrawTimeIndex();
		DrawTimeRuler();
		view.offX = prepOffX;
		view.offY = prepOffY;
	}
	pRenderer.RenderPresent();
}

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

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

void CAniEditorTimeLine::SetLayerNumAndAniLen(int aniLen, int layerNum)
{
	view.count_w = aniLen;
	view.count_max = aniLen * layerNum;
	Draw();
}

MyAniFrame CAniEditorTimeLine::GetCurFrame()
{
	CAniEditor* parentEditor = (CAniEditor*)pParentEditor;
	auto step = parentEditor->GetStep();
	if (!step)
		return MyAniFrame();
	if (view.cursorY < step->size() &&
		view.cursorX < step->front().rcList.size())
		return  step->at(view.cursorY).rcList.at(view.cursorX);
	return MyAniFrame();
}

int CAniEditorTimeLine::GetTimeIndex()
{
	return timeIndex;
}

void CAniEditorTimeLine::SetTimeIndex(int index)
{
	timeIndex = index;
	view.cursorX_selected = timeIndex;
}

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

BOOL CAniEditorTimeLine::OnInitDialog()
{
	CDialog::OnInitDialog();
	//初始化渲染器
	pRenderer.Init(m_hWnd);
	view.Init(this, &pRenderer);
	pFont_sourcesun70 = pRenderer.MyLoadFont("SourceHanSansSC-Normal", 14 * 5);
	pFont_sourcesun14 = pRenderer.MyLoadFont("SourceHanSansSC-Normal", 14);
	view.count_max = 16;
	view.count_w = 8;
	view.scale = 2;
	return 0;
}

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

	
	if (!view.pRenderer)
		return;
	float prep_window_w = (float)cx;
	float prep_window_h = (float)cy;
	view.window_w = (float)cx - view.grid_w * view.scale;
	view.window_h = (float)cy - view.grid_h * view.scale;
	view.SetScrollBar();
	view.window_w = prep_window_w;
	view.window_h = prep_window_h;
	pRenderer.OnSize(cx, cy, nType == SIZE_MINIMIZED);
}


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

void CAniEditorTimeLine::OnLButtonDown(UINT nFlags, CPoint point)
{
	if (view.count_w == 0)
		return;
	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;
		timeIndex = view.cursorX;
		CPoint pt = point;
		pt.x -= (LONG)(view.grid_w * view.scale);
		pt.y -= (LONG)(view.grid_h * view.scale);
		view.BeginSelect(pt);
		CAniEditor* parentEditor = (CAniEditor*)pParentEditor;
		parentEditor->Draw();
	}
	CDialog::OnLButtonDown(nFlags, point);
}

void CAniEditorTimeLine::OnLButtonUp(UINT nFlags, CPoint point)
{
	view.EndSelect();
	CDialog::OnLButtonUp(nFlags, point);
}

void CAniEditorTimeLine::OnRButtonDown(UINT nFlags, CPoint point)
{
	CPoint pt = point;
	pt.x -= (LONG)(view.grid_w * view.scale);
	pt.y -= (LONG)(view.grid_h * view.scale);
	view.WindowBind_OnRButtonDown(pt);
	//图层编辑
	rclick_last_pt = point;//保存右键点击坐标
	CDialog::OnRButtonDown(nFlags, point);
}


void CAniEditorTimeLine::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_CANIEDITOR_TIMELINE_RMENU);
		pm = m.GetSubMenu(0);
		ClientToScreen(&pt);
		pm->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
			pt.x, pt.y, this);
	}
	CDialog::OnRButtonUp(nFlags, point);
}


BOOL CAniEditorTimeLine::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	
	CRect rc;
	float prep_window_w = view.window_w;
	float prep_window_h = view.window_h;
	GetWindowRect(&rc);
	float scale = view.scale;
	if (zDelta > 0)//放大
		scale *= 2;
	else//缩小
		scale /= 2;
	view.window_w = (float)rc.Width() - view.grid_w * scale;
	view.window_h = (float)rc.Height() - view.grid_h * scale;
	if (view.WindowBind_OnMouseWheel(zDelta, pt))
	{
		view.window_w = prep_window_w;
		view.window_h = prep_window_h;
		Draw();
	}
	view.window_w = prep_window_w;
	view.window_h = prep_window_h;
	return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}


void CAniEditorTimeLine::OnMouseMove(UINT nFlags, CPoint point)
{
	
	CPoint pt = point;
	pt.x -= (LONG)(view.grid_w * view.scale);
	pt.y -= (LONG)(view.grid_h * view.scale);
	view.Select(pt);
	if (view.WindowBind_OnMouseMove(pt))
		Draw();
	CDialog::OnMouseMove(nFlags, point);
}


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


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

void CAniEditorTimeLine::DrawTimeRuler()
{
	/*------------------------------填充------------------------------*/
	//列填充
	MyRect rc;
	MyViewDrawFor vFor;
	vFor.Init(&view);
	int* pX = nullptr;
	int* pY = nullptr;
	pRenderer.SetPenDraw();
	MyDX11PenVertex v1, v2;
	DWORD fill_c = RGBA(0xff, 0xff, 0xff, 0xff);
	DWORD grid_c = RGBA(0, 0, 0, 0xff);
	if (isDark)
	{
		fill_c = RGBA(0x8f, 0x8f, 0x8f, 0xff);
		grid_c = RGBA(0x6a, 0x6a, 0x6a, 0xff);
	}
	else
	{
		fill_c = RGBA(0xff, 0xff, 0xff, 0xff);
		grid_c = RGBA(0, 0, 0, 0xff);
	}
	//列填充
	for (vFor.DrawForYBegin(&pY); vFor.DrawForY(); vFor.DrawForYInc())
	{
		rc.Set1(0, vFor.rc_draw_y, vFor.rc_draw_w, vFor.rc_draw_h);
		pRenderer.AddFillRect(&rc, fill_c);
	}
	//行填充
	vFor.Init(&view);
	for (vFor.DrawForXBegin(&pX); vFor.DrawForX(); vFor.DrawForXInc())
	{
		rc.Set1(vFor.rc_draw_x, 0, vFor.rc_draw_w, vFor.rc_draw_h);
		if (vFor._x == timeIndex)
			pRenderer.AddFillRect(&rc, isDark ? timeIndexColor_DarkFill : timeIndexColor_LightFill);
		else
			pRenderer.AddFillRect(&rc, fill_c);
	}
	//左上角填充
	rc.Set1(0, 0, view.grid_w * view.scale, view.grid_h * view.scale);
	pRenderer.AddFillRect(&rc, fill_c);
	pRenderer.DrawFillRect();
	/*------------------------------线框------------------------------*/
	//列线框
	vFor.Init(&view);
	pRenderer.SetPenDraw();
	for (vFor.DrawForYBegin(&pY); vFor.DrawForY(); vFor.DrawForYInc())
	{
		rc.Set1(0, vFor.rc_draw_y, vFor.rc_draw_w, vFor.rc_draw_h);
		pRenderer.AddRect(&rc, grid_c);
	}
	//行线框
	vFor.Init(&view);
	for (vFor.DrawForXBegin(&pX); vFor.DrawForX(); vFor.DrawForXInc())
	{
		rc.Set1(vFor.rc_draw_x, 0, vFor.rc_draw_w, vFor.rc_draw_h);
		if (vFor._x == timeIndex)
		{
			pRenderer.AddRect(&rc, isDark ? timeIndexColor_DarkGrid : timeIndexColor_LightGrid);
			rc.left++;
			rc.right--;
			rc.top++;
			rc.bottom--;
			pRenderer.AddRect(&rc, isDark ? timeIndexColor_DarkGrid : timeIndexColor_LightGrid);
		}
		else
			pRenderer.AddRect(&rc, grid_c);
	}
	//左上角线框
	rc.Set1(0, 0, view.grid_w * view.scale, view.grid_h * view.scale);
	pRenderer.AddRect(&rc, grid_c);
	pRenderer.DrawLine();
	/*------------------------------数字------------------------------*/
	//列数字
	vFor.Init(&view);
	for (vFor.DrawForYBegin(&pY); vFor.DrawForY(); vFor.DrawForYInc())
	{
		rc.Set1(0, vFor.rc_draw_y, vFor.rc_draw_w, vFor.rc_draw_h);
		DrawNumber(0, vFor.rc_draw_y, vFor._y, &rc);
	}
		
	//行数字
	vFor.Init(&view);
	for (vFor.DrawForXBegin(&pX); vFor.DrawForX(); vFor.DrawForXInc())
	{
		rc.Set1(vFor.rc_draw_x, 0, vFor.rc_draw_w, vFor.rc_draw_h);
		DrawNumber(vFor.rc_draw_x, 0, vFor._x, &rc);
	}
	//左上角方框
	pRenderer.SetPenDraw();
	rc.Set1(0, 0, view.grid_w * view.scale, view.grid_h * view.scale);
	pRenderer.AddFillRect(&rc, fill_c);
	pRenderer.DrawFillRect();
	pRenderer.SetPenDraw();
	rc.Set1(0, 0, view.grid_w * view.scale, view.grid_h * view.scale);
	pRenderer.AddRect(&rc, grid_c);
	pRenderer.DrawLine();
}

void CAniEditorTimeLine::DrawNumber(float x, float y, int num, MyRect* rc)
{
	CString str;
	str.Format(L"%d", num);
	if (isDark)
		pRenderer.DrawText_Unicode_AdjustInRect(&pFontMap70, pFont_sourcesun70, str.GetString(), x, y,
			rc, RGBA(0xff, 0xff, 0xff, 0xff));
	else
		pRenderer.DrawText_Unicode_AdjustInRect(&pFontMap70, pFont_sourcesun70, str.GetString(), x, y,
			rc, RGBA(0, 0, 0, 0xff));
}

void CAniEditorTimeLine::DrawTimeIndex()
{
	MyRect rc;
	rc.Set1((timeIndex * view.grid_w) * view.scale - floorf(view.offX * view.scale),
		view.grid_h * view.scale,
		max(view.scale / 3.0f, 1.0f), view.window_h - view.grid_h * view.scale);
	pRenderer.SetPenDraw();
	pRenderer.AddFillRect(&rc, isDark ? timeIndexColor_DarkGrid : timeIndexColor_LightGrid);
	pRenderer.DrawFillRect();
}

void CAniEditorTimeLine::DrawAni()
{
	if (!tas.pTexture || !tas.pSRV)
		return;
	CAniEditor* parentEditor = (CAniEditor*)pParentEditor;
	CPidEditor* pidEditor = (CPidEditor*)parentEditor->pParentEditor;
	if (!parentEditor->IsLoaded())
		return;
	auto step = parentEditor->GetStep();
	if (!step)
		return;
	MyRect rc, adjustRc;
	MyViewDrawFor vFor;
	int layerNum = (int)step->size();
	if (layerNum == 0)
		return;
	int aniLen = (int)step->front().rcList.size();
	if (aniLen == 0)
		return;
	vFor.Init(&view);
	int* pX = nullptr;
	int* pY = nullptr;

	pRenderer.SetTPenDraw(tas.pSRV);
	for (vFor.DrawForYBegin(&pY); vFor.DrawForY(); vFor.DrawForYInc())
	{
		if (vFor._y >= layerNum)
			continue;
		for (vFor.DrawForXBegin(&pX); vFor.DrawForX(&rc); vFor.DrawForXInc())
		{
			if (vFor._x >= aniLen)
				continue;
			MyAniFrame& frame = step->at(vFor._y).rcList.at(vFor._x);
			MyRect src;
			parentEditor->AniIDSetRect(frame.id, &src);
			adjustRc = src;
			adjustRc.AdjustIn(rc);
			pRenderer.AddRenderCopy(&src, &adjustRc);
		}
	}
	pRenderer.DrawRenderCopy();
	//绘制数字
	if (pidEditor->showID)
	{
		CString str;
		for (vFor.DrawForYBegin(&pY); vFor.DrawForY(); vFor.DrawForYInc())
		{
			if (vFor._y >= layerNum)
				continue;
			for (vFor.DrawForXBegin(&pX); vFor.DrawForX(&rc); vFor.DrawForXInc())
			{
				if (vFor._x >= aniLen)
					continue;
				MyAniFrame& frame = step->at(vFor._y).rcList.at(vFor._x);
				str.Format(L"%d", frame.id);
				float nextX = rc.left;
				float nextY = rc.top;
				if (isDark)
					pRenderer.DrawText_Unicode(&pFontMap14, pFont_sourcesun14, str.GetString(),
						rc.left, &nextX, &nextY, RGBA(0xff, 0xff, 0xff, 0xff));
				else
					pRenderer.DrawText_Unicode(&pFontMap14, pFont_sourcesun14, str.GetString(),
						rc.left, &nextX, &nextY, RGBA(0, 0, 0, 0xff));
			}
		}
	}
}
