#include "CAniEditor.h"
#include "resource.h"
#include "CPidEditor.h"
#include "CNewAni.h"
#include "CAniEditorDrawGrid.h"
#include "CAniEditorLayerEdit.h"
#include "CAniEditorHideTable.h"
#include "CAniEditorChangeID.h"
#include "CAniOp.h"

IMPLEMENT_DYNAMIC(CAniEditor, CDialog)

BEGIN_MESSAGE_MAP(CAniEditor, CDialog)
	ON_COMMAND(IDOK, &CAniEditor::OnEnterKey)
	ON_WM_SIZE()
	ON_WM_SHOWWINDOW()
	ON_WM_TIMER()
	ON_COMMAND(ID_ADD_ANI, &CAniEditor::OnAddAni)
	ON_COMMAND(ID_PREP_ANI, &CAniEditor::OnPrepAni)
	ON_COMMAND(ID_ANIOP, &CAniEditor::OnAniop)
	ON_COMMAND(ID_COPY, &CAniEditor::OnCopy)
	ON_COMMAND(ID_PASTE, &CAniEditor::OnPaste)
	ON_COMMAND(ID_CUT, &CAniEditor::OnCut)
	ON_COMMAND(ID_DELETE, &CAniEditor::OnDeleteAni)
	ON_COMMAND(ID_DELETE_ANI, &CAniEditor::OnDeleteAni)
	ON_COMMAND(ID_REDO, &CAniEditor::OnRedo)
	ON_COMMAND(ID_SAVE_FILE, &CAniEditor::OnSaveFile)
	ON_COMMAND(ID_UNDO, &CAniEditor::OnUndo)
	ON_COMMAND(ID_BK_SETTING, &CAniEditor::OnBkSetting)
	ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_ANILIST, &CAniEditor::OnTvnSelchangedTreeAnilist)
	ON_MESSAGE(MYPICBUTTON_LBUTTONUP, &CAniEditor::OnMyPicButtonLButtonUp)
	ON_COMMAND(ID_NEXTFRAME, &CAniEditor::OnNextframe)
	ON_COMMAND(ID_PREVFRAME, &CAniEditor::OnPrevframe)
	ON_COMMAND(ID_OP_LAYER, &CAniEditor::OnOpLayer)
	ON_COMMAND(ID_HIDE_TABLE, &CAniEditor::OnHideTable)
	ON_COMMAND(ID_CHANGE_ID, &CAniEditor::OnChangeId)
END_MESSAGE_MAP()

CAniEditor::CAniEditor(CWnd* pParent)
	: CDialog(IDD_CANIEDITOR, pParent)
{
}

CAniEditor::~CAniEditor()
{
}

void CAniEditor::Load(CString filename)
{
	pngfile = filename;
	pDrawWnd.Load(filename);
	pTimeLineWnd.Load(filename);
	tree_aniList.SetMenu(IDR_CANIEDITOR_ANILIST_RMENU, IDR_CANIEDITOR_ANILIST_RMENU_NOSEL);
}

void CAniEditor::ResetContext()
{
	playing = false;
	pngfile = L"";
	tree_aniList.DeleteAllItems();
	anisetList.clear();
	saved.clear();
	UpdateMenuState();//更新菜单状态
	UpdateWindowTitle();//更新窗口标题
	tree_aniList.SetMenu(0, 0);
	Draw();
}

//递归添加
void CAniEditor_TreeItemToXML(std::unordered_map<std::wstring, MyAniSet>* anisetList, CMyTreeCtrl* treeCtrl, HTREEITEM item, tinyxml2::XMLDocument* xmlDoc, tinyxml2::XMLElement* xmlElement, bool onlySelf = false)
{
	if (item == nullptr)
		return;
	CString aniName = treeCtrl->GetItemText(item);
	auto & as = anisetList->at(aniName.GetString());
	std::vector<char> nameBuff;
	UTF16ToUTF8(aniName.GetString(), &nameBuff);
	auto elem_animation = xmlDoc->NewElement("Animation");
	elem_animation->SetAttribute("Name", nameBuff.data());
	elem_animation->SetAttribute("Speed", as.playSpeed);
	elem_animation->SetAttribute("Loop", as.loop);
	elem_animation->SetAttribute("Texture_Left", as.texture_left);
	elem_animation->SetAttribute("Texture_Right", as.texture_right);
	elem_animation->SetAttribute("Texture_Up", as.texture_up);
	elem_animation->SetAttribute("Texture_Down", as.texture_down);
	for (auto& t : *as.GetStep())
	{
		auto elem_layer = xmlDoc->NewElement("Layer");
		for (auto& frame : t.rcList)
		{
			auto elem_rc = xmlDoc->NewElement("Frame");
			elem_rc->SetAttribute("id", frame.id);
			elem_rc->SetAttribute("offx", frame.offx);
			elem_rc->SetAttribute("offy", frame.offy);
			elem_layer->InsertEndChild(elem_rc);
		}
		elem_animation->InsertEndChild(elem_layer);
	}
	//插入节点
	if (xmlElement)
		xmlElement->InsertEndChild(elem_animation);
	else
		xmlDoc->InsertEndChild(elem_animation);
	//遍历子节点
	CAniEditor_TreeItemToXML(anisetList, treeCtrl, treeCtrl->GetChildItem(item), xmlDoc, elem_animation);
	//遍历兄弟节点
	if (!onlySelf)
		CAniEditor_TreeItemToXML(anisetList, treeCtrl, treeCtrl->GetNextSiblingItem(item), xmlDoc, xmlElement);
}

CString CAniEditor::XMLSaved()
{
	tinyxml2::XMLDocument xmlDoc;
	//动画表
	auto elem_ani = xmlDoc.NewElement("Ani");
	xmlDoc.InsertEndChild(elem_ani);
	CAniEditor_TreeItemToXML(&anisetList, &tree_aniList, tree_aniList.GetRootItem(), &xmlDoc, elem_ani);
	//图层隐藏表
	std::vector<char> utf8;
	UTF16ToUTF8(hideTable.GetString(), &utf8);
	auto elem_hideTable = xmlDoc.NewElement("HideTable");
	elem_hideTable->SetText(utf8.data());
	xmlDoc.InsertEndChild(elem_hideTable);
	//转化成字符串
	tinyxml2::XMLPrinter xmlPrinter;
	xmlDoc.Print(&xmlPrinter);
	std::vector<wchar_t> wchar_buff;
	UTF8ToUTF16(xmlPrinter.CStr(), &wchar_buff);
	return CString(wchar_buff.data());
}

//递归添加
void CAniEditor_XMLToTreeItem(std::unordered_map<std::wstring, MyAniSet>* anisetList, CMyTreeCtrl* treeCtrl, HTREEITEM item, tinyxml2::XMLElement* xmlElement)
{
	std::vector<wchar_t> wchar_buff;
	if (xmlElement == nullptr)
		return;
	//跳过设定标签
	if (strcmp(xmlElement->Name(), "Animation") == 0)//pos
	{
		MyAniSet as;
		auto& step = *as.GetStep();
		//取动画名称
		const char* name = xmlElement->Attribute("Name");
		UTF8ToUTF16(name, &wchar_buff);
		CString aniName = wchar_buff.data();
		as.loop = xmlElement->BoolAttribute("Loop");
		as.playSpeed = xmlElement->IntAttribute("Speed");
		as.texture_left = xmlElement->IntAttribute("Texture_Left", 16);
		as.texture_right = xmlElement->IntAttribute("Texture_Right", 16);
		as.texture_up = xmlElement->IntAttribute("Texture_Up", 16);
		as.texture_down = xmlElement->IntAttribute("Texture_Down", 16);
		//遍历动画层表
		for (auto p = xmlElement->FirstChildElement(); p != nullptr; p = p->NextSiblingElement())
		{
			//如果不是Layer元素则跳过
			if (strcmp(p->Name(), "Layer") != 0)
				continue;
			MyAniLayer layer;
			//遍历矩形表
			for (auto t = p->FirstChildElement(); t != nullptr; t = t->NextSiblingElement())
			{
				//如果不是Rect元素则跳过
				if (strcmp(t->Name(), "Frame") != 0)
					continue;
				MyAniFrame frame;
				frame.id = t->IntAttribute("id");
				frame.offx = t->FloatAttribute("offx");
				frame.offy = t->FloatAttribute("offy");
				layer.rcList.push_back(frame);
			}
			step.push_back(layer);
		}
		//防止重名
		while (anisetList->find(aniName.GetString()) != anisetList->end())
			aniName.Append(L"0");
		anisetList->insert(std::make_pair(aniName.GetString(), as));
		//插入节点
		HTREEITEM childItem = treeCtrl->InsertItem(aniName.GetString(), item);
		//遍历子节点
		CAniEditor_XMLToTreeItem(anisetList, treeCtrl, childItem, xmlElement->FirstChildElement());
	}
	//遍历兄弟节点
	CAniEditor_XMLToTreeItem(anisetList, treeCtrl, item, xmlElement->NextSiblingElement());
}

void CAniEditor::XMLLoad(CString xml)
{
	std::vector<char> xml_utf8;
	UTF16ToUTF8(xml.GetString(), &xml_utf8);
	tinyxml2::XMLDocument xmlDoc;
	xmlDoc.Parse(xml_utf8.data());
	ResetContext();
	//重新添加
	//寻找Ani元素
	tinyxml2::XMLElement* elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "Ani"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		CAniEditor_XMLToTreeItem(&anisetList, &tree_aniList, TVI_ROOT, elem->FirstChildElement());
	}
	tree_aniList.SetMenu(IDR_CANIEDITOR_ANILIST_RMENU, IDR_CANIEDITOR_ANILIST_RMENU_NOSEL);
	//寻找HideTable元素
	hideIDTable.clear();
	hideTable = L"";
	elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "HideTable"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		std::vector<wchar_t> utf16;
		UTF8ToUTF16(elem->GetText(), &utf16);
		hideTable = utf16.data();
		hideTable = StrAddLr(hideTable);
		std::vector<int> idList;
		CAniEditorHideTable::ParseInts(hideTable.GetString(), idList);
		for (auto& i : idList)
		{
			if (hideIDTable.find(i) == hideIDTable.end())
				hideIDTable.insert(i);
		}
	}
}

bool CAniEditor::CheckSaved()
{
	return anisetList == saved &&
		hideTable == hideTable_saved;
}

void CAniEditor::StepCopyToSaved()
{
	saved = anisetList;
	hideTable_saved = hideTable;
	UpdateMenuState();//更新菜单状态
	UpdateWindowTitle();//更新窗口标题
}

void CAniEditor::UpdateMenuState()
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	
	if (parentEditor->IsLoaded())
	{
		GetMenu()->GetSubMenu(CANIEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_COPY, MF_ENABLED);
		GetMenu()->GetSubMenu(CANIEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_PASTE, MF_ENABLED);
		GetMenu()->GetSubMenu(CANIEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_CUT, MF_ENABLED);
		auto item = tree_aniList.GetSelectedItem();
		if (item)
		{
			CString aniName = tree_aniList.GetItemText(item);
			MyAniSet& aniSet = anisetList.at(aniName.GetString());
			auto& undoRedo = aniSet.undoRedo;
			if (undoRedo.UndoEmpty())
				GetMenu()->GetSubMenu(CANIEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_UNDO, MF_DISABLED);
			else
				GetMenu()->GetSubMenu(CANIEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_UNDO, MF_ENABLED);

			if (undoRedo.RedoEmpty())
				GetMenu()->GetSubMenu(CANIEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_REDO, MF_DISABLED);
			else
				GetMenu()->GetSubMenu(CANIEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_REDO, MF_ENABLED);
		}
	}
	else
	{
		GetMenu()->GetSubMenu(CANIEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_COPY, MF_DISABLED);
		GetMenu()->GetSubMenu(CANIEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_PASTE, MF_DISABLED);
		GetMenu()->GetSubMenu(CANIEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_CUT, MF_DISABLED);
		GetMenu()->GetSubMenu(CANIEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_UNDO, MF_DISABLED);
		GetMenu()->GetSubMenu(CANIEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_REDO, MF_DISABLED);
	}
}

void CAniEditor::UpdateWindowTitle()
{
	CString windowTitle, appendStr;
	bool sav = CheckSaved();
	auto parentEditor = (CPidEditor*)pParentEditor;
	appendStr.Format(TEXT("动画编辑窗口 - "));
	windowTitle.Append(appendStr);
	auto item = tree_aniList.GetSelectedItem();
	if (item)
	{
		CString aniName = tree_aniList.GetItemText(item);
		appendStr.Format(TEXT("编辑动画：%s - "), aniName.GetString());
	}
	else
		appendStr.Format(TEXT("未选中任何动画 - "));
	windowTitle.Append(appendStr);
	if (parentEditor->IsLoaded())
	{
		appendStr.Format(TEXT("已载入文件：%s"), parentEditor->GetPidFile().GetString());
		windowTitle.Append(appendStr);
		if (!sav)
			windowTitle.Append(TEXT("(未保存)"));
		else
			windowTitle.Append(TEXT("(已保存)"));
	}
	else
	{
		windowTitle.Append(TEXT("(未载入文件)"));
	}
	SetWindowText(windowTitle);
	parentEditor->UpdateWindowTitle();
}

void CAniEditor::Draw()
{
	pDrawWnd.Draw();
	pTimeLineWnd.Draw();
}

void CAniEditor::SetAniID(int id)
{
	if (!button_edit.GetCheck())
		return;
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	CString aniName = tree_aniList.GetItemText(item);
	auto& aniSet = anisetList.at(aniName.GetString());
	auto& step = *aniSet.GetStep();
	auto& view = *pTimeLineWnd.GetMyView();
	if (view.cursorY_selected >= step.size())// 2025/4/26 bug修复
		return;
	auto& layer = step.at(view.cursorY_selected);
	if (view.cursorX_selected >= layer.rcList.size())// 2025/5/31 bug修复
		return;
	auto& aniIndex = layer.rcList.at(view.cursorX_selected);
	aniSet.undoRedo.BeginStep(CANIEDITOR_DATATYPE_ANI_STR);
	aniIndex.id = id;
	aniSet.undoRedo.EndStep();
	Draw();
	UpdateMenuState();
	UpdateWindowTitle();
}

void CAniEditor::SetAniFrame(const MyAniFrame* frame)
{
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	CString aniName = tree_aniList.GetItemText(item);
	auto& aniSet = anisetList.at(aniName.GetString());
	auto& step = *aniSet.GetStep();
	auto& view = *pTimeLineWnd.GetMyView();
	int layerNum = (int)step.size();
	if (!layerNum)
		return;
	int aniLen = (int)(step.front().rcList.size());
	if (!aniLen)
		return;
	if (view.cursorX >= aniLen || view.cursorY >= layerNum)
		return;
	aniSet.undoRedo.BeginStep(CANIEDITOR_DATATYPE_ANI_STR);
	auto& layer = step.at(view.cursorY);
	auto& aniIndex = layer.rcList.at(view.cursorX);
	aniIndex = *frame;
	aniSet.undoRedo.EndStep();
	Draw();
	UpdateMenuState();
	UpdateWindowTitle();
}

void CAniEditor::GetAniFrame(std::list<MyAniFrame>* frameList)
{
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	CString aniName = tree_aniList.GetItemText(item);
	auto& aniSet = anisetList.at(aniName.GetString());
	auto& step = *aniSet.GetStep();
	auto& view = *pTimeLineWnd.GetMyView();
	int layerNum = (int)step.size();
	if (!layerNum)
		return;
	int aniLen = (int)(step.front().rcList.size());
	if (!aniLen)
		return;
	frameList->clear();
	if (pTimeLineWnd.GetTimeIndex() >= aniLen)
		return;
	int id = 0;
	for (auto& p : step)
	{
		//跳过隐藏图层
		if (hideIDTable.find(id) == hideIDTable.end())
			frameList->push_front(p.rcList.at(pTimeLineWnd.GetTimeIndex()));
		id++;
	}
}

void CAniEditor::GetSelectAniFrame(std::vector<MyAniFrame*>* frameList)
{
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	CString aniName = tree_aniList.GetItemText(item);
	auto& aniSet = anisetList.at(aniName.GetString());
	auto& step = *aniSet.GetStep();
	auto& view = *pTimeLineWnd.GetMyView();
	int layerNum = (int)step.size();
	if (!layerNum)
		return;
	int aniLen = (int)(step.front().rcList.size());
	if (!aniLen)
		return;
	frameList->clear();
	if (pTimeLineWnd.GetTimeIndex() >= aniLen)
		return;
	if (view.cursorX_selected >= aniLen || view.cursorY_selected >= layerNum)
		return;
	for (int y = view.cursorY_selected; y < view.cursorY_selected + view.cursorH_selected && y < step.size(); y++)
		for (int x = view.cursorX_selected; x < view.cursorX_selected + view.cursorW_selected && x < step.at(y).rcList.size(); x++)
			frameList->push_back(&step.at(y).rcList.at(x));
}

void CAniEditor::GetSelectAniInfo(MyAniSet** as)
{
	*as = nullptr;
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	CString aniName = tree_aniList.GetItemText(item);
	auto& aniSet = anisetList.at(aniName.GetString());
	*as = &aniSet;
}

MyUndoRedo* CAniEditor::GetMyUndoRedo()
{
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return nullptr;
	CString aniName = tree_aniList.GetItemText(item);
	auto& aniSet = anisetList.at(aniName.GetString());
	return &aniSet.undoRedo;
}

CANIEDITOR_DATATYPE_ANI* CAniEditor::GetStep()
{
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return nullptr;
	//选择
	CString aniName = tree_aniList.GetItemText(item);
	MyAniSet& aniSet = anisetList.at(aniName.GetString());
	return aniSet.GetStep();
}

void CAniEditor::AniIDSetRect(int id, MyRect* rc)
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	parentEditor->AniIDSetRect(id, rc);
}

bool CAniEditor::IsLoaded()
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	return parentEditor->IsLoaded();
}

std::set<int>* CAniEditor::GetHideTable()
{
	return &hideIDTable;
}

int CAniEditor::GetSelectedLayerIndex()
{
	return pTimeLineWnd.GetMyView()->cursorY_selected;
}

std::unordered_map<std::wstring, MyAniSet>* CAniEditor::GetAniList()
{
	return &anisetList;
}

BOOL CAniEditor::PreTranslateMessage(MSG* pMsg)
{
	HOTKEYPROC;
}

void CAniEditor::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	static_aniList = (CStatic*)GetDlgItem(IDC_STATIC_ANILIST);
	DDX_Control(pDX, IDC_TREE_ANILIST, tree_aniList);
	DDX_Control(pDX, IDC_CHECK_EDIT, button_edit);
	static_playView = (CStatic*)GetDlgItem(IDC_STATIC_PLAYVIEW);
	static_timeLine = (CStatic*)GetDlgItem(IDC_STATIC_TIMELINE);
}

BOOL CAniEditor::OnInitDialog()
{
	CDialog::OnInitDialog();
	//载入快捷键
	LOADHOTKEY(IDR_ACC_ANIEDITOR);
	//设置应用程序图标
	auto hIcon = AfxGetApp()->LoadIcon(IDI_ICON_PID);
	SetIcon(hIcon, true);
	//设置tree_aniList
	auto style = tree_aniList.GetStyle();
	style |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT;
	tree_aniList.ModifyStyle(0, style);
	UpdateMenuState();//更新菜单状态
	UpdateWindowTitle();//更新窗口标题
	//初始化子窗口
	pDrawWnd.pParentEditor = this;
	pDrawWnd.Create(IDD_CANIEDITOR_DRAW, this);
	pDrawWnd.ShowWindow(SW_SHOW);
	pTimeLineWnd.pParentEditor = this;
	pTimeLineWnd.Create(IDD_CANIEDITOR_TIMELINE, this);
	pTimeLineWnd.ShowWindow(SW_SHOW);
	btn_play.Create(IDD_CMYPICBUTTON, this);
	btn_play.SetPic(IDB_BTN_PLAY1, IDB_BTN_PLAY2);
	btn_play.ShowWindow(SW_SHOW);
	btn_pause.Create(IDD_CMYPICBUTTON, this);
	btn_pause.SetPic(IDB_BTN_PAUSE1, IDB_BTN_PAUSE2);
	btn_pause.ShowWindow(SW_HIDE);
	btn_stop.Create(IDD_CMYPICBUTTON, this);
	btn_stop.SetPic(IDB_BTN_STOP1, IDB_BTN_STOP2);
	btn_stop.ShowWindow(SW_SHOW);
	btn_refresh.Create(IDD_CMYPICBUTTON, this);
	btn_refresh.SetPic(IDB_BTN_REFRESH1, IDB_BTN_REFRESH2);
	btn_refresh.ShowWindow(SW_SHOW);
	//计时器
	timeid = SetTimer(1, 15, nullptr);
	return 0;
}

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

void CAniEditor::OnEnterKey()
{
}


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

	
	if (!static_aniList)
		return;
	auto dpi = MyGetDPI();
	//按钮
	int buttonOffx = cx - DPISCALE(194) - DPISCALE(10);
	btn_play.SetWindowPos(nullptr, buttonOffx, DPISCALE(3), DPISCALE(64), DPISCALE(36), SWP_NOZORDER);
	btn_pause.SetWindowPos(nullptr, buttonOffx, DPISCALE(3), DPISCALE(64), DPISCALE(36), SWP_NOZORDER);
	buttonOffx += DPISCALE(64);
	btn_stop.SetWindowPos(nullptr, buttonOffx, DPISCALE(3), DPISCALE(64), DPISCALE(36), SWP_NOZORDER);
	buttonOffx += DPISCALE(64);
	btn_refresh.SetWindowPos(nullptr, buttonOffx, DPISCALE(3), DPISCALE(64), DPISCALE(36), SWP_NOZORDER);
	//动画列表
	int x, y, w, h;
	x = DPISCALE(10);
	y = DPISCALE(10);
	w = DPISCALE(200);
	h = cy - DPISCALE(20);
	static_aniList->MoveWindow(x, y, w, h);
	y += DPISCALE(20);
	h -= DPISCALE(20);
	tree_aniList.MoveWindow(x, y, w, h);
	//【启用编辑】按钮
	x = DPISCALE(220);
	y = DPISCALE(10);
	w = DPISCALE(300);
	h = DPISCALE(30);
	button_edit.MoveWindow(x, y, w, h);
	//预览窗
	x = DPISCALE(220);
	y = DPISCALE(40);
	w = cx - DPISCALE(230);
	h = cy * 2 / 5;
	static_playView->MoveWindow(x, y, w, h);
	y += DPISCALE(20);
	h -= DPISCALE(20);
	pDrawWnd.MoveWindow(x, y, w, h);
	//时间轴
	x = DPISCALE(220);
	y = cy * 2 / 5 + DPISCALE(40);
	w = cx - DPISCALE(230);
	h = cy - y - DPISCALE(10);
	static_timeLine->MoveWindow(x, y, w, h);
	y += DPISCALE(20);
	h -= DPISCALE(20);
	pTimeLineWnd.MoveWindow(x, y, w, h);
}


void CAniEditor::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CDialog::OnShowWindow(bShow, nStatus);
	auto parentEditor = (CPidEditor*)pParentEditor;
	
	if (bShow)
		parentEditor->GetMenu()->GetSubMenu(CPIDEDITOR_MENUINDEX_WINDOW)->CheckMenuItem(ID_ANI_EDITOR, MF_BYCOMMAND | MF_CHECKED);
	else
		parentEditor->GetMenu()->GetSubMenu(CPIDEDITOR_MENUINDEX_WINDOW)->CheckMenuItem(ID_ANI_EDITOR, MF_BYCOMMAND | MF_UNCHECKED);
}

void CAniEditor::OnTimer(UINT_PTR nIDEvent)
{
	CDialog::OnTimer(nIDEvent);
	if (!playing || nIDEvent != timeid)
		return;
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	CString aniName = tree_aniList.GetItemText(item);
	MyAniSet& aniSet = anisetList.at(aniName.GetString());
	if (aniSet.playSpeed == 0)
		return;
	auto& step = *aniSet.GetStep();
	int layerNum = (int)step.size();
	if (!layerNum)
		return;
	int aniLen = (int)(step.front().rcList.size());
	if (!aniLen)
		return;

	if (timeCell >= aniSet.playSpeed)
	{
		timeCell = 0;
		Draw();
		auto timeIndex = pTimeLineWnd.GetTimeIndex();
		if(aniSet.loop || timeIndex  < aniLen - 1)
			pTimeLineWnd.SetTimeIndex(timeIndex + 1);
		timeIndex = pTimeLineWnd.GetTimeIndex();
		if (timeIndex >= aniLen)
			if (aniSet.loop)
				pTimeLineWnd.SetTimeIndex(0);
			else
				pTimeLineWnd.SetTimeIndex(aniLen - 1);
	}
	timeCell++;
}

void CAniEditor::OnAddAni()
{
	
	auto item = tree_aniList.GetSelectedItem();
	//添加动画
	CNewAni dlg;
	dlg.pAs = &anisetList;//重名测试参数
	if (dlg.DoModal() != IDOK)
		return;

	//anisetList添加
	MyAniSet as;
	as.loop = dlg.outLoopAni;
	as.playSpeed = dlg.outPlaySpeed;
	as.texture_left = dlg.outTextureLeft;
	as.texture_right = dlg.outTextureRight;
	as.texture_up = dlg.outTextureUp;
	as.texture_down = dlg.outTextureDown;
	auto& step = *as.GetStep();
	step.resize(dlg.outLayerNum);
	for (auto& p : step)
		p.rcList.resize(dlg.outAniLen);
	anisetList.insert(std::make_pair(dlg.outAniName.GetString(), as));
	//tree添加
	HTREEITEM childItem = tree_aniList.InsertItem(dlg.outAniName.GetString(), item);
	UpdateMenuState();//更新菜单状态
	UpdateWindowTitle();//更新窗口标题
}

void CAniEditor::OnPrepAni()
{
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	CString aniName = tree_aniList.GetItemText(item);
	auto& aniSet = anisetList.at(aniName.GetString());
	auto& step = *aniSet.GetStep();
	//编辑动画
	CNewAni dlg;
	dlg.outAniName = aniName;//动画名
	int layerNum = dlg.outLayerNum = (int)step.size();//层数
	int aniLen = 0;
	if (step.empty())//动画长度
		aniLen = dlg.outAniLen = 0;
	else
		aniLen = dlg.outAniLen = (int)step.front().rcList.size();
	bool loopAni = dlg.outLoopAni = aniSet.loop;//是否循环播放
	int playSpeed = dlg.outPlaySpeed = aniSet.playSpeed;//动画速度
	int texture_left = aniSet.texture_left;//贴图边界
	int texture_right = aniSet.texture_right;//贴图边界
	int texture_up = aniSet.texture_up;//贴图边界
	int texture_down = aniSet.texture_down;//贴图边界
	dlg.outTextureLeft = texture_left;
	dlg.outTextureRight = texture_right;
	dlg.outTextureUp = texture_up;
	dlg.outTextureDown = texture_down;
	dlg.pAs = &anisetList;//重名测试参数
	if (dlg.DoModal() != IDOK)
		return;
	bool bModify = false;
	//修改动画名
	if (aniName != dlg.outAniName)
	{
		tree_aniList.SetItemText(item, dlg.outAniName);
		MyAniSet copyofAniSet = anisetList.at(aniName.GetString());
		anisetList.insert(std::make_pair(dlg.outAniName.GetString(), copyofAniSet));
		anisetList.erase(aniName.GetString());
		bModify = true;
	}
	MyAniSet& editedAniSet = anisetList.at(dlg.outAniName.GetString());
	auto& editedStep = *editedAniSet.GetStep();
	//修改层数
	if (layerNum != dlg.outLayerNum)
	{
		editedStep.resize(dlg.outLayerNum);
		for (auto& p : editedStep)
			p.rcList.resize(dlg.outAniLen);
		pTimeLineWnd.SetLayerNumAndAniLen(dlg.outAniLen, dlg.outLayerNum);
		bModify = true;
	}
	//修改动画长度
	if (aniLen != dlg.outAniLen)
	{
		for (auto& p : editedStep)
			p.rcList.resize(dlg.outAniLen);
		pTimeLineWnd.SetLayerNumAndAniLen(dlg.outAniLen, dlg.outLayerNum);
		bModify = true;
	}
	//修改循环播放
	if (loopAni != dlg.outLoopAni)
	{
		editedAniSet.loop = dlg.outLoopAni;
		bModify = true;
	}
	//修改动画速度
	if (playSpeed != dlg.outPlaySpeed)
	{
		editedAniSet.playSpeed = dlg.outPlaySpeed;
		bModify = true;
	}
	//修改着色器贴图边界
	if (texture_left != dlg.outTextureLeft ||
		texture_right != dlg.outTextureRight ||
		texture_up != dlg.outTextureUp ||
		texture_down != dlg.outTextureDown)
	{
		editedAniSet.texture_left = dlg.outTextureLeft;
		editedAniSet.texture_right = dlg.outTextureRight;
		editedAniSet.texture_up = dlg.outTextureUp;
		editedAniSet.texture_down = dlg.outTextureDown;
		bModify = true;
	}
	if (bModify)//如果一旦有修改，则清除撤销缓存
		editedAniSet.undoRedo.ClearUndoRedo();
	UpdateMenuState();//更新菜单状态
	UpdateWindowTitle();//更新窗口标题
	Draw();
}

void CAniEditor::OnAniop()
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	static AniOpArg opArg;

	CString aniName = tree_aniList.GetItemText(item);
	CAniOp dlg;
	dlg.inAniName = aniName;
	dlg.inLineShow = parentEditor->lineShow;
	dlg.outArg = opArg;
	if (dlg.DoModal() != IDOK)
		return;
	opArg = dlg.outArg;
	//进行变换操作
	auto& aniSet = anisetList.at(aniName.GetString());
	auto& step = *aniSet.GetStep();
	if (step.empty())
		return;
	aniSet.undoRedo.BeginStep(CANIEDITOR_DATATYPE_ANI_STR);
	std::set<int> layerList;
	switch (opArg.layerTargetMode)
	{
	case 0://所有图层
		for (int i = 0; i < step.size(); i++)
			layerList.insert(i);
		break;
	case 1://排除图层
		{
			std::vector<int> numList;
			CAniEditorHideTable::ParseInts(opArg.layerList.GetString(), numList);
			for (int i = 0; i < step.size(); i++)
				layerList.insert(i);
			for (auto& p : numList)
				layerList.erase(p);
		}
		break;
	case 2://指定图层
		{
			std::vector<int> numList;
			CAniEditorHideTable::ParseInts(opArg.layerList.GetString(), numList);
			for (auto& p : numList)
				layerList.insert(p);
		}
		break;
	}
	std::set<int> frameList;
	switch (opArg.frameTargetMode)
	{
	case 0://所有帧
		for (int i = 0; i < step[0].rcList.size(); i++)
			frameList.insert(i);
		break;
	case 1://排除帧
		{
			std::vector<int> numList;
			CAniEditorHideTable::ParseInts(opArg.frameList.GetString(), numList);
			for (int i = 0; i < step[0].rcList.size(); i++)
				frameList.insert(i);
			for (auto& p : numList)
				frameList.erase(p);
		}
		break;
	case 2://指定帧
		{
			std::vector<int> numList;
			CAniEditorHideTable::ParseInts(opArg.frameList.GetString(), numList);
			for (auto& p : numList)
				frameList.insert(p);
		}
		break;
	}
	for (auto& layerIndex : layerList)
	{
		for (auto& frameIndex : frameList)
		{
			auto& p = step[layerIndex].rcList[frameIndex];
			//变换pid
			switch (opArg.pidOpMode)
			{
			case 0://加法
				p.id += opArg.pidOpNum;
				break;
			case 1://赋值
				p.id = opArg.pidOpNum;
				break;
			}
			//变换offset_x
			switch (opArg.offsetXOpMode)
			{
			case 0://加法
				p.offx += opArg.offsetXOpNum;
				break;
			case 1://乘法
				p.offx *= opArg.offsetXOpNum;
				break;
			case 2://赋值
				p.offx = opArg.offsetXOpNum;
				break;
			}
			//变换offset_y
			switch (opArg.offsetYOpMode)
			{
			case 0://加法
				p.offy += opArg.offsetYOpNum;
				break;
			case 1://乘法
				p.offy *= opArg.offsetYOpNum;
				break;
			case 2://赋值
				p.offy = opArg.offsetYOpNum;
				break;
			}
		}
	}
	aniSet.undoRedo.EndStep();
	Draw();
	UpdateMenuState();
	UpdateWindowTitle();
}

void CAniEditor::OnCopy()
{
	std::vector<wchar_t> wchar_buff;
	auto parentEditor = (CPidEditor*)pParentEditor;
	if (!parentEditor->IsLoaded())
		return;
	
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	//看鼠标落在哪个区域
	CPoint pt;
	CRect rc;
	GetCursorPos(&pt);
	tree_aniList.GetWindowRect(&rc);
	if (rc.PtInRect(pt))//动画区的复制粘贴功能
	{
		tinyxml2::XMLDocument xmlDoc;
		CAniEditor_TreeItemToXML(&anisetList, &tree_aniList, item, &xmlDoc, xmlDoc.RootElement(), true);
		tinyxml2::XMLPrinter xmlPrinter;
		xmlDoc.Print(&xmlPrinter);
		UTF8ToUTF16(xmlPrinter.CStr(), &wchar_buff);
		posCopyXML = wchar_buff.data();
	}
	pTimeLineWnd.GetWindowRect(&rc);
	if (rc.PtInRect(pt))//时间线区的复制粘贴功能
		copyFrame = pTimeLineWnd.GetCurFrame();
}


void CAniEditor::OnPaste()
{
	std::vector<char> utf8_buff;
	auto parentEditor = (CPidEditor*)pParentEditor;
	if (!parentEditor->IsLoaded())
		return;
	auto item = tree_aniList.GetSelectedItem();
	//看鼠标落在哪个区域
	CPoint pt;
	CRect rc;
	GetCursorPos(&pt);
	tree_aniList.GetWindowRect(&rc);
	if (rc.PtInRect(pt))//动画区的复制粘贴功能
	{
		if (posCopyXML.GetLength() == 0)
			return;
		UTF16ToUTF8(posCopyXML.GetString(), &utf8_buff);
		tinyxml2::XMLDocument xmlDoc;
		xmlDoc.Parse(utf8_buff.data());
		CAniEditor_XMLToTreeItem(&anisetList, &tree_aniList, item, xmlDoc.RootElement());
		tree_aniList.RedrawWindow();
		UpdateMenuState();//更新菜单状态
		UpdateWindowTitle();//更新窗口标题
	}
	pTimeLineWnd.GetWindowRect(&rc);
	if (rc.PtInRect(pt))//时间线区的复制粘贴功能
	{
		SetAniFrame(&copyFrame);
		UpdateMenuState();//更新菜单状态
		UpdateWindowTitle();//更新窗口标题
		Draw();
	}
}


void CAniEditor::OnCut()
{
	
	OnCopy();
	OnDeleteAni();
}

void CAniEditor_OnDeleteAni_ForeachAllChild(std::vector<std::wstring>* nameList, CMyTreeCtrl* treeCtrl, HTREEITEM item)
{
	if (item == nullptr)
		return;
	CString aniName = treeCtrl->GetItemText(item);
	nameList->push_back(aniName.GetString());
	//遍历子节点
	CAniEditor_OnDeleteAni_ForeachAllChild(nameList, treeCtrl, treeCtrl->GetChildItem(item));
	//遍历兄弟节点
	CAniEditor_OnDeleteAni_ForeachAllChild(nameList, treeCtrl, treeCtrl->GetNextSiblingItem(item));
}

void CAniEditor::OnDeleteAni()
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	if (!parentEditor->IsLoaded())
		return;
	
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	//看鼠标落在哪个区域
	CPoint pt;
	CRect rc;
	GetCursorPos(&pt);
	tree_aniList.GetWindowRect(&rc);
	if (rc.PtInRect(pt))//动画区的复制粘贴功能
	{
		//tree删除
		std::vector<std::wstring> nameList;
		//先保留要删除的所有item的名字
		CAniEditor_OnDeleteAni_ForeachAllChild(&nameList, &tree_aniList, tree_aniList.GetChildItem(item));//记录要删除子节点
		CString aniName = tree_aniList.GetItemText(item);
		nameList.push_back(aniName.GetString());//记录删除自己
		tree_aniList.DeleteItem(item);
		//anisetList删除
		for (auto& p : nameList)
			anisetList.erase(p);
		UpdateMenuState();//更新菜单状态
		UpdateWindowTitle();//更新窗口标题
	}
	pTimeLineWnd.GetWindowRect(&rc);
	if (rc.PtInRect(pt))//时间线区的复制粘贴功能
	{
		MyAniFrame emptyFrame;
		SetAniFrame(&emptyFrame);
		UpdateMenuState();//更新菜单状态
		UpdateWindowTitle();//更新窗口标题
		Draw();
	}
}


void CAniEditor::OnRedo()
{
	
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	CString aniName = tree_aniList.GetItemText(item);
	MyAniSet& aniSet = anisetList.at(aniName.GetString());
	aniSet.undoRedo.Redo();
	Draw();
	UpdateMenuState();
	UpdateWindowTitle();
}


void CAniEditor::OnSaveFile()
{
	
	auto parentEditor = (CPidEditor*)pParentEditor;
	parentEditor->Save();
}


void CAniEditor::OnUndo()
{
	
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	CString aniName = tree_aniList.GetItemText(item);
	MyAniSet& aniSet = anisetList.at(aniName.GetString());
	aniSet.undoRedo.Undo();
	Draw();
	UpdateMenuState();
	UpdateWindowTitle();
}

void CAniEditor::OnBkSetting()
{
	
	MyView& view = *pDrawWnd.GetMyView();
	CAniEditorDrawGrid dlg;
	dlg.outGridW = (int)view.grid_w;
	dlg.outGridH = (int)view.grid_h;
	dlg.outCountW = view.count_w;
	dlg.outCountH = view.count_max / view.count_w;
	dlg.outShowBk = pDrawWnd.showBk;
	dlg.outShowEntity = pDrawWnd.showEntity;
	dlg.outShowLine = pDrawWnd.showLine;
	dlg.outIsDark = pDrawWnd.isDark;
	if (dlg.DoModal() != IDOK)
		return;
	view.grid_w = (float)dlg.outGridW;
	view.grid_h = (float)dlg.outGridH;
	view.count_w = dlg.outCountW;
	view.count_max = dlg.outCountH * dlg.outCountW;
	pTimeLineWnd.showBk = pDrawWnd.showBk = dlg.outShowBk;
	pDrawWnd.showEntity = dlg.outShowEntity;
	pDrawWnd.showLine = dlg.outShowLine;
	pTimeLineWnd.isDark = pDrawWnd.isDark = dlg.outIsDark;
	pDrawWnd.ViewToCenter();
	Draw();
}

void CAniEditor::OnTvnSelchangedTreeAnilist(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
	auto item = tree_aniList.GetSelectedItem();
	UpdateMenuState();//更新菜单状态
	UpdateWindowTitle();//更新窗口标题
	auto& view = *pTimeLineWnd.GetMyView();
	if (item)
	{
		//选择
		lastSelectItem = item;
		CString aniName = tree_aniList.GetItemText(item);
		MyAniSet& aniSet = anisetList.at(aniName.GetString());
		auto& step = *aniSet.GetStep();
		int layerNum = (int)step.size();
		if (layerNum > 0)
		{
			int aniLen = (int)step.front().rcList.size();
			pTimeLineWnd.SetLayerNumAndAniLen(aniLen, layerNum);
			pDrawWnd.Draw();
		}
		else
		{
			view.count_max = 0;
			view.count_w = 0;
			Draw();
		}
	}
	else
	{
		//取消选择
		view.count_max = 0;
		view.count_w = 0;
		Draw();
	}
	*pResult = 0;
}

LRESULT CAniEditor::OnMyPicButtonLButtonUp(WPARAM wParam, LPARAM lParam)
{
	CMyPicButton* button = (CMyPicButton*)wParam;
	if (button == &btn_play)//如果是播放按钮
	{
		btn_play.ShowWindow(SW_HIDE);
		btn_pause.ShowWindow(SW_SHOW);
		//播放动画
		timeCell = 0;
		playing = true;
	}
	else if (button == &btn_pause)//如果是暂停按钮
	{
		btn_pause.ShowWindow(SW_HIDE);
		btn_play.ShowWindow(SW_SHOW);
		//暂停动画播放
		timeCell = 0;
		playing = false;
	}
	else if (button == &btn_stop)//如果是停止按钮
	{
		btn_pause.ShowWindow(SW_HIDE);
		btn_play.ShowWindow(SW_SHOW);
		//停止动画播放
		pTimeLineWnd.SetTimeIndex(0);
		timeCell = 0;
		playing = false;
		Draw();
	}
	else if (button == &btn_refresh)//如果是刷新按钮
	{
		pTimeLineWnd.SetTimeIndex(0);
		timeCell = 0;
		Draw();
	}
	return 0;
}

void CAniEditor::OnNextframe()
{
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
	{
		if (!lastSelectItem)
			return;
		else
			item = lastSelectItem;
	}
	CString aniName = tree_aniList.GetItemText(item);
	MyAniSet& aniSet = anisetList.at(aniName.GetString());
	auto& step = *aniSet.GetStep();
	if (step.empty())
		return;
	int aniLen = (int)(step.front().rcList.size());
	if (pTimeLineWnd.GetTimeIndex() + 1 < aniLen)
	{
		pTimeLineWnd.SetTimeIndex(pTimeLineWnd.GetTimeIndex() + 1);
		timeCell = 0;
		Draw();
	}
	else if (aniSet.loop)
	{
		pTimeLineWnd.SetTimeIndex(0);
		timeCell = 0;
		Draw();
	}
}


void CAniEditor::OnPrevframe()
{
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
	{
		if (!lastSelectItem)
			return;
		else
			item = lastSelectItem;
	}
	CString aniName = tree_aniList.GetItemText(item);
	MyAniSet& aniSet = anisetList.at(aniName.GetString());
	auto& step = *aniSet.GetStep();
	if (step.empty())
		return;
	int aniLen = (int)(step.front().rcList.size());
	if (pTimeLineWnd.GetTimeIndex() > 0)
	{
		pTimeLineWnd.SetTimeIndex(pTimeLineWnd.GetTimeIndex() - 1);
		timeCell = 0;
		Draw();
	}
	else if (aniSet.loop)
	{
		pTimeLineWnd.SetTimeIndex(aniLen - 1);
		timeCell = 0;
		Draw();
	}
}

void CAniEditor::OnOpLayer()
{
	auto item = tree_aniList.GetSelectedItem();
	if (!item)
		return;
	CString aniName = tree_aniList.GetItemText(item);
	auto& aniSet = anisetList.at(aniName.GetString());
	auto& step = *aniSet.GetStep();
	auto parentEditor = (CPidEditor*)pParentEditor;
	if (!parentEditor->IsLoaded())
	{
		MessageBoxW(L"必须先载入动画文件", L"未载入动画", MB_ICONINFORMATION);
		return;
	}
	if (pTimeLineWnd.GetMyView()->count_max == 0)
	{
		MessageBoxW(L"请先选择一个有效的动画", L"未选择动画", MB_ICONINFORMATION);
		return;
	}
	int aniLayer = (int)step.size();
	int aniLen = (int)step.front().rcList.size();

	CAniEditorLayerEdit dlg;
	dlg.outSrcLayerNum = pTimeLineWnd.GetMyView()->cursorY;
	dlg.testLayerNum = (int)step.size();//层数
	if (dlg.DoModal() != IDOK)
		return;
	switch (dlg.outOp)
	{
	case 0://上方位置插入
		{
			std::list<MyAniLayer> tempA(step.begin(), step.end());
			auto iter = tempA.begin();
			for (int i = 0; i < dlg.outSrcLayerNum; i++)
				iter++;
			for (int i = 0; i < dlg.outNum; i++)
			{
				MyAniLayer a;
				a.rcList.resize(aniLen);
				tempA.insert(iter,a);
			}
			std::vector<MyAniLayer> tempB(tempA.begin(), tempA.end());
			step = tempB;
			pTimeLineWnd.SetLayerNumAndAniLen(aniLen, aniLayer + dlg.outNum);
		}
		break;
	case 1://下方位置插入
		{
			std::list<MyAniLayer> tempA(step.begin(), step.end());
			auto iter = tempA.begin();
			for (int i = 0; i < dlg.outSrcLayerNum + 1; i++)
				iter++;
			if (iter == tempA.end())
			{
				//插入在末尾
				for (int i = 0; i < dlg.outNum; i++)
				{
					MyAniLayer a;
					a.rcList.resize(aniLen);
					tempA.push_back(a);
				}
			}
			else
			{
				//插入在前面
				for (int i = 0; i < dlg.outNum; i++)
				{
					MyAniLayer a;
					a.rcList.resize(aniLen);
					tempA.insert(iter, a);
				}
			}
			std::vector<MyAniLayer> tempB(tempA.begin(), tempA.end());
			step = tempB;
			pTimeLineWnd.SetLayerNumAndAniLen(aniLen, aniLayer + dlg.outNum);
		}
		break;
	case 2://交换
		step.at(dlg.outSrcLayerNum).rcList.swap(step.at(dlg.outDstLayerNum).rcList);
		break;
	case 3://复制
		step.at(dlg.outDstLayerNum).rcList = step.at(dlg.outSrcLayerNum).rcList;
		break;
	case 4://删除
		{
			std::list<MyAniLayer> tempA(step.begin(), step.end());
			auto iter = tempA.begin();
			for (int i = 0; i < dlg.outSrcLayerNum; i++)
				iter++;
			tempA.erase(iter);
			std::vector<MyAniLayer> tempB(tempA.begin(), tempA.end());
			step = tempB;
			pTimeLineWnd.SetLayerNumAndAniLen(aniLen, aniLayer - 1);
		}
		break;
	}
	UpdateMenuState();//更新菜单状态
	UpdateWindowTitle();//更新窗口标题
	Draw();
}


void CAniEditor::OnHideTable()
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	if (!parentEditor->IsLoaded())
	{
		MessageBoxW(L"必须先载入动画文件", L"未载入动画", MB_ICONINFORMATION);
		return;
	}
	CAniEditorHideTable dlg;
	dlg.outStr = hideTable;
	if (dlg.DoModal() != IDOK)
		return;
	hideTable = dlg.outStr;
	std::vector<int> idList;
	CAniEditorHideTable::ParseInts(hideTable.GetString(), idList);
	hideIDTable.clear();
	for (auto& i : idList)
	{
		if (hideIDTable.find(i) == hideIDTable.end())
			hideIDTable.insert(i);
	}
	UpdateMenuState();//更新菜单状态
	UpdateWindowTitle();//更新窗口标题
	Draw();
}


void CAniEditor::OnChangeId()
{
	auto parentEditor = (CPidEditor*)pParentEditor;
	if (!parentEditor->IsLoaded())
	{
		MessageBoxW(L"必须先载入动画文件", L"未载入动画", MB_ICONINFORMATION);
		return;
	}
	CAniEditorChangeID dlg;
	if (dlg.DoModal() != IDOK)
		return;
	int counter = 0;
	for (auto & pair_aniSet : anisetList)
	{
		auto& aniSet = pair_aniSet.second;
		auto& layerList = *aniSet.GetStep();
		for (auto& layer : layerList)
		{
			for (auto& frame : layer.rcList)
			{
				if (frame.id == dlg.outIDSrc)
				{
					aniSet.undoRedo.BeginStep(CANIEDITOR_DATATYPE_ANI_STR);
					frame.id = dlg.outIDDst;
					counter++;
				}
			}
		}
		aniSet.undoRedo.EndStep();
	}
	CString str;
	str.Format(L"已替换%d个", counter);
	MessageBoxW(str.GetString(), L"替换成功", MB_ICONINFORMATION);
}

