#include "MyStructDef.h"
#include <sstream>
Rect<float>& GetRectEntity::operator()(Entity* e) const
{
	return (Rect<float>&)e->cbRect.qtRect;
}

void MyRGBA::Set(DWORD c)
{
	r = c & 0xff;
	g = (c >> 8) & 0xff;
	b = (c >> 16) & 0xff;
	a = (c >> 24) & 0xff;
}

DWORD MyRGBA::Get()
{
	return RGBA(r, g, b, a);
}

void MyViewDrawFor::Init(MyView* view)
{
	this->view = view;
}

void MyViewDrawFor::DrawForYBegin(int** outY)
{
	draw_xMax = (int)(view->window_w / (view->grid_w * view->scale) + view->offX / view->grid_w + 2);
	draw_yMax = (int)(view->window_h / (view->grid_h * view->scale) + view->offY / view->grid_h + 2);
	count_h = view->count_max % view->count_w ? view->count_max / view->count_w + 1 : view->count_max / view->count_w;

	rc_draw_w = view->grid_w * view->scale;
	rc_draw_h = view->grid_h * view->scale;

	_y = (int)max(view->offY / view->grid_h, 0);
	rc_draw_y = (_y * view->grid_h) * view->scale - floorf(view->offY * view->scale);
	if (outY)
		*outY = &_y;
}

bool MyViewDrawFor::DrawForY()
{
	return _y < min(draw_yMax, count_h);
}

void MyViewDrawFor::DrawForYInc()
{
	_y++;
	rc_draw_y += rc_draw_h;
}

void MyViewDrawFor::DrawForXBegin(int** outX)
{
	_x = (int)max(view->offX / view->grid_w, 0);
	rc_draw_x = _x * view->grid_w * view->scale - floorf(view->offX * view->scale);
	if (outX)
		*outX = &_x;
}

bool MyViewDrawFor::DrawForX(MyRect* outRect)
{
	if (outRect)
		outRect->Set1(rc_draw_x, rc_draw_y, rc_draw_w, rc_draw_h);
	return  _x < min(draw_xMax, view->count_w);
}

void MyViewDrawFor::DrawForXInc()
{
	_x++;
	rc_draw_x += rc_draw_w;
}

void MyView::Init(CDialog* dlg, MyDX11Renderer* pRenderer)
{
	this->dlg = dlg;
	this->pRenderer = pRenderer;
}

void MyView::Reset()
{
	CDialog* dlg = this->dlg;
	MyDX11Renderer* pRenderer = this->pRenderer;//渲染器
	float window_w = this->window_w;
	float window_h = this->window_h;
	*this = MyView();
	Init(dlg, pRenderer);
	this->window_w = window_w;
	this->window_h = window_h;
}

void MyView::BeginSelect(CPoint pt)
{
	selecting = true;
	moveStartPos = pt;
	Select(pt);
}

void MyView::Select(CPoint pt)
{
	if (!selecting)
		return;
	int count_h = count_max % count_w ? count_max /count_w + 1 : count_max / count_w;
	if (allowSelectOut)
	{
		if (cursorX >= 0 && cursorY >= 0)
		{
			int start_cursorX = (int)((moveStartPos.x / scale + offX) / grid_w);
			int start_cursorY = (int)((moveStartPos.y / scale + offY) / grid_h);
			int end_cursorX = (int)((pt.x / scale + offX) / grid_w);
			int end_cursorY = (int)((pt.y / scale + offY) / grid_h);
			if (start_cursorX < 0)
				start_cursorX = 0;
			if (start_cursorY < 0)
				start_cursorY = 0;
			if (end_cursorX < 0)
				end_cursorX = 0;
			if (end_cursorY < 0)
				end_cursorY = 0;
			//进行左上右下变换
			int cursor_x1 = min(start_cursorX, end_cursorX);
			int cursor_y1 = min(start_cursorY, end_cursorY);
			int cursor_x2 = max(start_cursorX, end_cursorX);
			int cursor_y2 = max(start_cursorY, end_cursorY);
			cursorX_selected = cursor_x1;
			cursorY_selected = cursor_y1;
			cursorW_selected = cursor_x2 - cursor_x1 + 1;
			cursorH_selected = cursor_y2 - cursor_y1 + 1;
		}
	}
	else
	{
		if (cursorX >= 0 && cursorY >= 0 && cursorX < count_w && cursorY < count_h)
		{
			int start_cursorX = (int)((moveStartPos.x / scale + offX) / grid_w);
			int start_cursorY = (int)((moveStartPos.y / scale + offY) / grid_h);
			int end_cursorX = (int)((pt.x / scale + offX) / grid_w);
			int end_cursorY = (int)((pt.y / scale + offY) / grid_h);
			if (start_cursorX < 0)
				start_cursorX = 0;
			if (start_cursorY < 0)
				start_cursorY = 0;
			if (end_cursorX < 0)
				end_cursorX = 0;
			if (end_cursorY < 0)
				end_cursorY = 0;
			//进行左上右下变换
			int cursor_x1 = min(start_cursorX, end_cursorX);
			int cursor_y1 = min(start_cursorY, end_cursorY);
			int cursor_x2 = max(start_cursorX, end_cursorX);
			int cursor_y2 = max(start_cursorY, end_cursorY);
			cursorX_selected = cursor_x1;
			cursorY_selected = cursor_y1;
			cursorW_selected = cursor_x2 - cursor_x1 + 1;
			cursorH_selected = cursor_y2 - cursor_y1 + 1;
		}
	}
}

void MyView::EndSelect()
{
	selecting = false;
}

void MyView::DrawTransparentBk(DWORD c1, DWORD c2)
{
	if (!pRenderer)
		return;
	MyViewDrawFor vFor;
	MyRect rc;
	vFor.Init(this);
	int* pX = nullptr;
	int* pY = nullptr;
	int draw_count = 0;
	const int limit = 40000;//限制可绘制数量，防止卡住
	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 * count_w + x >= count_max) ||
				(draw_count > limit))
				goto MyView_DrawTransparentBk;
			DWORD c;
			if (y % 2)
				if (x % 2)
					c = c1;
				else
					c = c2;
			else
				if (x % 2)
					c = c2;
				else
					c = c1;
			pRenderer->AddFillRect(&rc, c);
			draw_count++;
		}
	}
MyView_DrawTransparentBk:
	pRenderer->DrawFillRect();
}

void MyView::DrawBorderLine(bool center)
{
	if (!pRenderer)
		return;
	MyDX11PenVertex p1, p2;
	pRenderer->SetPenDraw();
	if (center)
	{
		float incX = (float)(count_w / 2) * grid_w;
		float incY = (float)(count_max / count_w / 2) * grid_h;
		p1.Set(0, (incY) * scale - floorf(offY * scale), 0, RGBA(0, 0, 0xff, 0xff));
		p2.Set(window_w, (incY) * scale - floorf(offY * scale), 0, RGBA(0, 0, 0xff, 0xff));
		pRenderer->AddLine(&p1, &p2);
		p1.Set((incX) * scale - floorf(offX * scale), 0, 0, RGBA(0, 0, 0xff, 0xff));
		p2.Set((incX) * scale - floorf(offX * scale), window_h, 0, RGBA(0, 0, 0xff, 0xff));
		pRenderer->AddLine(&p1, &p2);
	}
	else
	{
		p1.Set(0, -floorf(offY * scale), 0, RGBA(0, 0, 0xff, 0xff));
		p2.Set(window_w, -floorf(offY * scale), 0, RGBA(0, 0, 0xff, 0xff));
		pRenderer->AddLine(&p1, &p2);
		p1.Set(-floorf(offX * scale), 0, 0, RGBA(0, 0, 0xff, 0xff));
		p2.Set(-floorf(offX * scale), window_h, 0, RGBA(0, 0, 0xff, 0xff));
		pRenderer->AddLine(&p1, &p2);
	}
	pRenderer->DrawLine();
}

void MyView::DrawGrid(DWORD c)
{
	if (!pRenderer)
		return;
	MyViewDrawFor vFor;
	vFor.Init(this);
	int* pX = nullptr;
	int* pY = nullptr;
	pRenderer->SetPenDraw();
	MyDX11PenVertex v1, v2;
	for (vFor.DrawForYBegin(&pY); vFor.DrawForY(); vFor.DrawForYInc())
	{
		vFor.DrawForXBegin(&pX);
		if (vFor.DrawForX())
		{
			v1.Set(vFor.rc_draw_x, vFor.rc_draw_y, 0, c);
			v2.Set((min(vFor.draw_xMax, count_w) * grid_w) * scale - floorf(offX * scale), vFor.rc_draw_y, 0, c);
			pRenderer->AddLine(&v1, &v2);
		}
	}
	//绘制最后一行
	int tail_count_w = count_max % count_w;
	v1.Set(vFor.rc_draw_x, vFor.rc_draw_y, 0, c);
	v2.Set((min(vFor.draw_xMax, tail_count_w ? tail_count_w : count_w) * grid_w) * scale - floorf(offX * scale), vFor.rc_draw_y, 0, c);
	pRenderer->AddLine(&v1, &v2);

	bool drawLastLine = false;
	for (vFor.DrawForXBegin(&pX); vFor.DrawForX(); vFor.DrawForXInc())
	{
		vFor.DrawForYBegin(&pY);
		if (vFor.DrawForY())
		{
			v1.Set(vFor.rc_draw_x, vFor.rc_draw_y, 0, c);
			v2.Set(vFor.rc_draw_x, ((min(vFor.draw_yMax, vFor.count_h) - 1) * grid_h) * scale - floorf(offY * scale), 0, c);
			pRenderer->AddLine(&v1, &v2);
			drawLastLine = true;
			//绘制最后一行 的最后一列
			if (!tail_count_w || (tail_count_w && vFor._x < tail_count_w))
			{
				v1.Set(vFor.rc_draw_x, ((min(vFor.draw_yMax, vFor.count_h)) * grid_h) * scale - floorf(offY * scale), 0, c);
				v2.Set(vFor.rc_draw_x, ((min(vFor.draw_yMax, vFor.count_h) - 1) * grid_h) * scale - floorf(offY * scale), 0, c);
				pRenderer->AddLine(&v1, &v2);
				v1.Set(vFor.rc_draw_x + grid_w * scale, ((min(vFor.draw_yMax, vFor.count_h)) * grid_h) * scale - floorf(offY * scale), 0, c);
				v2.Set(vFor.rc_draw_x + grid_w * scale, ((min(vFor.draw_yMax, vFor.count_h) - 1) * grid_h) * scale - floorf(offY * scale), 0, c);
				pRenderer->AddLine(&v1, &v2);
			}
		}
	}
	if (drawLastLine)
	{
		v1.Set(vFor.rc_draw_x, vFor.rc_draw_y, 0, c);
		v2.Set(vFor.rc_draw_x, ((min(vFor.draw_yMax, vFor.count_h) - 1) * grid_h) * scale - floorf(offY * scale), 0, c);
		pRenderer->AddLine(&v1, &v2);
	}
	pRenderer->DrawLine();
}

void MyView::DrawCursor()
{
	MyRect rc;
	//绘制已选择的光标
	pRenderer->SetPenDraw();
	if (drawSelectedCursor)
	{
		rc.Set1((cursorX_selected * grid_w) * scale - floorf(offX * scale),
			(cursorY_selected * grid_h) * scale - floorf(offY * scale),
			cursorW_selected * grid_w * scale,
			cursorH_selected * grid_h * scale);
		pRenderer->AddRect(&rc, RGBA(0, 0xff, 0xff, 0xff));
		rc.left--;
		rc.right++;
		rc.top--;
		rc.bottom++;
		pRenderer->AddRect(&rc, RGBA(0, 0xff, 0xff, 0xff));
	}
	//绘制实时光标
	rc.Set1((cursorX * grid_w) * scale - floorf(offX * scale),
		(cursorY * grid_h) * scale - floorf(offY * scale),
		cursorW * grid_w * scale,
		cursorH * grid_h * scale);
	pRenderer->AddRect(&rc, RGBA(0xff, 0xff, 0xff, 0xff));
	pRenderer->DrawLine();
}

void MyView::WindowBind_OnRButtonDown(CPoint point)
{
	moveMode = true;
	offX_start = offX;
	offY_start = offY;
	moveStartPos = point;
}

void MyView::WindowBind_OnRButtonUp()
{
	moveMode = false;
}

void MyView::SetScrollBar()
{
	int count_h = 0;
	if (count_w)
		count_h = count_max % count_w ? count_max / count_w + 1 : count_max / count_w;
	SCROLLINFO info;
	info.cbSize = sizeof(SCROLLBARINFO);
	info.fMask = SIF_PAGE | SIF_RANGE;
	info.nMin = 0;
	info.nMax = (int)(scale * count_h * grid_h);
	info.nPage = (UINT)window_h;
	dlg->SetScrollInfo(SB_VERT, &info);
	info.nMax = (int)(scale * count_w * grid_w);
	info.nPage = (UINT)window_w;
	dlg->SetScrollInfo(SB_HORZ, &info);
}

bool MyView::WindowBind_OnMouseMove(CPoint point)
{
	bool needDraw = false;
	if (moveMode)
	{
		CPoint mov = moveStartPos - point;
		offX = offX_start + mov.x / scale;
		offY = offY_start + mov.y / scale;
		dlg->SetScrollPos(SB_VERT, (int)(offY * scale));
		dlg->SetScrollPos(SB_HORZ, (int)(offX * scale));
		needDraw = true;//需要重新绘制
	}
	cursorX = (int)((point.x / scale + offX) / grid_w);
	if (cursorX < 0)
		cursorX = 0;
	cursorY = (int)((point.y / scale + offY) / grid_h);
	if (cursorY < 0)
		cursorY = 0;
	if (cursorX_last != cursorX || cursorY_last != cursorY)
	{
		cursorX_last = cursorX;
		cursorY_last = cursorY;
		needDraw = true;
	}
	return needDraw;
}

bool MyView::WindowBind_OnMouseWheel(short zDelta, CPoint pt)
{
	bool needDraw = zDelta != 0;
	auto scale_old = scale;//取旧的缩放
	if (zDelta > 0)//放大
		scale *= 2;
	else//缩小
		scale /= 2;
	CRect rect;
	dlg->GetClientRect(&rect);//取客户端矩形区
	dlg->ScreenToClient(&pt);//转换成客户端的鼠标坐标
	//计算旧缩放鼠标所指像素所在的滚动条下标
	auto xPix = pt.x / scale_old + offX;
	auto yPix = pt.y / scale_old + offY;
	offX = xPix - pt.x / scale;
	offY = yPix - pt.y / scale;
	SetScrollBar();
	return needDraw;
}

bool MyView::WindowBind_OnVScroll(UINT nSBCode, UINT nPos)
{
	bool needDraw = false;
	int count_h = count_max % count_w ? count_max / count_w + 1 : count_max / count_w;
	switch (nSBCode)
	{
	case SB_LINEUP:
		if ((int)offY % (int)grid_h)
			offY = floorf(offY / grid_h) * grid_h;
		else
			offY -= grid_h;
		nPos = (int)max(offY * scale, 0);
		offY = nPos / scale;
		dlg->SetScrollPos(SB_VERT, nPos);
		needDraw = true;
		break;
	case SB_LINEDOWN:
		if ((int)offY % (int)grid_h)
			offY = ceilf(offY / grid_h) * grid_h;
		else
			offY += grid_h;
		nPos = (int)min(offY * scale, count_h * grid_h * scale - window_h);
		offY = nPos / scale;
		dlg->SetScrollPos(SB_VERT, nPos);
		needDraw = true;
		break;
	case SB_PAGEUP:
		offY -= window_h / scale;
		nPos = (int)max(offY * scale, 0);
		offY = nPos / scale;
		dlg->SetScrollPos(SB_VERT, nPos);
		needDraw = true;
		break;
	case SB_PAGEDOWN:
		offY += window_h / scale;
		nPos = (int)min(offY * scale, count_h * grid_h * scale - window_h);
		offY = nPos / scale;
		dlg->SetScrollPos(SB_VERT, nPos);
		needDraw = true;
		break;
	case SB_THUMBTRACK:
		offY = nPos / scale;
		dlg->SetScrollPos(SB_VERT, nPos);
		needDraw = true;
		break;
	}
	return needDraw;
}

bool MyView::WindowBind_OnHScroll(UINT nSBCode, UINT nPos)
{
	bool needDraw = false;
	switch (nSBCode)
	{
	case SB_LINEUP:
		if ((int)offX % (int)grid_w)
			offX = floorf(offX / grid_w) * grid_w;
		else
			offX -= grid_w;
		nPos = (int)max(offX * scale, 0);
		offX = nPos / scale;
		dlg->SetScrollPos(SB_HORZ, nPos);
		needDraw = true;
		break;
	case SB_LINEDOWN:
		if ((int)offX % (int)grid_w)
			offX = ceilf(offX / grid_w) * grid_w;
		else
			offX += grid_w;
		nPos = (int)min(offX * scale, count_w * grid_w * scale - window_w);
		offX = nPos / scale;
		dlg->SetScrollPos(SB_HORZ, nPos);
		needDraw = true;
		break;
	case SB_PAGEUP:
		offX -= window_w / scale;
		nPos = (int)max(offX * scale, 0);
		offX = nPos / scale;
		dlg->SetScrollPos(SB_HORZ, nPos);
		needDraw = true;
		break;
	case SB_PAGEDOWN:
		offX += window_w / scale;
		nPos = (int)min(offX * scale, count_w * grid_w * scale - window_w);
		offX = nPos / scale;
		dlg->SetScrollPos(SB_HORZ, nPos);
		needDraw = true;
		break;
	case SB_THUMBTRACK:
		offX = nPos / scale;
		dlg->SetScrollPos(SB_HORZ, nPos);
		needDraw = true;
		break;
	}
	return needDraw;
}

MyUndoRedo::MyUndoRedo(const MyUndoRedo& src)
{
	*this = src;
}

MyUndoRedo& MyUndoRedo::operator=(const MyUndoRedo& src)
{
	canStep = src.canStep;
	dataOpMap = src.dataOpMap;
	//复制step
	for (auto& p : step)//清空step
	{
		auto& op = dataOpMap.at(p.first);
		auto& stepData = p.second;
		op.ReleaseData(stepData);
		stepData = nullptr;
	}
	step.clear();
	for (auto& p : src.step)
	{
		auto& op = src.dataOpMap.at(p.first);
		auto& stepData = p.second;
		void* newData = op.NewCopyOfData(stepData);
		step.insert(std::make_pair(p.first, newData));
	}
	//复制redo
	for (auto& p : redo)//清空redo
	{
		auto& op = dataOpMap.at(p.first);
		auto& redoData = p.second;
		for (auto& t : redoData)
			op.ReleaseData(t);
		redoData.clear();
	}
	redo.clear();
	for (auto& p : src.redo)
	{
		auto& op = src.dataOpMap.at(p.first);
		auto& redoData = p.second;
		std::list<void*> newRedoList;
		for (auto& t : redoData)
		{
			void* newData = op.NewCopyOfData(t);
			newRedoList.push_back(newData);
		}
		redo.insert(std::make_pair(p.first, newRedoList));
	}
	//复制undo
	for (auto& p : undo)//清空undo
	{
		auto& op = dataOpMap.at(p.first);
		auto& undoData = p.second;
		for (auto& t : undoData)
			op.ReleaseData(t);
		undoData.clear();
	}
	undo.clear();
	for (auto& p : src.undo)
	{
		auto& op = src.dataOpMap.at(p.first);
		auto& undoData = p.second;
		std::list<void*> newUndoList;
		for (auto& t : undoData)
		{
			void* newData = op.NewCopyOfData(t);
			newUndoList.push_back(newData);
		}
		undo.insert(std::make_pair(p.first, newUndoList));
	}
	dataTypeList_redo = src.dataTypeList_redo;
	dataTypeList_undo = src.dataTypeList_undo;
	return *this;
}

MyUndoRedo::~MyUndoRedo()
{
	Clear();
	for (auto& p : step)
	{
		auto& op = dataOpMap.at(p.first);
		auto& stepData = p.second;
		op.ReleaseData(stepData);
	}
}

void MyUndoRedo::AddDataType(const char* dataTypeName, MyUndoRedoDataOp op)
{
	dataOpMap.insert(std::make_pair(dataTypeName, op));
	step.insert(std::make_pair(dataTypeName, op.NewData()));
	redo.insert(std::make_pair(dataTypeName, std::list<void*>()));
	undo.insert(std::make_pair(dataTypeName, std::list<void*>()));
}

void MyUndoRedo::BeginStep(const char* dataTypeName)
{
	if (canStep)
		return;
	//一但编辑 就会清空重做
	auto& dataOp = dataOpMap.at(dataTypeName);
	auto& redoData = redo.at(dataTypeName);
	for (auto& p : redoData)
		dataOp.ReleaseData(p);//清除数据
	redoData.clear();
	dataTypeList_redo.clear();
	//编辑前先入栈
	auto& undoData = undo.at(dataTypeName);
	auto& stepData = step.at(dataTypeName);
	undoData.push_back(dataOp.NewCopyOfData(stepData));
	if (dataTypeList_undo.size() >= maxSize)
	{
		auto& dstUndoData = undo.at(dataTypeList_undo.front());
		dstUndoData.pop_front();
		dataTypeList_undo.pop_front();
	}
	dataTypeList_undo.push_back(dataTypeName);
	canStep = true;
}

void MyUndoRedo::EndStep()
{
	canStep = false;
}

void MyUndoRedo::Undo()
{
	if (dataTypeList_undo.empty())
		return;
	std::string dataTypeName = dataTypeList_undo.back();
	dataTypeList_undo.pop_back();
	dataTypeList_redo.push_back(dataTypeName);

	auto& dataOp = dataOpMap.at(dataTypeName);
	auto& stepData = step.at(dataTypeName);
	auto& redoData = redo.at(dataTypeName);
	auto& undoData = undo.at(dataTypeName);

	redoData.push_back(dataOp.NewCopyOfData(stepData));
	dataOp.ReleaseData(stepData);
	stepData = undoData.back();
	undoData.pop_back();
}

void MyUndoRedo::Redo()
{
	if (dataTypeList_redo.empty())
		return;
	std::string dataTypeName = dataTypeList_redo.back();
	dataTypeList_redo.pop_back();
	dataTypeList_undo.push_back(dataTypeName);

	auto& dataOp = dataOpMap.at(dataTypeName);
	auto& stepData = step.at(dataTypeName);
	auto& redoData = redo.at(dataTypeName);
	auto& undoData = undo.at(dataTypeName);

	undoData.push_back(dataOp.NewCopyOfData(stepData));
	dataOp.ReleaseData(stepData);
	stepData = redoData.back();
	redoData.pop_back();
}

bool MyUndoRedo::UndoEmpty()
{
	return dataTypeList_undo.empty();
}

bool MyUndoRedo::RedoEmpty()
{
	return dataTypeList_redo.empty();
}

void MyUndoRedo::Clear()
{
	for (auto& p : step)
	{
		auto& op = dataOpMap.at(p.first);
		auto& stepData = p.second;
		op.ReleaseData(stepData);
		stepData = op.NewData();
	}
	ClearUndoRedo();
}

void MyUndoRedo::ClearUndoRedo()
{
	for (auto& p : redo)
	{
		auto& op = dataOpMap.at(p.first);
		auto& redoData = p.second;
		for (auto& t : redoData)
			op.ReleaseData(t);
		redoData.clear();
	}

	for (auto& p : undo)
	{
		auto& op = dataOpMap.at(p.first);
		auto& undoData = p.second;
		for (auto& t : undoData)
			op.ReleaseData(t);
		undoData.clear();
	}
	dataTypeList_redo.clear();
	dataTypeList_undo.clear();
}

void* MyUndoRedo::GetStep(const char* dataTypeName)
{
	return step.at(dataTypeName);
}

void* MyAniSet_NewData()
{
	return new CANIEDITOR_DATATYPE_ANI();
}

void* MyAniSet_NewCopyOfData(void* data)
{
	auto layerList = (CANIEDITOR_DATATYPE_ANI*)data;
	auto ret = new CANIEDITOR_DATATYPE_ANI();
	*ret = *layerList;
	return ret;
}

void MyAniSet_ReleaseData(void* data)
{
	auto layerList = (CANIEDITOR_DATATYPE_ANI*)data;
	delete layerList;
}

MyAniSet::MyAniSet()
{
	MyUndoRedoDataOp op;
	op.NewData = MyAniSet_NewData;
	op.NewCopyOfData = MyAniSet_NewCopyOfData;
	op.ReleaseData = MyAniSet_ReleaseData;
	undoRedo.AddDataType(CANIEDITOR_DATATYPE_ANI_STR, op);
}

CANIEDITOR_DATATYPE_ANI* MyAniSet::GetStep()
{
	return (CANIEDITOR_DATATYPE_ANI*)undoRedo.GetStep(CANIEDITOR_DATATYPE_ANI_STR);
}

bool operator==(const MyAniFrame& l, const MyAniFrame& r)
{
	return l.id == r.id &&
		l.offx == r.offx &&
		l.offy == r.offy;
}

bool operator==(const MyAniLayer& l, const MyAniLayer& r)
{
	return l.rcList == r.rcList;
}

bool operator==(const MyAniSet& l, const MyAniSet& r)
{
	bool b1 = (l.loop == r.loop && 
		l.playSpeed == r.playSpeed &&
		l.texture_left == r.texture_left &&
		l.texture_right == r.texture_right &&
		l.texture_up == r.texture_up &&
		l.texture_down == r.texture_down);
	CANIEDITOR_DATATYPE_ANI* lstep = (CANIEDITOR_DATATYPE_ANI*)l.undoRedo.step.at(CANIEDITOR_DATATYPE_ANI_STR);
	CANIEDITOR_DATATYPE_ANI* rstep = (CANIEDITOR_DATATYPE_ANI*)r.undoRedo.step.at(CANIEDITOR_DATATYPE_ANI_STR);
	bool b2 = (*lstep == *rstep);
	return b1 && b2;
}

bool operator==(const EntityFlag& l, const EntityFlag& r)
{
	return l.tCheck == r.tCheck &&
		l.tTouch == r.tTouch &&
		l.tDeath == r.tDeath &&
		l.tCrush == r.tCrush &&
		l.tHurt == r.tHurt &&
		l.tDamage == r.tDamage &&
		l.fShow == r.fShow &&
		l.fHide == r.fHide &&
		l.skShow == r.skShow &&
		l.skHide == r.skHide &&
		l.d0Show == r.d0Show &&
		l.d0Hide == r.d0Hide &&
		l.d1Show == r.d1Show &&
		l.d1Hide == r.d1Hide &&
		l.lr == r.lr &&
		l.text == r.text &&
		l.save == r.save &&
		l.simpAni == r.simpAni;
}

bool operator==(const EntityLoad& l, const EntityLoad& r)
{
	return l.name == r.name &&
		l.x == r.x &&
		l.y == r.y &&
		l.eid == r.eid &&
		l.eventName == r.eventName &&
		l.arg == r.arg &&
		l.arg2 == r.arg2 &&
		l.arg3 == r.arg3 &&
		l.flag == r.flag;
}

void MyMapLayer::UpdatePxmArr(int pxaArr_w)
{
	pxmArr_w = 0;
	pxmArr_h = 0;
	for (auto& p : *GetPxmStep())
	{
		auto x = LOWORD(p.first);
		auto y = HIWORD(p.first);
		if (x > pxmArr_w)
			pxmArr_w = x;
		if (y > pxmArr_h)
			pxmArr_h = y;
	}
	//是宽度所以+1
	pxmArr_w++;
	pxmArr_h++;
	pxmArr.resize(pxmArr_w * pxmArr_h);
	std::fill(pxmArr.begin(), pxmArr.end(), 0);
	//把所有数据拷贝进数组
	for (auto& p : *GetPxmStep())
	{
		auto x = LOWORD(p.first);
		auto y = HIWORD(p.first);
		auto pxaX = LOWORD(p.second);
		auto pxaY = HIWORD(p.second);
		pxmArr[y * pxmArr_w + x] = pxaY * pxaArr_w + pxaX;
	}
}

CMAPEDITOR_DATATYPE_PXM* MyMapLayer::GetPxmStep()
{
	return (CMAPEDITOR_DATATYPE_PXM*)undoRedo.GetStep(CMAPEDITOR_DATATYPE_PXM_STR);
}

CMAPEDITOR_DATATYPE_PXE* MyMapLayer::GetPxeStep()
{
	return (CMAPEDITOR_DATATYPE_PXE*)undoRedo.GetStep(CMAPEDITOR_DATATYPE_PXE_STR);
}

bool MyMapLayer::operator<(const MyMapLayer& r) const
{
	return order > r.order;
}

bool operator==(const MyMapLayer& l, const MyMapLayer& r)
{
	auto b1 = //地形组
		l.visible == r.visible &&
		l.pxaName == r.pxaName &&
		//图层类型
		l.layerType == r.layerType &&
		//图层属性
		l.offx == r.offx &&
		l.offy == r.offy &&
		l.myFar == r.myFar &&
		//循环背景层属性
		l.loopH == r.loopH &&
		l.loopV == r.loopV &&
		l.speedH == r.speedH &&
		l.speedV == r.speedV &&
		//通用
		l.order == r.order &&
		l.jumpFrame == r.jumpFrame &&
		//光层
		l.dayLight == r.dayLight &&
		l.tinyHSV[0] == r.tinyHSV[0] &&
		l.tinyHSV[1] == r.tinyHSV[1] &&
		l.tinyHSV[2] == r.tinyHSV[2] &&
		l.lightConst == r.lightConst &&
		//颜色调整
		l.color == r.color &&
		//绘制剪切区域
		l.enableClipZone == r.enableClipZone &&
		l.clipZone == r.clipZone;
	CMAPEDITOR_DATATYPE_PXM* lstep_pxm = (CMAPEDITOR_DATATYPE_PXM*)l.undoRedo.step.at(CMAPEDITOR_DATATYPE_PXM_STR);
	CMAPEDITOR_DATATYPE_PXM* rstep_pxm = (CMAPEDITOR_DATATYPE_PXM*)r.undoRedo.step.at(CMAPEDITOR_DATATYPE_PXM_STR);
	
	CMAPEDITOR_DATATYPE_PXM lpxm, rpxm;
	//只比较有值的部分
	for (auto& p : *lstep_pxm)
		if (p.second != 0)
			lpxm.insert(p);
	for (auto& p : *rstep_pxm)
		if (p.second != 0)
			rpxm.insert(p);
	bool b2 = (lpxm == rpxm);
	CMAPEDITOR_DATATYPE_PXE* lstep_pxe = (CMAPEDITOR_DATATYPE_PXE*)l.undoRedo.step.at(CMAPEDITOR_DATATYPE_PXE_STR);
	CMAPEDITOR_DATATYPE_PXE* rstep_pxe = (CMAPEDITOR_DATATYPE_PXE*)r.undoRedo.step.at(CMAPEDITOR_DATATYPE_PXE_STR);
	bool b3 = (*lstep_pxe == *rstep_pxe);
	return b1 && b2 && b3;
}

bool operator==(const MyMapSet& l, const MyMapSet& r)
{
	return l.mapName == r.mapName &&
		l.mapW == r.mapW &&
		l.mapH == r.mapH &&
		l.layerList == r.layerList;
}

CString StrAddLr(CString text)
{
	std::wstringstream strbuff;
	for (int i = 0; i < text.GetLength(); i++)
	{
		auto c = text.GetAt(i);
		if (c == L'\n')
		{
			if (i - 1 > 0 &&
				text.GetAt(i - 1) != L'\r')
				strbuff << L'\r';
			else if (i == 0)
				strbuff << L'\r';
		}
		strbuff << c;
	}
	CString ret = strbuff.str().c_str();
	return ret;
}

void PxaData::UpdatePxaArr()
{
	pxaArr_w = 0;
	pxaArr_h = 0;
	for (auto& p : pxa)
	{
		auto x = LOWORD(p.first);
		auto y = HIWORD(p.first);
		if (x > pxaArr_w)
			pxaArr_w = x;
		if (y > pxaArr_h)
			pxaArr_h = y;
	}
	//是宽度所以+1
	pxaArr_w++;
	pxaArr_h++;
	pxaArr.resize(pxaArr_w * pxaArr_h);
	std::fill(pxaArr.begin(), pxaArr.end(), 0);
	//把所有数据拷贝进数组
	for (auto& p : pxa)
	{
		auto x = LOWORD(p.first);
		auto y = HIWORD(p.first);
		pxaArr[y * pxaArr_w + x] = p.second;
	}
}
