#include "CMapEditor.h"
#include "resource.h"
#include "CMainEditor.h"
#include "CNewMap.h"
#include "CNewLayer.h"
#include "CEntityFlag.h"
#include "CImportCaveStoryPxm.h"
#include "CPidEditorLang.h"
#include "CMoveMap.h"
#include "CWallAdjust.h"
#include "CWaitRecord.h"
IMPLEMENT_DYNAMIC(CMapEditor, CDialog)

BEGIN_MESSAGE_MAP(CMapEditor, CDialog)
	ON_COMMAND(IDOK, &CMapEditor::OnEnterKey)
	ON_WM_SIZE()
	ON_WM_MOVING()
	ON_WM_SIZING()
	ON_WM_SHOWWINDOW()
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_CHECK_MAPLIST, &CMapEditor::OnBnClickedCheckMaplist)
	ON_BN_CLICKED(IDC_CHECK_ENTITYLIST, &CMapEditor::OnBnClickedCheckEntitylist)
	ON_BN_CLICKED(IDC_CHECK_LAYERLIST, &CMapEditor::OnBnClickedCheckLayerlist)
	ON_BN_CLICKED(IDC_CHECK_LIGHT, &CMapEditor::OnBnClickedCheckLight)
	ON_BN_CLICKED(IDC_RADIO_EDITMAP, &CMapEditor::OnBnClickedRadioEditmap)
	ON_BN_CLICKED(IDC_RADIO_EDITENTITY, &CMapEditor::OnBnClickedRadioEditentity)
	ON_BN_CLICKED(IDC_CHECK_FGROUND, &CMapEditor::OnUpdateDraw)
	ON_BN_CLICKED(IDC_CHECK_ENTITY, &CMapEditor::OnUpdateDraw)
	ON_BN_CLICKED(IDC_CHECK_BGROUND, &CMapEditor::OnUpdateDraw)
	ON_BN_CLICKED(IDC_CHECK_ENTITYLABEL, &CMapEditor::OnUpdateDraw)
	ON_BN_CLICKED(IDC_CHECK_BK, &CMapEditor::OnUpdateDraw)
	ON_BN_CLICKED(IDC_CHECK_ENTITYSHOW, &CMapEditor::OnUpdateDraw)
	ON_BN_CLICKED(IDC_CHECK_PXATYPE, &CMapEditor::OnUpdateDraw)
	ON_BN_CLICKED(IDC_CHECK_GRID, &CMapEditor::OnUpdateDraw)
	ON_BN_CLICKED(IDC_RADIO_PAINT, &CMapEditor::OnBnClickedRadioPaint)
	ON_BN_CLICKED(IDC_RADIO_REPLACE, &CMapEditor::OnBnClickedRadioReplace)
	ON_BN_CLICKED(IDC_RADIO_FILL, &CMapEditor::OnBnClickedRadioFill)
	ON_BN_CLICKED(IDC_RADIO_RECT, &CMapEditor::OnBnClickedRadioRect)
	ON_BN_CLICKED(IDC_RADIO_COPY, &CMapEditor::OnBnClickedRadioCopy)
	ON_BN_CLICKED(IDC_RADIO_PASTE, &CMapEditor::OnBnClickedRadioPaste)
	ON_BN_CLICKED(IDC_BUTTON_BRUSHWND, &CMapEditor::OnBnClickedButtonBrushwnd)
	ON_BN_CLICKED(IDC_BUTTON_ENTITYOPTION, &CMapEditor::OnBnClickedButtonEntityoption)
	ON_COMMAND(ID_EDIT_MAP, &CMapEditor::OnEditMap)
	ON_COMMAND(ID_PREP_MAP, &CMapEditor::OnPrepMap)
	ON_COMMAND(ID_SCRIPT_MAP, &CMapEditor::OnScriptMap)
	ON_COMMAND(ID_SCRIPT_DRAWCLICK_MAP, &CMapEditor::OnScriptDrawclickMap)
	ON_COMMAND(ID_COPY_MAP, &CMapEditor::OnCopyMap)
	ON_COMMAND(ID_ADD_MAP, &CMapEditor::OnAddMap)
	ON_COMMAND(ID_DELETE_MAP, &CMapEditor::OnDeleteMap)
	ON_COMMAND(ID_OPEN_FOLDER, &CMapEditor::OnOpenFolder)
	ON_COMMAND(ID_UPDATE_LIST, &CMapEditor::OnUpdateList)
	ON_LBN_DBLCLK(IDC_LIST_MAPLIST, &CMapEditor::OnLbnDblclkListMaplist)
	ON_COMMAND(ID_OPEN_FILE, &CMapEditor::OnOpenFile)
	ON_COMMAND(ID_SAVE_FILE, &CMapEditor::OnSaveFile)
	ON_COMMAND(ID_CLOSE_FILE, &CMapEditor::OnCloseFile)
	ON_COMMAND(ID_UNDO, &CMapEditor::OnUndo)
	ON_COMMAND(ID_REDO, &CMapEditor::OnRedo)
	ON_COMMAND(ID_COPY, &CMapEditor::OnCopy)
	ON_COMMAND(ID_PASTE, &CMapEditor::OnPaste)
	ON_COMMAND(ID_CUT, &CMapEditor::OnCut)
	ON_COMMAND(ID_MOVE_MAP, &CMapEditor::OnMoveMap)
	ON_COMMAND(ID_WALL_ADJUST, &CMapEditor::OnWallAdjust)
	ON_COMMAND(ID_SHOW_BK, &CMapEditor::OnShowBk)
	ON_COMMAND(ID_SHOW_GRID, &CMapEditor::OnShowGrid)
	ON_COMMAND(ID_EDIT_GLOBALSCRIPT, &CMapEditor::OnEditGlobalscript)
	ON_COMMAND(ID_SWITCH_LANGUAGE, &CMapEditor::OnSwitchLanguage)
	ON_COMMAND(ID_IMPORT_CAVESTORY_PXM, &CMapEditor::OnImportCavestoryPxm)
	ON_COMMAND(ID_SCREENSHOT, &CMapEditor::OnScreenshot)
	ON_COMMAND(ID_REFRESH_IMAGE, &CMapEditor::OnRefreshImage)
	ON_LBN_SELCHANGE(IDC_LIST_LAYERLIST, &CMapEditor::OnLbnSelchangeListLayerlist)
	ON_COMMAND(ID_ADD_LAYER, &CMapEditor::OnAddLayer)
	ON_COMMAND(ID_PREP_LAYER, &CMapEditor::OnPrepLayer)
	ON_COMMAND(ID_COPY_LAYER, &CMapEditor::OnCopyLayer)
	ON_COMMAND(ID_PASTE_LAYER, &CMapEditor::OnPasteLayer)
	ON_COMMAND(ID_DELETE_LAYER, &CMapEditor::OnDeleteLayer)
	ON_COMMAND(ID_SHOW_LAYER, &CMapEditor::OnShowLayer)
	ON_COMMAND(ID_HIDEOTHER_LAYER, &CMapEditor::OnHideotherLayer)
	ON_COMMAND(ID_SHOWALL_LAYER, &CMapEditor::OnShowallLayer)
	ON_LBN_DBLCLK(IDC_LIST_LAYERLIST, &CMapEditor::OnLbnDblclkListLayerlist)
	ON_MESSAGE(MYPICBUTTON_LBUTTONUP, &CMapEditor::OnMyPicButtonLButtonUp)
	ON_COMMAND(ID_ADD_ENTITY, &CMapEditor::OnAddEntity)
	ON_COMMAND(ID_DELETE_ENTITY, &CMapEditor::OnDeleteEntity)
	ON_COMMAND(ID_COPY_ENTITY, &CMapEditor::OnCopyEntity)
	ON_COMMAND(ID_PASTE_ENTITY, &CMapEditor::OnPasteEntity)
	ON_COMMAND(ID_TESTPOS, &CMapEditor::OnTestpos)
	ON_COMMAND(ID_SET_RECORD_END_POS, &CMapEditor::OnSetRecordEndPos)
	ON_COMMAND(ID_START_RECORD, &CMapEditor::OnStartRecord)
	ON_EN_CHANGE(IDC_EDIT_ENTITYNAME, &CMapEditor::OnEnChangeEditEntityname)
	ON_EN_CHANGE(IDC_EDIT_ENTITYID, &CMapEditor::OnEnChangeEditEntityid)
	ON_EN_CHANGE(IDC_EDIT_EVENT, &CMapEditor::OnEnChangeEditEvent)
	ON_EN_CHANGE(IDC_EDIT_ARG, &CMapEditor::OnEnChangeEditArg)
	ON_EN_CHANGE(IDC_EDIT_ARG2, &CMapEditor::OnEnChangeEditArg2)
	ON_EN_CHANGE(IDC_EDIT_ARG3, &CMapEditor::OnEnChangeEditArg3)
	ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_ENTITYLIST, &CMapEditor::OnTvnSelchangedTreeEntitylist)
END_MESSAGE_MAP()

CMapEditor::CMapEditor(CWnd* pParent)
	: CDialog(IDD_CMAPEDITOR, pParent)
{
}

CMapEditor::~CMapEditor()
{
}

bool CMapEditor::Light()
{
	return check_light.GetCheck();
}

bool CMapEditor::Grid()
{
	return check_grid.GetCheck();
}

bool CMapEditor::Bk()
{
	return check_bk.GetCheck();
}

bool CMapEditor::Pxa()
{
	return check_pxaType.GetCheck();
}

bool CMapEditor::FGround()
{
	return check_fGround.GetCheck();
}

bool CMapEditor::BGround()
{
	return check_bGround.GetCheck();
}

bool CMapEditor::Entity()
{
	return check_entity.GetCheck();
}

bool CMapEditor::EntityLabel()
{
	return check_entityLabel.GetCheck();
}

bool CMapEditor::EntityShow()
{
	return check_entityShow.GetCheck();
}

bool CMapEditor::IsEditMapMode()
{
	return radio_editMap.GetCheck();
}

bool CMapEditor::IsEditEntityMode()
{
	return radio_editEntity.GetCheck();
}

int CMapEditor::GetPaintMode()
{
	if (radio_paint.GetCheck())
		return 0;
	else if (radio_replace.GetCheck())
		return 1;
	else if (radio_fill.GetCheck())
		return 2;
	else if (radio_rect.GetCheck())
		return 3;
	else if (radio_copy.GetCheck())
		return 4;
	else if (radio_paste.GetCheck())
		return 5;
	return 0;
}

CString CMapEditor::GetMapFileName()
{
	return mapfilename;
}

CMyListBox* CMapEditor::GetMapListBox()
{
	return &list_mapList;
}

bool CMapEditor::Close()
{
	//停止动画播放
	btn_pause.ShowWindow(SW_HIDE);
	btn_play.ShowWindow(SW_SHOW);
	//停止动画播放
	timeCounter = 0;
	windAniIndex = 0;
	windAniIndex2 = 0;
	playing = false;
	pDrawWnd.ResetEntityPlay();
	if (!IsLoaded())
		return false;
	if (!CheckSaved())//如果未保存
	{
		switch (MessageBox(TEXT("想要保存已修改的数据吗？"), TEXT("修改的数据即将丢失"), MB_YESNOCANCEL | MB_ICONWARNING))
		{
		case IDYES:
			Save();
		case IDNO:
			break;
		case IDCANCEL:
			return true;
		}
	}
	ResetContext();
	//锁定界面
	EnableControl(false);
	EnableEdit(false);
	Draw();
	return false;
}

void CMapEditor::Draw()
{
	pDrawWnd.Draw();
	pBrushWnd.Draw();
}

void CMapEditor::Load(CString mapfilename)
{
	this->mapfilename = mapfilename;
	pxmfile.Format(L"./data/map/%s.pxm", mapfilename.GetString());
	mapSet.layerList.clear();
	saved.layerList.clear();
	//载入文件数据
	FILE* fp;
	_wfopen_s(&fp, pxmfile.GetString(), L"rb");
	if (fp)
	{
		fseek(fp, 0, SEEK_END);
		size_t fileLen = ftell(fp);
		fseek(fp, 0, SEEK_SET);
		std::vector<BYTE> cbuff;
		cbuff.resize(fileLen);
		fread_s(cbuff.data(), fileLen, fileLen, 1, fp);
		fclose(fp);
		std::vector<BYTE> byte_buff;
		size_t len = 0;
		ZLibUncompressData(&byte_buff, &len, cbuff.data(), fileLen);
		CString xml = (wchar_t*)byte_buff.data();
		XMLLoad(xml);//读取地图数据
		//赋值
		StepCopyToSaved();
	}
	UpdateMenuState();//更新撤销重做菜单状态
	UpdateWindowTitle();//更新窗口标题
	//启用界面
	EnableControl(true);
	//设置菜单
	list_mapList.ClearDisableMenu();//启用属性编辑菜单
	//设置list_layerList
	list_layerList.SetMenu(IDR_CMAPEDITOR_LAYERLIST_RMENU, IDR_CMAPEDITOR_LAYERLIST_RMENU_NOSEL);
	UpdateLayerList();
	//更新影表
	pDrawWnd.UpdateMapCache();
	UpdateMapCache();
	Draw();
}

void CMapEditor::Save()
{
	StepCopyToSaved();
	CString xml = XMLSaved();//写入pxm数据
	//数据压缩
	std::vector<BYTE> compressData;
	size_t compressData_len;
	ZLibCompressData(&compressData, &compressData_len, xml.GetString(), ((size_t)xml.GetLength() + 1) * sizeof(wchar_t));//加入\0符
	//文件数据写入
	FILE* fp = nullptr;
	_wfopen_s(&fp, pxmfile.GetString(), L"wb+");
	if (!fp)
	{
		CString err;
		err.Format(L"写入%s失败\n文件可能正在被占用", pxmfile.GetString());
		MessageBox(err.GetString(), L"文件写入失败", MB_ICONINFORMATION);
		return;
	}
	fwrite(compressData.data(), compressData_len, 1, fp);
	fclose(fp);
	//更新窗口标题
	UpdateWindowTitle();
	//刷新列表
	OnUpdateList();
}

bool CMapEditor::CheckSaved()
{
	return saved == mapSet;
}

bool CMapEditor::IsLoaded()
{
	return mapfilename.GetLength() > 0;
}

void CMapEditor::ResetContext()
{
	mapfilename = L"";
	pxmfile = L"";
	mapSet.layerList.clear();
	saved.layerList.clear();
	list_mapList.ClearDisableMenu();
	list_mapList.AddDisableMenu(ID_PREP_MAP);
	list_layerList.SetMenu(0, 0);
	list_layerList.ResetContent();
	pDrawWnd.ResetContext();
	pBrushWnd.ResetContext();
	pBrushPreview.ResetContext();
	//更新撤销重做菜单状态
	UpdateMenuState();
	//更新窗口标题
	UpdateWindowTitle();
}

void CMapEditor::UpdateMenuState()
{
	if (IsLoaded())
	{
		MyMapLayer* pLayer = GetSelectLayer();
		if (!pLayer)//如果未选择也禁用所有编辑菜单
			goto CMapEditor_UpdateMenuState_Else;
		auto& undoRedo = pLayer->undoRedo;
		if (undoRedo.UndoEmpty())
			GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_UNDO, MF_DISABLED);
		else
			GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_UNDO, MF_ENABLED);

		if (undoRedo.RedoEmpty())
			GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_REDO, MF_DISABLED);
		else
			GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_REDO, MF_ENABLED);
		auto bCheck = (radio_editEntity.GetCheck() ? MF_ENABLED : MF_DISABLED);
		GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_COPY, bCheck);
		GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_PASTE, bCheck);
		GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_CUT, bCheck);
	}
	else
	{
		CMapEditor_UpdateMenuState_Else:
		GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_COPY, MF_DISABLED);
		GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_PASTE, MF_DISABLED);
		GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_CUT, MF_DISABLED);
		GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_UNDO, MF_DISABLED);
		GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_REDO, MF_DISABLED);
	}
}

void CMapEditor::UpdateWindowTitle()
{
	CString windowTitle, appendStr;
	bool sav = CheckSaved();
	//窗口标题
	appendStr.Format(TEXT("地图编辑器窗口 - "));
	windowTitle.Append(appendStr);
	CString selectLayerName = GetSelectLayerName();
	if (selectLayerName.GetLength() == 0)
		appendStr.Format(TEXT("未选中图层 - "));
	else
		appendStr.Format(TEXT("当前选中图层：%s - "), selectLayerName.GetString());
	if (IsLoaded())
	{
		appendStr.Format(TEXT("已载入文件：%s"), pxmfile.GetString());
		windowTitle.Append(appendStr);
		if (!sav)
			windowTitle.Append(TEXT("(未保存)"));
		else
			windowTitle.Append(TEXT("(已保存)"));
	}
	else
	{
		windowTitle.Append(TEXT("(未载入文件)"));
	}
	auto& drawView = *pDrawWnd.GetMyView();
	appendStr.Format(L" - (%d,%d)", drawView.cursorX, drawView.cursorY);
	windowTitle.Append(appendStr);
	if (pDrawWnd.GetEntityRes()->GetErrorMsg().GetLength() > 0)
	{
		appendStr.Format(L" 错误消息：%s", pDrawWnd.GetEntityRes()->GetErrorMsg().GetString());
		windowTitle.Append(appendStr);
	}
	SetWindowText(windowTitle);
	//图层列表
	for (auto& p : mapSet.layerList)
	{
		//如果找到了主层
		if (p.second.layerType == 0)
		{
			windowTitle.Format(L"图层列表（主图层：%s）",p.first.c_str());
			goto CMapEditor_UpdateWindowTitle_MainLayerSetting;
		}
	}
	windowTitle.Format(L"图层列表（未设置主图层）");
CMapEditor_UpdateWindowTitle_MainLayerSetting:
	static_layerList->SetWindowTextW(windowTitle.GetString());
}

CString CMapEditor::XMLSaved()
{
	//写入xml文件
	tinyxml2::XMLDocument xmlDoc;
	//写入Pxm元素
	auto elem_pxm = xmlDoc.NewElement("Pxm");
	std::vector<char> utf8_buff;
	UTF16ToUTF8(saved.mapName.c_str(), &utf8_buff);
	elem_pxm->SetAttribute("MapName", utf8_buff.data());
	elem_pxm->SetAttribute("MapW", saved.mapW);
	elem_pxm->SetAttribute("MapH", saved.mapH);
	xmlDoc.InsertEndChild(elem_pxm);
	//循环列入地图层数据
	for (auto& p : saved.layerList)
	{
		//写入图层属性
		auto elem_layer = xmlDoc.NewElement("Layer");
		//地形组
		elem_layer->SetAttribute("Visiable", p.second.visible);//图层是否可见
		UTF16ToUTF8(p.first.c_str(), &utf8_buff);
		elem_layer->SetAttribute("Name", utf8_buff.data());//写入图层名
		UTF16ToUTF8(p.second.pxaName.c_str(), &utf8_buff);
		elem_layer->SetAttribute("PxaName", utf8_buff.data());//地形组名
		//图层类型
		elem_layer->SetAttribute("LayerType", p.second.layerType);//图层是否可见
		//图层属性
		elem_layer->SetAttribute("OffX", p.second.offx);//x偏移
		elem_layer->SetAttribute("OffY", p.second.offy);//y偏移
		elem_layer->SetAttribute("Far", p.second.myFar);//距离
		//循环背景层属性
		elem_layer->SetAttribute("LoopH", p.second.loopH);//水平循环显示
		elem_layer->SetAttribute("LoopV", p.second.loopV);//垂直循环显示
		elem_layer->SetAttribute("SpeedH", p.second.speedH);//水平平移速度
		elem_layer->SetAttribute("SpeedV", p.second.speedV);//垂直平移速度
		//通用
		elem_layer->SetAttribute("Order", p.second.order);//图层顺序
		elem_layer->SetAttribute("JumpFrame", p.second.jumpFrame);//帧数跳跃
		//光层
		elem_layer->SetAttribute("DayLight", p.second.dayLight);//天光
		elem_layer->SetAttribute("tinyHSV_H", p.second.tinyHSV[0]);//细微HSV调整
		elem_layer->SetAttribute("tinyHSV_S", p.second.tinyHSV[1]);//细微HSV调整
		elem_layer->SetAttribute("tinyHSV_V", p.second.tinyHSV[2]);//细微HSV调整
		elem_layer->SetAttribute("LightConst", p.second.lightConst);//收到来自其他层的光线影响比例
		//颜色调整
		elem_layer->SetAttribute("Color", (UINT64)p.second.color);//混合颜色
		//绘制剪切区域
		elem_layer->SetAttribute("EnableClipZone", p.second.enableClipZone);//启用绘制剪切区域
		elem_layer->SetAttribute("ClipUp", p.second.clipZone.top);//剪切区域上
		elem_layer->SetAttribute("ClipDown", p.second.clipZone.bottom);//剪切区域下
		elem_layer->SetAttribute("ClipLeft", p.second.clipZone.left);//剪切区域左
		elem_layer->SetAttribute("ClipRight", p.second.clipZone.right);//剪切区域右
		elem_pxm->InsertEndChild(elem_layer);
		//写入瓦片数据
		auto& step_pxm = *p.second.GetPxmStep();
		auto& step_pxe = *p.second.GetPxeStep();
		for (auto& t : step_pxm)
		{
			int pxmX = LOWORD(t.first);
			int pxmY = HIWORD(t.first);
			int pxaX = LOWORD(t.second);
			int pxaY = HIWORD(t.second);
			if (p.second.layerType != 2 && 
				pxaX == 0 && pxaY == 0)
				continue;
			auto elem_id = xmlDoc.NewElement("ID");
			elem_id->SetAttribute("pxmX", pxmX);
			elem_id->SetAttribute("pxmY", pxmY);
			elem_id->SetAttribute("pxaX", pxaX);
			elem_id->SetAttribute("pxaY", pxaY);
			elem_layer->InsertEndChild(elem_id);
		}
		//写入实体数据
		for (auto& t : step_pxe)
		{
			EntityLoad& entityLoad = t.second;
			auto elem_ent = xmlDoc.NewElement("ENT");
			UTF16ToUTF8(entityLoad.name.c_str(), &utf8_buff);
			elem_ent->SetAttribute("name", utf8_buff.data());
			elem_ent->SetAttribute("x", entityLoad.x);
			elem_ent->SetAttribute("y", entityLoad.y);
			UTF16ToUTF8(entityLoad.eid.c_str(), &utf8_buff);
			elem_ent->SetAttribute("eid", utf8_buff.data());
			UTF16ToUTF8(entityLoad.eventName.c_str(), &utf8_buff);
			elem_ent->SetAttribute("event", utf8_buff.data());
			UTF16ToUTF8(entityLoad.arg.c_str(), &utf8_buff);
			elem_ent->SetAttribute("arg", utf8_buff.data());
			UTF16ToUTF8(entityLoad.arg2.c_str(), &utf8_buff);
			elem_ent->SetAttribute("arg2", utf8_buff.data());
			UTF16ToUTF8(entityLoad.arg3.c_str(), &utf8_buff);
			elem_ent->SetAttribute("arg3", utf8_buff.data());
			auto& flag = entityLoad.flag;
			elem_ent->SetAttribute("tCheck", flag.tCheck);
			elem_ent->SetAttribute("tTouch", flag.tTouch);
			elem_ent->SetAttribute("tDeath", flag.tDeath);
			elem_ent->SetAttribute("tCrush", flag.tCrush);
			elem_ent->SetAttribute("tHurt", flag.tHurt);
			elem_ent->SetAttribute("tDamage", flag.tDamage);
			elem_ent->SetAttribute("fShow", flag.fShow);
			elem_ent->SetAttribute("fHide", flag.fHide);
			elem_ent->SetAttribute("skShow", flag.skShow);
			elem_ent->SetAttribute("skHide", flag.skHide);
			elem_ent->SetAttribute("d0Show", flag.d0Show);
			elem_ent->SetAttribute("d0Hide", flag.d0Hide);
			elem_ent->SetAttribute("d1Show", flag.d1Show);
			elem_ent->SetAttribute("d1Hide", flag.d1Hide);
			elem_ent->SetAttribute("lr", flag.lr);
			elem_ent->SetAttribute("text", flag.text);
			elem_ent->SetAttribute("save", flag.save);
			elem_ent->SetAttribute("simpAni", flag.simpAni);
			elem_layer->InsertEndChild(elem_ent);
		}
	}
	//写出到文件
	tinyxml2::XMLPrinter xmlPrinter;
	xmlDoc.Print(&xmlPrinter);
	std::vector<wchar_t> wchar_buff;
	UTF8ToUTF16(xmlPrinter.CStr(), &wchar_buff);
	CString allData = wchar_buff.data();
	return allData;
}

void* CMapEditor_Pxm_NewData()
{
	return new CMAPEDITOR_DATATYPE_PXM();
}
void* CMapEditor_Pxm_NewCopyOfData(void* data)
{
	CMAPEDITOR_DATATYPE_PXM* pStep = (CMAPEDITOR_DATATYPE_PXM*)data;
	CMAPEDITOR_DATATYPE_PXM* pNewStep = new CMAPEDITOR_DATATYPE_PXM();
	*pNewStep = *pStep;
	return pNewStep;
}
void CMapEditor_Pxm_ReleaseData(void* data)
{
	CMAPEDITOR_DATATYPE_PXM* pStep = (CMAPEDITOR_DATATYPE_PXM*)data;
	delete pStep;
}

void* CMapEditor_Pxe_NewData()
{
	return new CMAPEDITOR_DATATYPE_PXE();
}
void* CMapEditor_Pxe_NewCopyOfData(void* data)
{
	CMAPEDITOR_DATATYPE_PXE* pStep = (CMAPEDITOR_DATATYPE_PXE*)data;
	CMAPEDITOR_DATATYPE_PXE* pNewStep = new CMAPEDITOR_DATATYPE_PXE();
	*pNewStep = *pStep;
	return pNewStep;
}
void CMapEditor_Pxe_ReleaseData(void* data)
{
	CMAPEDITOR_DATATYPE_PXE* pStep = (CMAPEDITOR_DATATYPE_PXE*)data;
	delete pStep;
}

void CMapEditor::XMLLoad(CString xml)
{
	std::vector<char> xml_utf8;
	UTF16ToUTF8(xml.GetString(), &xml_utf8);
	tinyxml2::XMLDocument xmlDoc;
	xmlDoc.Parse(xml_utf8.data());
	tinyxml2::XMLElement* elem = nullptr;
	//寻找Pxm元素
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "Pxm"))
		{
			elem = pElem;
			break;
		}	
	}
	if (!elem)
	{
		CString err;
		err.Format(L"文件%s找不到Pxm元素", pxmfile.GetString());
		MessageBox(err.GetString(), L"文件载入错误", MB_ICONWARNING);
		return;
	}
	mapSet.layerList.clear();
	//读取地图数据
	CString layerName;
	std::vector<wchar_t> wchar_buff;
	UTF8ToUTF16(elem->Attribute("MapName"), &wchar_buff);
	mapSet.mapName = wchar_buff.data();
	mapSet.mapW = elem->IntAttribute("MapW");
	mapSet.mapH = elem->IntAttribute("MapH");
	//遍历所有Layer元素
	for (auto p = elem->FirstChildElement(); p; p = p->NextSiblingElement())
	{
		//跳过不是Layer的元素
		if (strcmp(p->Name(), "Layer"))
			continue;
		MyMapLayer layer;
		//设置Pxm撤销重做功能
		MyUndoRedoDataOp op_pxm;
		op_pxm.NewData = CMapEditor_Pxm_NewData;
		op_pxm.NewCopyOfData = CMapEditor_Pxm_NewCopyOfData;
		op_pxm.ReleaseData = CMapEditor_Pxm_ReleaseData;
		layer.undoRedo.AddDataType(CMAPEDITOR_DATATYPE_PXM_STR, op_pxm);
		//设置Pxe撤销重做功能
		MyUndoRedoDataOp op_pxe;
		op_pxe.NewData = CMapEditor_Pxe_NewData;
		op_pxe.NewCopyOfData = CMapEditor_Pxe_NewCopyOfData;
		op_pxe.ReleaseData = CMapEditor_Pxe_ReleaseData;
		layer.undoRedo.AddDataType(CMAPEDITOR_DATATYPE_PXE_STR, op_pxe);
		//地形组
		layer.visible = p->BoolAttribute("Visiable");
		UTF8ToUTF16(p->Attribute("Name"), &wchar_buff);//读取图层名
		layerName = wchar_buff.data();
		UTF8ToUTF16(p->Attribute("PxaName"), &wchar_buff);//读取地形组
		layer.pxaName = wchar_buff.data();
		//图层类型
		layer.layerType = p->IntAttribute("LayerType");
		//图层属性
		layer.offx = p->FloatAttribute("OffX");//x偏移
		layer.offy = p->FloatAttribute("OffY");//y偏移
		layer.myFar = p->FloatAttribute("Far");//距离
		//循环背景层属性
		layer.loopH = p->BoolAttribute("LoopH");//水平循环显示
		layer.loopV = p->BoolAttribute("LoopV");//垂直循环显示
		layer.speedH = p->FloatAttribute("SpeedH");//水平平移速度
		layer.speedV = p->FloatAttribute("SpeedV");//垂直平移速度
		//通用
		layer.order = p->FloatAttribute("Order");//图层顺序
		layer.jumpFrame_counter = layer.jumpFrame = p->IntAttribute("JumpFrame");//帧数跳跃
		//光层
		layer.dayLight = p->FloatAttribute("DayLight", 1.0f);//天光
		layer.tinyHSV[0] = p->FloatAttribute("tinyHSV_H", 0.0f);//细微HSV调整
		layer.tinyHSV[1] = p->FloatAttribute("tinyHSV_S", 0.0f);//细微HSV调整
		layer.tinyHSV[2] = p->FloatAttribute("tinyHSV_V", 0.0f);//细微HSV调整
		layer.lightConst = p->FloatAttribute("LightConst", 1.0f);//收到来自其他层的光线影响比例
		//颜色调整
		layer.color = (DWORD)p->Unsigned64Attribute("Color");//混合颜色
		//绘制剪切区域
		layer.enableClipZone = p->BoolAttribute("EnableClipZone");//启用绘制剪切区域
		layer.clipZone.top = p->FloatAttribute("ClipUp");//剪切区域上
		layer.clipZone.bottom = p->FloatAttribute("ClipDown");//剪切区域上
		layer.clipZone.left = p->FloatAttribute("ClipLeft");//剪切区域上
		layer.clipZone.right = p->FloatAttribute("ClipRight");//剪切区域上
		auto& step_pxm = *layer.GetPxmStep();
		auto& step_pxe = *layer.GetPxeStep();
		//遍历ID元素
		for (auto t = p->FirstChildElement(); t != nullptr; t = t->NextSiblingElement())
		{
			//如果是ID元素
			if (!strcmp(t->Name(), "ID"))
			{
				int pxmX = t->IntAttribute("pxmX");
				int pxmY = t->IntAttribute("pxmY");
				int pxaX = t->IntAttribute("pxaX");
				int pxaY = t->IntAttribute("pxaY");
				step_pxm.insert(std::make_pair(MAKELONG(pxmX, pxmY), MAKELONG(pxaX, pxaY)));
			}
			//如果是ENT元素
			else if (!strcmp(t->Name(), "ENT"))
			{
				EntityLoad entityLoad;
				UTF8ToUTF16(t->Attribute("name"), &wchar_buff);
				entityLoad.name = wchar_buff.data();
				entityLoad.x = t->IntAttribute("x");
				entityLoad.y = t->IntAttribute("y");
				UTF8ToUTF16(t->Attribute("eid"), &wchar_buff);
				entityLoad.eid = wchar_buff.data();
				UTF8ToUTF16(t->Attribute("event"), &wchar_buff);
				entityLoad.eventName = wchar_buff.data();
				wchar_buff.resize(1);
				wchar_buff[0] = 0;
				UTF8ToUTF16(t->Attribute("arg"), &wchar_buff);
				entityLoad.arg = wchar_buff.data();
				wchar_buff.resize(1);
				wchar_buff[0] = 0;
				UTF8ToUTF16(t->Attribute("arg2"), &wchar_buff);
				entityLoad.arg2 = wchar_buff.data();
				wchar_buff.resize(1);
				wchar_buff[0] = 0;
				UTF8ToUTF16(t->Attribute("arg3"), &wchar_buff);
				entityLoad.arg3 = wchar_buff.data();
				auto& flag = entityLoad.flag;
				flag.tCheck = t->BoolAttribute("tCheck");
				flag.tTouch = t->BoolAttribute("tTouch");
				flag.tDeath = t->BoolAttribute("tDeath");
				flag.tCrush = t->BoolAttribute("tCrush");
				flag.tHurt = t->BoolAttribute("tHurt");
				flag.tDamage = t->BoolAttribute("tDamage");
				flag.fShow = t->BoolAttribute("fShow");
				flag.fHide = t->BoolAttribute("fHide");
				flag.skShow = t->BoolAttribute("skShow");
				flag.skHide = t->BoolAttribute("skHide");
				flag.d0Show = t->BoolAttribute("d0Show");
				flag.d0Hide = t->BoolAttribute("d0Hide");
				flag.d1Show = t->BoolAttribute("d1Show");
				flag.d1Hide = t->BoolAttribute("d1Hide");
				flag.lr = t->BoolAttribute("lr");
				flag.text = t->BoolAttribute("text");
				flag.save = t->BoolAttribute("save");
				flag.simpAni = t->BoolAttribute("simpAni");
				step_pxe.insert(std::make_pair(layer.nextPxeID, entityLoad));
				layer.nextPxeID++;
			}
		}
		//更新到数组的版本
		layer.UpdatePxmArr(pDrawWnd.GetPxa(layer.pxaName.c_str())->pxaArr_w);
		mapSet.layerList.insert(std::make_pair(layerName.GetString(), layer));
	}
}

CString CMapEditor::LayerListNameToLayerName(CString listName)
{
	int lStart = listName.Find(L'.', 0) + 1;
	int rStart = listName.ReverseFind(L'*');
	if (rStart < 0)
		rStart = listName.GetLength();
	CString str = listName.Left(rStart);
	str = str.Mid(lStart);
	return str;
}

void CMapEditor::UpdateLayerList(CString setSel)
{
	//保存选择
	int sel = list_layerList.GetCurSel();
	CString text;
	if (sel >= 0)
		list_layerList.GetText(sel, text);
	CString selStr;
	if (text.GetLength() > 0)
		selStr = LayerListNameToLayerName(text);
	//重置列表
	mtx.lock();//开始更新drawLayer
	drawLayer.clear();
	list_layerList.ResetContent();
	std::priority_queue<MyMapLayer> sortList;
	std::unordered_map<std::wstring, std::wstring> layerNameList;
	//排序
	for (auto& p : mapSet.layerList)
	{
		MyMapLayer& layer = p.second;
		layer.tempLayerName = p.first;
		sortList.push(layer);
	}
	//插入
	while (!sortList.empty())
	{
		MyMapLayer layer = sortList.top();
		CString text;
		text.Format(L"%d.%s", list_layerList.GetCount(), layer.tempLayerName.c_str());
		if (!layer.visible)
			text.Append(L"*");
		list_layerList.AddString(text.GetString());
		layerNameList.insert(std::make_pair(layer.tempLayerName, text.GetString()));
		drawLayer.push_front(&mapSet.layerList.at(layer.tempLayerName));
		sortList.pop();
	}
	mtx.unlock();//结束更新drawLayer
	bool cancelSel = true;
	//恢复选择
	if (selStr.GetLength() > 0)
	{
		if (layerNameList.find(selStr.GetString()) != layerNameList.end())
		{
			text = layerNameList.at(selStr.GetString()).c_str();
			int index = list_layerList.FindString(0, text.GetString());
			list_layerList.SetCurSel(index);
			cancelSel = false;
		}
	}
	else if (setSel.GetLength() > 0 &&
		layerNameList.find(setSel.GetString()) != layerNameList.end())
	{
		text = layerNameList.at(setSel.GetString()).c_str();
		int index = list_layerList.FindString(0, text.GetString());
		list_layerList.SetCurSel(index);
		cancelSel = false;
	}
	if (cancelSel)
		EnableEdit(false);//取消选择
}

MyMapLayer* CMapEditor::GetSelectLayer()
{
	int sel = list_layerList.GetCurSel();
	if (sel < 0)
		return nullptr;
	CString text;
	list_layerList.GetText(sel, text);
	CString layerName = LayerListNameToLayerName(text);
	MyMapLayer& layer = mapSet.layerList.at(layerName.GetString());
	layer.tempLayerName = layerName;
	return &layer;
}

void CMapEditor::ResetWindowPos()
{
	CRect rcDst, rcSrc;
	GetWindowRect(rcDst);
	pBrushWnd.GetWindowRect(rcSrc);
	MoveToNeighborRect(rcDst, rcSrc, 1, 1);
	auto dpi = MyGetDPI();
	::MoveWindow(&pBrushWnd, rcSrc.left, rcSrc.top + DPISCALE(50));
}

void CMapEditor::SelectToEntity()
{
	auto pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	if (pLayer->selected_entity < 0)
		return;
	auto& step_pxe = *pLayer->GetPxeStep();
	auto iter = step_pxe.find(pLayer->selected_entity);
	if (iter == step_pxe.end())
		return;
	//把实体信息填入控件中
	EnableEntityEdit(true);
	EntityLoad& el = iter->second;
	edit_entityName.SetWindowTextW(el.name.c_str());//实体类型
	edit_entityID.SetWindowTextW(el.eid.c_str());//实体号
	edit_event.SetWindowTextW(el.eventName.c_str());//事件
	edit_arg.SetWindowTextW(el.arg.c_str());//参数
	edit_arg2.SetWindowTextW(el.arg2.c_str());//参数
	edit_arg3.SetWindowTextW(el.arg3.c_str());//参数
	CString str;
	str.Format(L"信息 - 编辑器id：%d", pLayer->selected_entity);
	static_info->SetWindowText(str);
	pLayer->undoRedo.EndStep();
	UpdateMenuState();
	UpdateWindowTitle();
}

void CMapEditor::SelectOutEntity()
{
	auto pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	if (pLayer->selected_entity < 0)
		return;
	EnableEntityEdit(false);
	static_info->SetWindowText(L"信息");
	pLayer->selected_entity = -1;
	pLayer->undoRedo.EndStep();
	UpdateMenuState();
	UpdateWindowTitle();
}

void CMapEditor::UpdateMapCache()
{
	for (auto& p : mapSet.layerList)
		p.second.UpdatePxmArr(pDrawWnd.GetPxa(p.second.pxaName.c_str())->pxaArr_w);
}

BOOL CMapEditor::PreTranslateMessage(MSG* pMsg)
{
	CPoint pt;
	GetCursorPos(&pt);
	ScreenToClient(&pt);
	
	CRect rc;
	pDrawWnd.GetWindowRect(&rc);
	ScreenToClient(&rc);

	if (rc.PtInRect(pt))
	{
		HOTKEYPROC;
	}
	else
	{
		if (TranslateAccelerator(GetSafeHwnd(), hAccel_Save, pMsg))
			return TRUE;
		return CDialog::PreTranslateMessage(pMsg);
	}
}

void CMapEditor::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//地图列表
	static_mapList = (CStatic*)GetDlgItem(IDC_STATIC_MAPLIST);
	DDX_Control(pDX, IDC_LIST_MAPLIST, list_mapList);
	//列表
	static_listOP = (CStatic*)GetDlgItem(IDC_STATIC_LISTOP);
	DDX_Control(pDX, IDC_CHECK_MAPLIST, check_mapList);
	DDX_Control(pDX, IDC_CHECK_ENTITYLIST, check_entityList);
	DDX_Control(pDX, IDC_CHECK_LAYERLIST, check_layerList);
	//全局
	static_light = (CStatic*)GetDlgItem(IDC_STATIC_GLOBAL);
	DDX_Control(pDX, IDC_CHECK_LIGHT, check_light);
	//显示
	static_display = (CStatic*)GetDlgItem(IDC_STATIC_DISPLAY);
	DDX_Control(pDX, IDC_RADIO_EDITMAP, radio_editMap);
	DDX_Control(pDX, IDC_RADIO_EDITENTITY, radio_editEntity);
	DDX_Control(pDX, IDC_CHECK_FGROUND, check_fGround);
	DDX_Control(pDX, IDC_CHECK_ENTITY, check_entity);
	DDX_Control(pDX, IDC_CHECK_BGROUND, check_bGround);
	DDX_Control(pDX, IDC_CHECK_ENTITYLABEL, check_entityLabel);
	DDX_Control(pDX, IDC_CHECK_BK, check_bk);
	DDX_Control(pDX, IDC_CHECK_ENTITYSHOW, check_entityShow);
	DDX_Control(pDX, IDC_CHECK_PXATYPE, check_pxaType);
	DDX_Control(pDX, IDC_CHECK_GRID, check_grid);
	//信息
	static_info = (CStatic*)GetDlgItem(IDC_STATIC_INFO);
	DDX_Control(pDX, IDC_RADIO_PAINT, radio_paint);
	DDX_Control(pDX, IDC_RADIO_REPLACE, radio_replace);
	DDX_Control(pDX, IDC_RADIO_FILL, radio_fill);
	DDX_Control(pDX, IDC_RADIO_RECT, radio_rect);
	DDX_Control(pDX, IDC_RADIO_COPY, radio_copy);
	DDX_Control(pDX, IDC_RADIO_PASTE, radio_paste);
	DDX_Control(pDX, IDC_BUTTON_BRUSHWND, button_brushWnd);
	//实体信息
	static_entityType = (CStatic*)GetDlgItem(IDC_STATIC_ENTITYTYPE);
	DDX_Control(pDX, IDC_EDIT_ENTITYNAME, edit_entityName);
	static_entityID = (CStatic*)GetDlgItem(IDC_STATIC_ENTITYID);
	DDX_Control(pDX, IDC_EDIT_ENTITYID, edit_entityID);
	static_entityOption = (CStatic*)GetDlgItem(IDC_STATIC_ENTITYOPTION);
	DDX_Control(pDX, IDC_BUTTON_ENTITYOPTION, button_entityOption);
	static_event = (CStatic*)GetDlgItem(IDC_STATIC_EVENT);
	DDX_Control(pDX, IDC_EDIT_EVENT, edit_event);
	static_arg = (CStatic*)GetDlgItem(IDC_STATIC_ARG);
	DDX_Control(pDX, IDC_EDIT_ARG, edit_arg);
	static_arg2 = (CStatic*)GetDlgItem(IDC_STATIC_ARG2);
	DDX_Control(pDX, IDC_EDIT_ARG2, edit_arg2);
	static_arg3 = (CStatic*)GetDlgItem(IDC_STATIC_ARG3);
	DDX_Control(pDX, IDC_EDIT_ARG3, edit_arg3);
	//实体列表
	static_entityList = (CStatic*)GetDlgItem(IDC_STATIC_ENTITYLIST);
	DDX_Control(pDX, IDC_TREE_ENTITYLIST, tree_entityList);
	//图层列表
	static_layerList = (CStatic*)GetDlgItem(IDC_STATIC_LAYERLIST);
	DDX_Control(pDX, IDC_LIST_LAYERLIST, list_layerList);
}

void MapListOnRButtonDown(CString selectedItemText, CWnd* parentWnd)
{
	CMapEditor* _this = (CMapEditor*)parentWnd;
	if (!_this->IsLoaded())
		return;
	if (selectedItemText != _this->GetMapFileName())
	{
		_this->GetMapListBox()->ClearDisableMenu();
		_this->GetMapListBox()->AddDisableMenu(ID_PREP_MAP);
	}
	else
	{
		_this->GetMapListBox()->ClearDisableMenu();
	}
}

BOOL CMapEditor::OnInitDialog()
{
	CDialog::OnInitDialog();
	//载入快捷键
	LOADHOTKEY(IDR_ACC_MAPEDITOR);
	hAccel_Save = ::LoadAccelerators(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDR_ACC_MAPEDITOR_SAVE));
	//设置应用程序图标
	auto hIcon = AfxGetApp()->LoadIcon(IDI_ICON_PXM);
	SetIcon(hIcon, true);
	//初始化子窗口
	pDrawWnd.pParentEditor = this;
	pDrawWnd.pBrushView = pBrushWnd.GetMyView();
	pDrawWnd.pTimeCounter = &timeCounter;
	pDrawWnd.pWindAniIndex = &windAniIndex;
	pDrawWnd.pWindAniIndex2 = &windAniIndex2;
	pDrawWnd.pMapW = &mapSet.mapW;
	pDrawWnd.pMapH = &mapSet.mapH;
	pDrawWnd.pDrawLayer = &drawLayer;
	pDrawWnd.pMtx = &mtx;
	pDrawWnd.pPlaying = &playing;
	pDrawWnd.pDragEntity = &dragEntity;
	pDrawWnd.pRecordEndPos_x = &recordEndPos_x;
	pDrawWnd.pRecordEndPos_y = &recordEndPos_y;
	pDrawWnd.Create(IDD_CMAPEDITOR_DRAW, this);
	pDrawWnd.ShowWindow(SW_SHOW);
	pBrushWnd.pParentEditor = this;
	pBrushWnd.pDrawView = pDrawWnd.GetMyView();
	pBrushWnd.pPreviewWnd = &pBrushPreview;
	pBrushWnd.Create(IDD_CMAPEDITOR_BRUSH, this);
	pBrushPreview.pBrushView = pBrushWnd.GetMyView();
	pBrushPreview.Create(IDD_CBRUSHPREVIEW, this);
	pBrushPreview.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);
	//设置list_mapList
	list_mapList.SetMenu(IDR_CMAPEDITOR_MAPLIST_RMENU, IDR_CMAPEDITOR_MAPLIST_RMENU_NOSEL);
	list_mapList.AddDisableMenu(ID_PREP_MAP);
	list_mapList.MyOnRButtonDown = MapListOnRButtonDown;
	//设置tree_entityList
	auto style = tree_entityList.GetStyle();
	style |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT;
	tree_entityList.ModifyStyle(0, style);
	//设置控件初始状态
	check_mapList.SetCheck(true);
	check_entityList.SetCheck(true);
	check_layerList.SetCheck(true);
	check_light.SetCheck(true);
	radio_paint.SetCheck(true);
	check_fGround.SetCheck(true);
	check_bGround.SetCheck(true);
	check_entity.SetCheck(true);
	check_entityLabel.SetCheck(true);
	check_entityShow.SetCheck(true);
	OnShowBk();//默认打开显示透明背景
	//默认选中编辑实体
	radio_editEntity.SetCheck(true);
	OnBnClickedRadioEditentity();
	//更新列表
	OnUpdateList();
	//更新实体列表
	RefreshEntityList();
	//锁定控件
	EnableControl(false);
	//重置笔刷窗口位置
	ResetWindowPos();
	//计时器
	timeid = SetTimer(1, 15, nullptr);
	return 0;
}

void CMapEditor::OnCancel()
{
	if (Close())
		return;
	ShowWindow(SW_HIDE);
}

BOOL CMapEditor::OnCommand(WPARAM wParam, LPARAM lParam)
{
	if (lParam == 0 && wParam >= 2000 && wParam < 3000)//from right-click contex menu
	{
		auto layer = GetSelectLayer();
		if (layer)
		{
			layer->selected_entity = (int)wParam - 2000;
			SelectToEntity();
		}
	}
	return CDialog::OnCommand(wParam, lParam);
}

void CMapEditor::OnEnterKey()
{
}

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

	// TODO: 在此处添加消息处理程序代码
	if (!static_mapList)
		return;
	auto dpi = MyGetDPI();
	//按钮
	int buttonOffx = DPISCALE(350);
	int buttonOffy = DPISCALE(14);
	btn_play.SetWindowPos(nullptr, buttonOffx, buttonOffy, DPISCALE(64), DPISCALE(36), SWP_NOZORDER);
	btn_pause.SetWindowPos(nullptr, buttonOffx, buttonOffy, DPISCALE(64), DPISCALE(36), SWP_NOZORDER);
	buttonOffx += DPISCALE(64);
	btn_stop.SetWindowPos(nullptr, buttonOffx, buttonOffy, DPISCALE(64), DPISCALE(36), SWP_NOZORDER);
	buttonOffx += DPISCALE(64);
	btn_refresh.SetWindowPos(nullptr, buttonOffx, buttonOffy, DPISCALE(64), DPISCALE(36), SWP_NOZORDER);
	bool bShowMapList = check_mapList.GetCheck();
	bool bShowEntityList = check_entityList.GetCheck();
	bool bShowLayerList = check_layerList.GetCheck();
	//地图列表
	int x, y, w, h;
	int offx = 0;
	if (bShowMapList || bShowLayerList)
	{
		offx = DPISCALE(210);
		//如果显示了地图列表和图层列表中任何一个
		if (bShowMapList && !bShowLayerList)
		{
			//只显示地图列表
			//地图列表
			x = DPISCALE(10);
			y = DPISCALE(50);
			w = DPISCALE(200);
			h = cy - y - DPISCALE(10);
			static_mapList->MoveWindow(x, y, w, h);
			y += DPISCALE(20);
			h -= DPISCALE(20);
			list_mapList.MoveWindow(x, y, w, h);
		}
		else if(!bShowMapList && bShowLayerList)
		{
			//只显示图层列表
			x = DPISCALE(10);
			y = DPISCALE(50);
			w = DPISCALE(200);
			h = cy - y - DPISCALE(10);
			static_layerList->MoveWindow(x, y, w, h);
			y += DPISCALE(20);
			h -= DPISCALE(20);
			list_layerList.MoveWindow(x, y, w, h);
		}
		else//都显示
		{
			//地图列表
			x = DPISCALE(10);
			y = DPISCALE(50);
			w = DPISCALE(200);
			h = (cy - y - DPISCALE(10)) / 2;
			static_mapList->MoveWindow(x, y, w, h);
			y += DPISCALE(20);
			h -= DPISCALE(20);
			list_mapList.MoveWindow(x, y, w, h);
			//图层列表
			y += h;
			h = cy - h - DPISCALE(80);
			static_layerList->MoveWindow(x, y, w, h);
			y += DPISCALE(20);
			h -= DPISCALE(20);
			list_layerList.MoveWindow(x, y, w, h);
		}
	}
	if (bShowEntityList)
	{
		//实体列表
		y = DPISCALE(50);
		w = DPISCALE(200);
		h = cy - y - DPISCALE(10);
		x = cx - w - DPISCALE(10);
		static_entityList->MoveWindow(x, y, w, h);
		y += DPISCALE(20);
		h -= DPISCALE(20);
		tree_entityList.MoveWindow(x, y, w, h);
		CRect rc;
		tree_entityList.GetClientRect(&rc);
		tree_entityList.InvalidateRect(&rc);
	}
	//列表
	x = DPISCALE(10);
	y = DPISCALE(10);
	w = DPISCALE(250);
	h = DPISCALE(40);
	static_listOP->MoveWindow(x, y, w, h);
	x += DPISCALE(10);
	y += DPISCALE(15);
	w = DPISCALE(70);
	h = DPISCALE(20);
	check_mapList.MoveWindow(x, y, w, h);
	x += w + DPISCALE(10);
	check_layerList.MoveWindow(x, y, w, h);
	x += w + DPISCALE(10);
	check_entityList.MoveWindow(x, y, w, h);
	//全局
	x = DPISCALE(270);
	y = DPISCALE(10);
	h = DPISCALE(40);
	static_light->MoveWindow(x, y, w, h);
	x += DPISCALE(10);
	y += DPISCALE(15);
	w = DPISCALE(50);
	h = DPISCALE(20);
	check_light.MoveWindow(x, y, w, h);
	//显示
	x = DPISCALE(10) + offx;
	y = DPISCALE(50);
	w = DPISCALE(170);
	h = DPISCALE(120);
	static_display->MoveWindow(x, y, w, h);
	x += DPISCALE(10);
	y += DPISCALE(15);
	w = DPISCALE(70);
	h = DPISCALE(20);
	radio_editMap.MoveWindow(x, y, w, h);
	x += w + DPISCALE(10);
	radio_editEntity.MoveWindow(x, y, w, h);
	x = DPISCALE(10) + offx;
	x += DPISCALE(10);
	y += h;
	check_fGround.MoveWindow(x, y, w, h);
	x += w + DPISCALE(10);
	check_entity.MoveWindow(x, y, w, h);
	x = DPISCALE(10) + offx;
	x += DPISCALE(10);
	y += h;
	check_bGround.MoveWindow(x, y, w, h);
	x += w + DPISCALE(10);
	check_entityLabel.MoveWindow(x, y, w, h);
	x = DPISCALE(10) + offx;
	x += DPISCALE(10);
	y += h;
	check_bk.MoveWindow(x, y, w, h);
	x += w + DPISCALE(10);
	check_entityShow.MoveWindow(x, y, w, h);
	x = DPISCALE(10) + offx;
	x += DPISCALE(10);
	y += h;
	check_pxaType.MoveWindow(x, y, w, h);
	x += w + DPISCALE(10);
	check_grid.MoveWindow(x, y, w, h);
	//信息
	x = DPISCALE(190) + offx;
	y = DPISCALE(50);
	w = DPISCALE(500);
	h = DPISCALE(120);
	static_info->MoveWindow(x, y, w, h);
	x += DPISCALE(10);
	y += DPISCALE(20);
	w = DPISCALE(50);
	h = DPISCALE(20);
	radio_paint.MoveWindow(x, y, w, h);
	x += w + DPISCALE(10);
	radio_replace.MoveWindow(x, y, w, h);
	x = DPISCALE(190) + offx;
	x += DPISCALE(10);
	y += h;
	radio_fill.MoveWindow(x, y, w, h);
	x += w + DPISCALE(10);
	radio_rect.MoveWindow(x, y, w, h);
	x = DPISCALE(190) + offx;
	x += DPISCALE(10);
	y += h;
	radio_copy.MoveWindow(x, y, w, h);
	x += w + DPISCALE(10);
	radio_paste.MoveWindow(x, y, w, h);
	x = DPISCALE(190) + offx;
	x += DPISCALE(10);
	y += h;
	w = DPISCALE(110);
	h = DPISCALE(30);
	button_brushWnd.MoveWindow(x, y, w, h);
	x = DPISCALE(320) + offx;
	y = DPISCALE(70);
	w = DPISCALE(160);
	h = DPISCALE(90);
	pBrushPreview.MoveWindow(x, y, w, h);
	//实体信息
	x = DPISCALE(190) + offx;
	y = DPISCALE(50);
	x += DPISCALE(10);
	y += DPISCALE(25);
	w = DPISCALE(30);
	h = DPISCALE(20);
	static_entityType->MoveWindow(x, y, w, h);
	x += w;
	y -= DPISCALE(3);
	w = DPISCALE(250);
	h = DPISCALE(22);
	edit_entityName.MoveWindow(x, y, w, h);
	x = DPISCALE(190) + offx;
	x += DPISCALE(10);
	y += DPISCALE(40);
	w = DPISCALE(40);
	h = DPISCALE(20);
	static_entityID->MoveWindow(x, y, w, h);
	x += w + DPISCALE(5);
	y -= DPISCALE(2);
	w = DPISCALE(115);
	h = DPISCALE(22);
	edit_entityID.MoveWindow(x, y, w, h);
	x += w + DPISCALE(5);
	y += DPISCALE(2);
	static_entityOption->MoveWindow(x, y, w, h);
	x += DPISCALE(30);
	y -= DPISCALE(5);
	h = DPISCALE(30);
	w = DPISCALE(85);
	button_entityOption.MoveWindow(x, y, w, h);
	x = DPISCALE(190) + offx;
	x += DPISCALE(10);
	y += DPISCALE(38);
	w = DPISCALE(50);
	h = DPISCALE(20);
	static_event->MoveWindow(x, y, w, h);
	x += w + DPISCALE(5);
	y -= DPISCALE(2);
	w = DPISCALE(225);
	h = DPISCALE(22);
	edit_event.MoveWindow(x, y, w, h);
	x = DPISCALE(480) + offx;
	y = DPISCALE(50);
	x += DPISCALE(10);
	y += DPISCALE(25);
	w = DPISCALE(30);
	h = DPISCALE(20);
	static_arg->MoveWindow(x, y, w, h);
	x += w;
	y -= DPISCALE(3);
	w = DPISCALE(160);
	h = DPISCALE(22);
	edit_arg.MoveWindow(x, y, w, h);
	x = DPISCALE(480) + offx;
	x += DPISCALE(10);
	y += DPISCALE(38);
	w = DPISCALE(30);
	h = DPISCALE(20);
	static_arg2->MoveWindow(x, y, w, h);
	x += w;
	y -= DPISCALE(3);
	w = DPISCALE(160);
	h = DPISCALE(22);
	edit_arg2.MoveWindow(x, y, w, h);
	x = DPISCALE(480) + offx;
	x += DPISCALE(10);
	y += DPISCALE(38);
	w = DPISCALE(30);
	h = DPISCALE(20);
	static_arg3->MoveWindow(x, y, w, h);
	x += w;
	y -= DPISCALE(3);
	w = DPISCALE(160);
	h = DPISCALE(22);
	edit_arg3.MoveWindow(x, y, w, h);
	//pDrawWnd绘制窗口
	x = DPISCALE(10) + offx;
	y = DPISCALE(180);
	w = cx - x - (bShowEntityList ? DPISCALE(220) : DPISCALE(10));
	h = cy - y - DPISCALE(10);
	pDrawWnd.MoveWindow(x, y, w, h);
	ResetWindowPos();
}

void CMapEditor::OnMoving(UINT fwSide, LPRECT pRect)
{
	CDialog::OnMoving(fwSide, pRect);
	ResetWindowPos();
}

void CMapEditor::OnSizing(UINT fwSide, LPRECT pRect)
{
	CDialog::OnSizing(fwSide, pRect);
	ResetWindowPos();
}

void CMapEditor::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CDialog::OnShowWindow(bShow, nStatus);
	auto mainEditor = (CMainEditor*)pMainEditor;
	if (bShow)
		mainEditor->GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_GAMEEDITOR)->CheckMenuItem(ID_MAP_EDITOR, MF_BYCOMMAND | MF_CHECKED);
	else
	{
		mainEditor->GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_GAMEEDITOR)->CheckMenuItem(ID_MAP_EDITOR, MF_BYCOMMAND | MF_UNCHECKED);
		pBrushWnd.ShowWindow(SW_HIDE);
	}
}

void CMapEditor::OnTimer(UINT_PTR nIDEvent)
{
	CDialog::OnTimer(nIDEvent);
	if (!playing || nIDEvent != timeid)
		return;
	timeCounter++;
	windAniIndex += windAniSpeed;
	if (windAniIndex >= 1)
		windAniIndex -= 1;
	windAniIndex2 += windAniSpeed2;
	if (windAniIndex2 >= 1)
		windAniIndex2 -= 1;
	pDrawWnd.Draw(true);
}

void CMapEditor::OnBnClickedCheckMaplist()
{
	// TODO: 在此添加控件通知处理程序代码
	if (check_mapList.GetCheck())
	{
		static_mapList->ShowWindow(SW_SHOW);
		list_mapList.ShowWindow(SW_SHOW);
	}
	else
	{
		static_mapList->ShowWindow(SW_HIDE);
		list_mapList.ShowWindow(SW_HIDE);
	}
	//重新发送消息OnSize消息
	CRect rc;
	GetClientRect(&rc);
	PostMessage(WM_SIZE, (WPARAM)SIZE_RESTORED, MAKELPARAM(rc.Width(), rc.Height()));
	RedrawControlWnd();
}

void CMapEditor::OnBnClickedCheckEntitylist()
{
	// TODO: 在此添加控件通知处理程序代码
	if (check_entityList.GetCheck())
	{
		static_entityList->ShowWindow(SW_SHOW);
		tree_entityList.ShowWindow(SW_SHOW);
	}
	else
	{
		static_entityList->ShowWindow(SW_HIDE);
		tree_entityList.ShowWindow(SW_HIDE);
	}
	//重新发送消息OnSize消息
	CRect rc;
	GetClientRect(&rc);
	PostMessage(WM_SIZE, (WPARAM)SIZE_RESTORED, MAKELPARAM(rc.Width(), rc.Height()));
	RedrawControlWnd();
}

void CMapEditor::OnBnClickedCheckLayerlist()
{
	// TODO: 在此添加控件通知处理程序代码
	if (check_layerList.GetCheck())
	{
		static_layerList->ShowWindow(SW_SHOW);
		list_layerList.ShowWindow(SW_SHOW);
	}
	else
	{
		static_layerList->ShowWindow(SW_HIDE);
		list_layerList.ShowWindow(SW_HIDE);
	}
	//重新发送消息OnSize消息
	CRect rc;
	GetClientRect(&rc);
	PostMessage(WM_SIZE, (WPARAM)SIZE_RESTORED, MAKELPARAM(rc.Width(), rc.Height()));
	RedrawControlWnd();
}

void CMapEditor::OnBnClickedCheckLight()
{
	pDrawWnd.Draw();
}

void CMapEditor::OnBnClickedRadioEditmap()
{
	// TODO: 在此添加控件通知处理程序代码
	check_entity.EnableWindow(true);
	ShowMapInfo(true);
	ShowEntityInfo(false);
	if (IsWindowVisible())
		pBrushWnd.ShowWindow(SW_SHOW);
	auto layer = GetSelectLayer();
	if (layer)
		SwitchPaintMenu(layer);
}

void CMapEditor::OnBnClickedRadioEditentity()
{
	// TODO: 在此添加控件通知处理程序代码
	check_entity.SetCheck(true);
	check_entity.EnableWindow(false);
	ShowMapInfo(false);
	ShowEntityInfo(true);
	pBrushWnd.ShowWindow(SW_HIDE);
	auto layer = GetSelectLayer();
	if (layer)
		SwitchPaintMenu(layer);
	Draw();
}

void CMapEditor::OnBnClickedCheckEntity()
{
	// TODO: 在此添加控件通知处理程序代码
}

void CMapEditor::OnBnClickedCheckEntitylabel()
{
	// TODO: 在此添加控件通知处理程序代码
}

void CMapEditor::OnBnClickedCheckEntityshow()
{
	// TODO: 在此添加控件通知处理程序代码
}

void CMapEditor::OnUpdateDraw()
{
	Draw();
}

void CMapEditor::OnBnClickedRadioPaint()
{
	auto& pDrawView = *pDrawWnd.GetMyView();
	auto& pBrushView = *pBrushWnd.GetMyView();
	pDrawView.cursorW = pBrushView.cursorW_selected;
	pDrawView.cursorH = pBrushView.cursorH_selected;
	Draw();
}

void CMapEditor::OnBnClickedRadioReplace()
{
	auto& pDrawView = *pDrawWnd.GetMyView();
	pDrawView.cursorW = 1;
	pDrawView.cursorH = 1;
	Draw();
}

void CMapEditor::OnBnClickedRadioFill()
{
	auto& pDrawView = *pDrawWnd.GetMyView();
	pDrawView.cursorW = 1;
	pDrawView.cursorH = 1;
	Draw();
}

void CMapEditor::OnBnClickedRadioRect()
{
	auto& pDrawView = *pDrawWnd.GetMyView();
	pDrawView.cursorW = 1;
	pDrawView.cursorH = 1;
	Draw();
}

void CMapEditor::OnBnClickedRadioCopy()
{
	auto& pDrawView = *pDrawWnd.GetMyView();
	pDrawView.cursorW = 1;
	pDrawView.cursorH = 1;
	Draw();
}

void CMapEditor::OnBnClickedRadioPaste()
{
	pDrawWnd.SetCursorToCopyBuffSize();
	Draw();
}

void CMapEditor::OnBnClickedButtonBrushwnd()
{
	pBrushWnd.ShowWindow(pBrushWnd.IsWindowVisible() ? SW_HIDE : SW_SHOW);
}

void CMapEditor::OnBnClickedButtonEntityoption()
{
	auto pLayer = GetSelectLayer(); 
	if (!pLayer || pLayer->selected_entity < 0)
		return;
	CEntityFlag dlg;
	//如果修改了flag
	auto& step_pxe = *pLayer->GetPxeStep();
	auto& el = step_pxe.at(pLayer->selected_entity);
	dlg.outFlag = el.flag;
	if (dlg.DoModal() != IDOK)
		return;
	if (!(dlg.outFlag == el.flag))
	{
		pLayer->undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
		el.flag = dlg.outFlag;
		pDrawWnd.ResetEntityPlay();
		Draw();
	}
}

void CMapEditor::OnEditMap()
{
	int sel = list_mapList.GetCurSel();
	if (Close())
		return;
	//载入
	if (sel < 0)
		return;
	list_mapList.GetText(sel, mapfilename);
	Load(mapfilename);
}

void CMapEditor::OnPrepMap()
{
	if (!IsLoaded())
	{
		MessageBox(L"需要载入地图后来修改地图属性", L"未载入地图", MB_ICONINFORMATION);
		return;
	}
	CNewMap dlg;
	dlg.load = true;
	dlg.outMapFile = mapfilename;
	dlg.outMapName = mapSet.mapName.c_str();
	dlg.outMapW = mapSet.mapW;
	dlg.outMapH = mapSet.mapH;
	if (dlg.DoModal() != IDOK)
		return;
	//内部已经检查了是否文件夹下有同名文件
	if (mapfilename != dlg.outMapFile)
	{
		//修改pxm文件
		CString oldPxmFile;
		oldPxmFile.Format(L"./data/map/%s.pxm", mapfilename.GetString());
		CString newPxmFile;
		newPxmFile.Format(L"./data/map/%s.pxm", dlg.outMapFile.GetString());
		if (_wrename(oldPxmFile.GetString(), newPxmFile.GetString()))
		{
			//重命名失败
			CString err;
			err.Format(L"文件名%s修改为%s失败", oldPxmFile.GetString(), newPxmFile.GetString());
			MessageBox(err.GetString(), L"文件重命名失败", MB_ICONWARNING);
			return;
		}
		//修改lua文件
		CString oldLuaFile;
		oldLuaFile.Format(L"./data/map/%s.lua", mapfilename.GetString());
		//检查lua文件是否存在
		FILE* fp;
		_wfopen_s(&fp, oldLuaFile.GetString(), L"rb");
		if (fp)
		{
			fclose(fp);
			CString newLuaFile;
			newLuaFile.Format(L"./data/map/%s.lua", dlg.outMapFile.GetString());
			if (_wrename(oldLuaFile.GetString(), newLuaFile.GetString()))
			{
				//重命名失败
				CString err;
				err.Format(L"文件名%s修改为%s失败", oldLuaFile.GetString(), newLuaFile.GetString());
				MessageBox(err.GetString(), L"文件重命名失败", MB_ICONWARNING);
				return;
			}
		}
	}
	mapfilename = dlg.outMapFile;
	mapSet.mapName = dlg.outMapName.GetString();
	//如果更新了房间尺寸
	if (dlg.outMapW != mapSet.mapW || dlg.outMapH != mapSet.mapH)
		pDrawWnd.ResetEntityPlay();
	mapSet.mapW = dlg.outMapW;
	mapSet.mapH = dlg.outMapH;
	pDrawWnd.UpdateMapCache();
	pxmfile.Format(L"./data/map/%s.pxm", mapfilename.GetString());
	OnUpdateList();
	UpdateWindowTitle();//更新窗口标题
	Draw();
}

void CMapEditor::OnScriptMap()
{
	int sel = list_mapList.GetCurSel();
	if (sel < 0)
	{
		if (IsLoaded())
			sel = list_mapList.FindString(0, mapfilename.GetString());
		if (sel < 0)
			return;
	}
	CString map,luafile;
	list_mapList.GetText(sel, map);
	luafile.Format(L"./data/map/%s.lua", map.GetString());
	//检查脚本文件是否存在
	FILE* fp;
	_wfopen_s(&fp, luafile.GetString(), L"rb");
	if (!fp)
	{
		//如果脚本文件不存在则新建脚本文件
		_wfopen_s(&fp, luafile.GetString(), L"wb+");
		if (!fp)
		{
			CString err;
			err.Format(L"无法创建脚本文件：%s", luafile.GetString());
			MessageBox(err.GetString(), L"写入文件错误", MB_ICONWARNING);
			return;
		}
		else
			fclose(fp);
	}
	else
		fclose(fp);
	wchar_t buff[MAX_PATH];
	CString filepath;
	GetModuleFileNameW(nullptr, buff, _countof(buff));
	filepath = buff;
	auto index = filepath.ReverseFind(L'\\');
	filepath.Delete(index, filepath.GetLength() - index);
	filepath.Append(L"\\");
	luafile.Format(L"data\\map\\%s.lua", map.GetString());
	filepath.Append(luafile);
	//打开脚本文件
	CString cmd;
	cmd.Format(L"explorer \"%s\"", filepath.GetString());
	MyWinExec(cmd.GetString());
}

void CMapEditor::OnScriptDrawclickMap()
{
	if (!IsLoaded())
		return;
	CString luafile;
	luafile.Format(L"./data/map/%s.lua", mapfilename.GetString());
	//检查脚本文件是否存在
	FILE* fp;
	_wfopen_s(&fp, luafile.GetString(), L"rb");
	if (!fp)
	{
		//如果脚本文件不存在则新建脚本文件
		_wfopen_s(&fp, luafile.GetString(), L"wb+");
		if (!fp)
		{
			CString err;
			err.Format(L"无法创建脚本文件：%s", luafile.GetString());
			MessageBox(err.GetString(), L"写入文件错误", MB_ICONWARNING);
			return;
		}
		else
			fclose(fp);
	}
	else
		fclose(fp);
	wchar_t buff[MAX_PATH];
	CString filepath;
	GetModuleFileNameW(nullptr, buff, _countof(buff));
	filepath = buff;
	auto index = filepath.ReverseFind(L'\\');
	filepath.Delete(index, filepath.GetLength() - index);
	filepath.Append(L"\\");
	luafile.Format(L"data\\map\\%s.lua", mapfilename.GetString());
	filepath.Append(luafile);
	//打开脚本文件
	CString cmd;
	cmd.Format(L"explorer \"%s\"", filepath.GetString());
	MyWinExec(cmd.GetString());
}

void CMapEditor::OnCopyMap()
{
	//载入
	int sel = list_mapList.GetCurSel();
	if (sel < 0)
		return;
	list_mapList.GetText(sel, mapfilename);
	//复制地图
	CString newMapName = mapfilename;
	CString newMapFileName;
	FILE* fp = nullptr;
	do
	{
		if (fp)
		{
			fclose(fp);
			fp = nullptr;
		}
		newMapName.Append(L"0");
		newMapFileName.Format(L"./data/map/%s.pxm", newMapName.GetString());
		_wfopen_s(&fp, newMapFileName.GetString(), L"rb");
	} while (fp);
	CString srcMapFileName;
	srcMapFileName.Format(L"./data/map/%s.pxm", mapfilename.GetString());
	CopyFile(srcMapFileName.GetString(), newMapFileName.GetString(), true);
	//复制脚本
	CString srcLuaFileName;
	srcLuaFileName.Format(L"./data/map/%s.lua", mapfilename.GetString());
	CString newLuaFileName;
	newLuaFileName.Format(L"./data/map/%s.lua", newMapName.GetString());
	CopyFile(srcLuaFileName.GetString(), newLuaFileName.GetString(), false);
	OnUpdateList();
	int index = list_mapList.FindString(0, newMapName.GetString());
	list_mapList.SetCurSel(index);
	OnEditMap();
}

void CMapEditor::OnAddMap()
{
	if (Close())
		return;
	CNewMap dlg;
	if (dlg.DoModal() != IDOK)
		return;
	mapfilename = dlg.outMapFile;
	mapSet.mapName = dlg.outMapName.GetString();
	mapSet.mapW = dlg.outMapW;
	mapSet.mapH = dlg.outMapH;
	pxmfile.Format(L"./data/map/%s.pxm", mapfilename.GetString());
	Save();
	int index = list_mapList.FindString(0, mapfilename.GetString());
	list_mapList.SetCurSel(index);
	OnEditMap();
}

void CMapEditor::OnDeleteMap()
{
	CString selectedMapName;
	//载入
	int sel = list_mapList.GetCurSel();
	list_mapList.GetText(sel, selectedMapName);
	//如果当前正在编辑的地图是正要删除的
	if (mapfilename == selectedMapName)
	{
		ResetContext();
		//锁定界面
		EnableControl(false);
		EnableEdit(false);
		Draw();
	}
	CString filename;
	filename.Format(L"./data/map/%s.pxm", selectedMapName.GetString());
	if (_wremove(filename.GetString()) != 0)
	{
		CString err;
		err.Format(L"删除文件%s失败", filename.GetString());
		MessageBoxW(err.GetString(), L"删除地图失败", MB_ICONWARNING);
	}
	filename.Format(L"./data/map/%s.lua", selectedMapName.GetString());
	if (_wremove(filename.GetString()) != 0)
	{
		CString err;
		err.Format(L"删除文件%s失败", filename.GetString());
		MessageBoxW(err.GetString(), L"删除脚本失败", MB_ICONWARNING);
	}
	list_mapList.DeleteString(sel);
}

void CMapEditor::OnOpenFolder()
{
	wchar_t buff[MAX_PATH];
	CString filepath;
	GetModuleFileNameW(nullptr, buff, _countof(buff));
	filepath = buff;
	auto index = filepath.ReverseFind(L'\\');
	filepath.Delete(index, filepath.GetLength() - index);
	filepath.Append(L"\\data\\map\\");
	CString cmd;
	index = list_mapList.GetCurSel();
	if (index >= 0)
	{
		CString pngfile;
		list_mapList.GetText(index, pngfile);
		filepath.Append(pngfile);
		cmd.Format(L"explorer /select,%s.pxm", filepath.GetString());
	}
	else
	{
		cmd.Format(L"explorer %s", filepath.GetString());
	}
	MyWinExec(cmd.GetString());
}

void CMapEditor::OnUpdateList()
{
	int nSelectedIndex = list_mapList.GetCurSel();
	int nScrollPos = list_mapList.GetScrollPos(SB_VERT);
	list_mapList.ResetContent();
	CFileFind finder;
	bool rs = finder.FindFile(L"./data/map/*.pxm");
	while (rs)
	{
		rs = finder.FindNextFile();
		CString str = finder.GetFileName();
		auto index = str.ReverseFind(L'.');
		CString mapName = str.Left(index);
		list_mapList.AddString(mapName.GetString());
	}
	list_mapList.SetScrollPos(SB_VERT, nScrollPos, TRUE);
	// 恢复选中的下标
	if (nSelectedIndex != LB_ERR)
		list_mapList.SetCurSel(nSelectedIndex);
}

void CMapEditor::OnLbnDblclkListMaplist()
{
	int selIndex = list_mapList.GetCurSel();
	if (selIndex < 0)
		return;
	OnEditMap();
}

void CMapEditor::OnOpenFile()
{
	// TODO: 在此添加命令处理程序代码
	if (Close())
		return;
	wchar_t buff[MAX_PATH];
	CString filepath;
	GetModuleFileNameW(nullptr, buff, _countof(buff));
	filepath = buff;
	auto index = filepath.ReverseFind(L'\\');
	filepath.Delete(index, filepath.GetLength() - index);
	filepath.Append(L"\\data\\map\\");

	CFileDialog fd(TRUE, TEXT(""),TEXT(""), OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, TEXT("地图文件(*.pxm)|*.pxm|所有文件(*.*)|*.*||"), this);
	fd.m_ofn.lpstrInitialDir = filepath.GetString();
	if (fd.DoModal() != IDOK)
		return;
	CString str = fd.GetFileName();
	index = str.ReverseFind(L'.');
	CString mapName = str.Left(index);
	Load(mapName);
	UpdateMenuState();
	UpdateWindowTitle();
}

void CMapEditor::OnSaveFile()
{
	if (!IsLoaded())
		return;
	Save();
}

void CMapEditor::OnCloseFile()
{
	Close();
}

void CMapEditor::OnUndo()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& layer = *pLayer;
	auto& undoRedo = layer.undoRedo;
	undoRedo.Undo();
	pDrawWnd.UpdateMapCache();
	UpdateMenuState();
	UpdateWindowTitle();
	Draw();
}

void CMapEditor::OnRedo()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& layer = *pLayer;
	auto& undoRedo = layer.undoRedo;
	undoRedo.Redo();
	pDrawWnd.UpdateMapCache();
	UpdateMenuState();
	UpdateWindowTitle();
	Draw();
}

void CMapEditor::OnCopy()
{
	OnCopyEntity();
}

void CMapEditor::OnPaste()
{
	OnPasteEntity();
}

void CMapEditor::OnCut()
{
	OnCopyEntity();
	SelectToEntity();
	OnDeleteEntity();
}

void CMapEditor::OnMoveMap()
{
	if (!IsLoaded())
	{
		MessageBox(L"需要先载入地图来编辑", L"未载入地图", MB_ICONINFORMATION);
		return;
	}
	if (mapSet.layerList.empty())
	{
		MessageBox(L"至少需要创建一个图层来编辑", L"未创建图层", MB_ICONINFORMATION);
		return;
	}
	CMoveMap dlg;
	if (dlg.DoModal() != IDOK)
		return;
	if (dlg.outX == 0 && dlg.outY == 0)
		return;
	//如果没有选择图层，则选择第一个图层
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		list_layerList.SetCurSel(0);
	//对所有图层操作
	for (auto& p : mapSet.layerList)
	{
		auto& layer = p.second;
		//跳过循环背景层
		if (!dlg.outMoveLoopLayer && layer.layerType == 2)
			continue;
		//移动地图
		layer.undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXM_STR);
		std::unordered_map<LONG, LONG> temp_pxm;
		auto& step_pxm = *layer.GetPxmStep();
		for (auto& t : step_pxm)
		{
			int y = HIWORD(t.first);
			int x = LOWORD(t.first);
			int dstX = x + dlg.outX;
			int dstY = y + dlg.outY;
			if (dlg.outLoop)
			{
				//循环移动
				if (dstX < 0)
				{
					auto num = (int)ceilf((float)abs(dstX) / mapSet.mapW);
					dstX += num * mapSet.mapW;
				}
				else
				{
					dstX %= mapSet.mapW;
				}
				if (dstY < 0)
				{
					auto num = (int)ceilf((float)abs(dstY) / mapSet.mapH);
					dstY += num * mapSet.mapH;
				}
				else
				{
					dstY %= mapSet.mapH;
				}
				temp_pxm.insert(std::make_pair(MAKELONG(dstX, dstY), t.second));
			}
			else
			{
				//不循环
				//剔除超出房间范围的部分
				if (dstX >= 0 && dstX < mapSet.mapW && dstY >= 0 && dstY < mapSet.mapH)
					temp_pxm.insert(std::make_pair(MAKELONG(dstX, dstY), t.second));
			}
		}
		step_pxm = temp_pxm;
		layer.undoRedo.EndStep();
		//移动实体
		layer.undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
		auto& step_pxe = *layer.GetPxeStep();
		for (auto& t : step_pxe)
		{
			auto& el = t.second;
			int dstX = el.x + dlg.outX;
			int dstY = el.y + dlg.outY;
			if (dlg.outLoop)
			{
				//循环移动
				if (dstX < 0)
				{
					auto num = (int)ceilf((float)abs(dstX) / mapSet.mapW);
					dstX += num * mapSet.mapW;
				}
				else
				{
					dstX %= mapSet.mapW;
				}
				if (dstY < 0)
				{
					auto num = (int)ceilf((float)abs(dstY) / mapSet.mapH);
					dstY += num * mapSet.mapH;
				}
				else
				{
					dstY %= mapSet.mapH;
				}	
			}
			el.x = dstX;
			el.y = dstY;
			if (el.x < 0)
				el.x = 0;
			if (el.y < 0)
				el.y = 0;
		}
		layer.undoRedo.EndStep();
	}
	UpdateMenuState();
	UpdateWindowTitle();
	pDrawWnd.ResetEntityPlay();
}

void CMapEditor::OnWallAdjust()
{
	if (!IsLoaded())
	{
		MessageBox(L"需要先载入地图来编辑", L"未载入地图", MB_ICONINFORMATION);
		return;
	}
	if (mapSet.layerList.empty())
	{
		MessageBox(L"至少需要创建一个图层来编辑", L"未创建图层", MB_ICONINFORMATION);
		return;
	}
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
	{
		MessageBox(L"未选择图层", L"意外的错误", MB_ICONINFORMATION);
		return;
	}
	CWallAdjust dlg;
	pBrushWnd.pWallAdjust_Edit_w = &dlg.edit_w;
	pBrushWnd.pWallAdjust_Edit_h = &dlg.edit_h;
	dlg.inW = pBrushWnd.GetMyView()->cursorW_selected;
	dlg.inH = pBrushWnd.GetMyView()->cursorH_selected;
	auto res = dlg.DoModal();
	pBrushWnd.pWallAdjust_Edit_w = nullptr;
	pBrushWnd.pWallAdjust_Edit_h = nullptr;
	if (res != IDOK)
		return;
	auto& brushView = *pBrushWnd.GetMyView();
	//调整当前图层
	if (dlg.outOp == 0)
	{
		std::set<LONG> adjustPxm;
		auto& step_pxm = *pLayer->GetPxmStep();
		for (auto& p : step_pxm)
		{
			int pX = LOWORD(p.second);
			int pY = HIWORD(p.second);
			if (pX >= brushView.cursorX_selected &&
				pX < brushView.cursorX_selected + brushView.cursorW_selected &&
				pY >= brushView.cursorY_selected &&
				pY < brushView.cursorY_selected + brushView.cursorH_selected)
				adjustPxm.insert(p.first);
		}
		if (!adjustPxm.empty())
		{
			int dx = dlg.outDx;
			int dy = dlg.outDy;
			pLayer->undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXM_STR);
			for (auto& p : adjustPxm)
			{
				int x = LOWORD(p);
				int y = HIWORD(p);
				LONG dstPxa = MAKELONG(brushView.cursorX_selected + (x + dx) % brushView.cursorW_selected,
					brushView.cursorY_selected + (y + dy) % brushView.cursorH_selected);
				step_pxm[p] = dstPxa;
			}
			pLayer->undoRedo.EndStep();
		}
	}
	//调整所有图层
	else
	{
		for (auto& p : mapSet.layerList)
		{
			auto& layer = p.second;
			if (layer.pxaName != pLayer->pxaName)
				continue;
			std::set<LONG> adjustPxm;
			auto& step_pxm = *layer.GetPxmStep();
			for (auto& p : step_pxm)
			{
				int pX = LOWORD(p.second);
				int pY = HIWORD(p.second);
				if (pX >= brushView.cursorX_selected &&
					pX < brushView.cursorX_selected + brushView.cursorW_selected &&
					pY >= brushView.cursorY_selected &&
					pY < brushView.cursorY_selected + brushView.cursorH_selected)
					adjustPxm.insert(p.first);
			}
			if (!adjustPxm.empty())
			{
				int dx = dlg.outDx;
				int dy = dlg.outDy;
				layer.undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXM_STR);
				for (auto& p : adjustPxm)
				{
					int x = LOWORD(p);
					int y = HIWORD(p);
					LONG dstPxa = MAKELONG(brushView.cursorX_selected + (x + dx) % brushView.cursorW_selected,
						brushView.cursorY_selected + (y + dy) % brushView.cursorH_selected);
					step_pxm[p] = dstPxa;
				}
				layer.undoRedo.EndStep();
			}
		}
	}
	UpdateMenuState();
	UpdateWindowTitle();
}

void CMapEditor::OnShowBk()
{
	if (check_bk.GetCheck())
	{
		check_bk.SetCheck(false);
		GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_OPTION)->CheckMenuItem(ID_SHOW_BK, MF_BYCOMMAND | MF_UNCHECKED);
	}
	else
	{
		check_bk.SetCheck(true);
		GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_OPTION)->CheckMenuItem(ID_SHOW_BK, MF_BYCOMMAND | MF_CHECKED);
	}
	Draw();
}

void CMapEditor::OnShowGrid()
{
	if (check_grid.GetCheck())
	{
		check_grid.SetCheck(false);
		GetMenu()->GetSubMenu(CPIDEDITOR_MENUINDEX_OPTION)->CheckMenuItem(ID_SHOW_GRID, MF_BYCOMMAND | MF_UNCHECKED);
	}
	else
	{
		check_grid.SetCheck(true);
		GetMenu()->GetSubMenu(CPIDEDITOR_MENUINDEX_OPTION)->CheckMenuItem(ID_SHOW_GRID, MF_BYCOMMAND | MF_CHECKED);
	}
	Draw();
}

void CMapEditor::OnEditGlobalscript()
{
	wchar_t buff[MAX_PATH];
	CString filepath;
	GetModuleFileNameW(nullptr, buff, _countof(buff));
	filepath = buff;
	auto index = filepath.ReverseFind(L'\\');
	filepath.Delete(index, filepath.GetLength() - index);
	filepath.Append(L"\\data\\global.lua");

	CString cmd;
	cmd.Format(L"explorer \"%s\"", filepath.GetString());
	MyWinExec(cmd.GetString());
}

void CMapEditor::OnSwitchLanguage()
{
	CPidEditorLang dlg;
	dlg.languageSel = pDrawWnd.GetEntityRes()->entityLanguage;
	if (dlg.DoModal() != IDOK)
		return;
	if (pDrawWnd.GetEntityRes()->entityLanguage != dlg.languageSel)
	{
		pDrawWnd.GetEntityRes()->entityLanguage = dlg.languageSel;
		pDrawWnd.GetEntityRes()->ReloadLanguage();
		Draw();
	}
}

void CMapEditor::OnImportCavestoryPxm()
{
	CImportCaveStoryPxm dlg;
	dlg.inLastOffX = last_CImportCaveStoryPxmOffX;
	dlg.inLastOffY = last_CImportCaveStoryPxmOffY;
	if (dlg.DoModal() != IDOK)
		return;
	dlg.inLastOffX = last_CImportCaveStoryPxmOffX;
	dlg.inLastOffY = last_CImportCaveStoryPxmOffY;
	//把数据拷贝到复制板中
	CMAPEDITOR_DATATYPE_PXM* pCopyBuff = nullptr;
	int* pCopyBuff_w = nullptr;
	int* pCopyBuff_h = nullptr;
	pDrawWnd.GetCopyBoard(&pCopyBuff, &pCopyBuff_w, &pCopyBuff_h);
	*pCopyBuff = dlg.outPxm;
	*pCopyBuff_w = dlg.outPxm_w;
	*pCopyBuff_h = dlg.outPxm_h;
	MessageBoxW(L"地图数据已成功拷贝到复制板\n请使用粘贴工具来涂绘", L"导入地图数据成功");
}

void CMapEditor::OnScreenshot()
{
	pDrawWnd.SetScreenShot();
}

void CMapEditor::OnRefreshImage()
{
	pDrawWnd.RefreshImage();
	pDrawWnd.Draw();
	pBrushWnd.RefreshImage();
	pBrushWnd.Draw();
	pBrushPreview.RefreshImage();
	pBrushPreview.Draw();
}

void CMapEditor::OnLbnSelchangeListLayerlist()
{
	CString layerName = GetSelectLayerName();
	if (layerName.GetLength() == 0)
	{
		//取消选择
		EnableEdit(false);
		return;
	}
	auto& layer = *GetSelectLayer();
	pBrushWnd.Load(layer.pxaName.c_str());
	pBrushPreview.Load(layer.pxaName.c_str());
	//选中
	if (radio_editMap.GetCheck())
	{
		//显示地形组
		pBrushWnd.ShowWindow(SW_SHOW);
		pBrushPreview.ShowWindow(SW_SHOW);
	}
	if (radio_editEntity.GetCheck())
	{
		//隐藏地形组
		pBrushWnd.ShowWindow(SW_HIDE);
		pBrushPreview.ShowWindow(SW_HIDE);
	}
	SwitchPaintMenu(&layer);
	EnableEdit(true);
	Draw();
}

void CMapEditor::OnAddLayer()
{
	CNewLayer dlg;
	//是否已有主图层
	for (auto& p : mapSet.layerList)
	{
		//如果找到了主层
		if (p.second.layerType == 0)
		{
			//默认选择背景层
			dlg.outLayerType = 1;
			dlg.outOrder = 200;
			goto CMapEditor_OnAddLayer_MainLayer;
		}
	}
	//默认选择主层
	dlg.outLayerType = 0;
	dlg.outOrder = 100;
	dlg.outJumpFrame = 0;
CMapEditor_OnAddLayer_MainLayer:
	dlg.pMapSet = &mapSet;
	dlg.outMapW = mapSet.mapW;
	dlg.outMapH = mapSet.mapH;
	if (dlg.DoModal() != IDOK)
		return;
	MyMapLayer layer;
	//地形组
	layer.pxaName = dlg.outPxa.GetString();
	//图层类型
	layer.layerType = dlg.outLayerType;
	switch (layer.layerType)
	{
	case 0://主层
		mapSet.mapW = dlg.outMapW;
		mapSet.mapH = dlg.outMapH;
		break;
	case 1://背景层
		layer.offx = dlg.outOffx;
		layer.offy = dlg.outOffy;
		layer.myFar = dlg.outMyFar;
		break;
	case 2://循环背景层
		layer.loopH = dlg.outLoopH;
		layer.loopV = dlg.outLoopV;
		layer.speedH = dlg.outSpeedH;
		layer.speedV = dlg.outSpeedV;
		layer.myFar = dlg.outMyFar;
		break;
	}
	//通用属性
	layer.order = dlg.outOrder;
	layer.jumpFrame = dlg.outJumpFrame;
	//颜色调整
	layer.color = dlg.outColor;
	layer.visible = true;
	//光线
	layer.dayLight = dlg.outDayLight;
	layer.tinyHSV[0] = dlg.outHSV[0];
	layer.tinyHSV[1] = dlg.outHSV[1];
	layer.tinyHSV[2] = dlg.outHSV[2];
	layer.lightConst = dlg.outLightConst;
	//绘制剪切区域
	layer.enableClipZone = dlg.outEnableClipZone;
	layer.clipZone = dlg.outClipZone;
	//设置Pxm撤销重做功能
	MyUndoRedoDataOp op_pxm;
	op_pxm.NewData = CMapEditor_Pxm_NewData;
	op_pxm.NewCopyOfData = CMapEditor_Pxm_NewCopyOfData;
	op_pxm.ReleaseData = CMapEditor_Pxm_ReleaseData;
	layer.undoRedo.AddDataType(CMAPEDITOR_DATATYPE_PXM_STR, op_pxm);
	//设置Pxe撤销重做功能
	MyUndoRedoDataOp op_pxe;
	op_pxe.NewData = CMapEditor_Pxe_NewData;
	op_pxe.NewCopyOfData = CMapEditor_Pxe_NewCopyOfData;
	op_pxe.ReleaseData = CMapEditor_Pxe_ReleaseData;
	layer.undoRedo.AddDataType(CMAPEDITOR_DATATYPE_PXE_STR, op_pxe);
	//添加层
	mapSet.layerList.insert(std::make_pair(dlg.outLayerName.GetString(), layer));
	pBrushWnd.Load(dlg.outPxa);
	SwitchPaintMenu(&layer);
	UpdateLayerList(dlg.outLayerName);
	UpdateWindowTitle();
	UpdateMenuState();
	Draw();
}

void CMapEditor::OnPrepLayer()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& layer = *pLayer;
	CString layerName = layer.tempLayerName.c_str();
	CString pxaName = layer.pxaName.c_str();
	//保存之前的光照参数
	auto srcDayLight = layer.dayLight;
	float srcTinyHSV[3];
	srcTinyHSV[0] = layer.tinyHSV[0];
	srcTinyHSV[1] = layer.tinyHSV[1];
	srcTinyHSV[2] = layer.tinyHSV[2];
	auto srcLightConst = layer.lightConst;
	DWORD srcColor = layer.color;
	CNewLayer dlg;
	dlg.pLayer = &layer;
	dlg.pDrawWnd = &pDrawWnd;
	//地形组
	dlg.outLayerName = layerName;
	dlg.outPxa = pxaName;
	//图层类型
	dlg.outLayerType = layer.layerType;
	//主层
	dlg.outMapW = mapSet.mapW;
	dlg.outMapH = mapSet.mapH;
	//背景层
	dlg.outOffx = layer.offx;
	dlg.outOffy = layer.offy;
	dlg.outMyFar = layer.myFar;
	//循环背景层
	dlg.outLoopH = layer.loopH;
	dlg.outLoopV = layer.loopV;
	dlg.outSpeedH = layer.speedH;
	dlg.outSpeedV = layer.speedV;
	//通用属性
	dlg.outOrder = layer.order;
	dlg.outJumpFrame = layer.jumpFrame;
	//颜色调整
	dlg.outColor = layer.color;
	//光线
	dlg.outDayLight = layer.dayLight;
	dlg.outHSV[0] = layer.tinyHSV[0];
	dlg.outHSV[1] = layer.tinyHSV[1];
	dlg.outHSV[2] = layer.tinyHSV[2];
	dlg.outLightConst = layer.lightConst;
	//绘制剪切区域
	dlg.outEnableClipZone = layer.enableClipZone;
	dlg.outClipZone = layer.clipZone;
	//设置对话框属性
	dlg.load = true;
	dlg.pMapSet = &mapSet;
	if (dlg.DoModal() != IDOK)
	{
		//恢复原来的值
		layer.dayLight = srcDayLight;
		layer.tinyHSV[0] = srcTinyHSV[0];
		layer.tinyHSV[1] = srcTinyHSV[1];
		layer.tinyHSV[2] = srcTinyHSV[2];
		layer.lightConst = srcLightConst;
		layer.color = srcColor;
		Draw();
		return;
	}
		
	MyMapLayer* dstLayer = &mapSet.layerList.at(layerName.GetString());
	//如果修改了图层名称
	if (layerName != dlg.outLayerName)
	{
		MyMapLayer newLayer = mapSet.layerList.at(layerName.GetString());
		mapSet.layerList.erase(layerName.GetString());
		mapSet.layerList.insert(std::make_pair(dlg.outLayerName.GetString(), newLayer));
		dstLayer = &mapSet.layerList.at(dlg.outLayerName.GetString());
	}
	//地形组
	dstLayer->pxaName = dlg.outPxa.GetString();
	//图层类型
	dstLayer->layerType = dlg.outLayerType;
	switch (dstLayer->layerType)
	{
	case 0://主层
		//取消所有其他图层的主层
		for (auto& p : mapSet.layerList)
		{
			//跳过自身
			if (dstLayer == &p.second)
				continue;
			//把设为主层的层改成背景层
			if (p.second.layerType == 0)
				p.second.layerType = 1;
		}
		//如果更新了房间尺寸
		if (dlg.outMapW != mapSet.mapW || dlg.outMapH != mapSet.mapH)
			pDrawWnd.ResetEntityPlay();
		mapSet.mapW = dlg.outMapW;
		mapSet.mapH = dlg.outMapH;
		pDrawWnd.UpdateMapCache();
		break;
	case 1://背景层
		dstLayer->offx = dlg.outOffx;
		dstLayer->offy = dlg.outOffy;
		dstLayer->myFar = dlg.outMyFar;
		break;
	case 2://循环背景层
		dstLayer->loopH = dlg.outLoopH;
		dstLayer->loopV = dlg.outLoopV;
		dstLayer->speedH = dlg.outSpeedH;
		dstLayer->speedV = dlg.outSpeedV;
		dstLayer->myFar = dlg.outMyFar;
		break;
	}
	//通用
	dstLayer->order = dlg.outOrder;
	dstLayer->jumpFrame = dlg.outJumpFrame;
	//颜色调整
	dstLayer->color = dlg.outColor;
	//光线
	dstLayer->dayLight = dlg.outDayLight;
	dstLayer->tinyHSV[0] = dlg.outHSV[0];
	dstLayer->tinyHSV[1] = dlg.outHSV[1];
	dstLayer->tinyHSV[2] = dlg.outHSV[2];
	dstLayer->lightConst = dlg.outLightConst;
	//绘制剪切区域
	dstLayer->enableClipZone = dlg.outEnableClipZone;
	dstLayer->clipZone = dlg.outClipZone;
	pBrushWnd.Load(dlg.outPxa);
	UpdateLayerList(dlg.outLayerName);
	SwitchPaintMenu(pLayer);
	UpdateWindowTitle();
	UpdateMenuState();
	Draw();
}

void CMapEditor::OnCopyLayer()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	copyLayer = *pLayer;
}

void CMapEditor::OnPasteLayer()
{
	MyMapLayer& newLayer = copyLayer;
	if (newLayer.layerType == 0)
		newLayer.layerType = 1;
	//添加层
	CString newName = newLayer.tempLayerName.c_str();
	do
	{
		newName.Append(L"0");
	} while (mapSet.layerList.find(newName.GetString()) != mapSet.layerList.end());
	mapSet.layerList.insert(std::make_pair(newName.GetString(), newLayer));
	pBrushWnd.Load(newLayer.pxaName.c_str());
	SwitchPaintMenu(&newLayer);
	UpdateLayerList(newName);
	UpdateWindowTitle();
	UpdateMenuState();
	Draw();
}

void CMapEditor::OnDeleteLayer()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	CString layerName = pLayer->tempLayerName.c_str();
	auto& layerList = mapSet.layerList;
	layerList.erase(layerName.GetString());
	UpdateLayerList();
	UpdateWindowTitle();
	UpdateMenuState();
	Draw();
}

void CMapEditor::OnShowLayer()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& layer = *pLayer;
	layer.visible = !layer.visible;
	UpdateLayerList();
	UpdateWindowTitle();
	Draw();
}

void CMapEditor::OnHideotherLayer()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	pLayer->visible = true;
	for (auto& p : mapSet.layerList)
	{
		if (&p.second == pLayer)
			continue;
		p.second.visible = false;
	}
	UpdateLayerList();
	UpdateWindowTitle();
	Draw();
}

void CMapEditor::OnShowallLayer()
{
	for (auto& p : mapSet.layerList)
		p.second.visible = true;
	UpdateLayerList();
	UpdateWindowTitle();
	Draw();
}

void CMapEditor::OnLbnDblclkListLayerlist()
{
	OnPrepLayer();
}

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

void CMapEditor::OnAddEntity()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& step_pxe = *pLayer->GetPxeStep();
	auto& drawView = *pDrawWnd.GetMyView();
	EntityLoad el;
	el.name = L"null";
	el.x = drawView.cursorX;
	el.y = drawView.cursorY;
	pLayer->undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
	step_pxe.insert(std::make_pair(pLayer->nextPxeID, el));
	pLayer->undoRedo.EndStep();
	pLayer->selected_entity = pLayer->nextPxeID;
	pLayer->nextPxeID++;
	SelectToEntity();
	UpdateWindowTitle();
	UpdateMenuState();
	pDrawWnd.ResetEntityPlay();
	Draw();
}


void CMapEditor::OnDeleteEntity()
{
	auto pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	if (pLayer->selected_entity < 0)
		return;
	auto& step_pxe = *pLayer->GetPxeStep();
	pLayer->undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
	step_pxe.erase(pLayer->selected_entity);
	SelectOutEntity();
	pDrawWnd.ResetEntityPlay();
	Draw();
}


void CMapEditor::OnCopyEntity()
{
	auto pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	if (pLayer->selected_entity < 0)
		return;
	auto& step_pxe = *pLayer->GetPxeStep();
	auto iter = step_pxe.find(pLayer->selected_entity);
	if (iter == step_pxe.end())
		return;
	copyEntity = iter->second;
}


void CMapEditor::OnPasteEntity()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& step_pxe = *pLayer->GetPxeStep();
	auto& drawView = *pDrawWnd.GetMyView();
	EntityLoad el = copyEntity;
	if (el.name.length() == 0)
		el.name = L"null";
	el.x = drawView.cursorX;
	el.y = drawView.cursorY;
	pLayer->undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
	step_pxe.insert(std::make_pair(pLayer->nextPxeID, el));
	pLayer->undoRedo.EndStep();
	pLayer->nextPxeID++;
	UpdateWindowTitle();
	UpdateMenuState();
	pDrawWnd.ResetEntityPlay();
	Draw();
}

void CMapEditor::OnTestpos()
{
	tinyxml2::XMLDocument xmlDoc;
	FILE* fp;
	_wfopen_s(&fp, L"./data/setting.xml", L"rb");
	if (!fp)
	{
		MessageBoxW(L"无法读取setting.xml文件", L"载入配置文件失败", MB_ICONERROR);
		return;
	}
	fseek(fp, 0, SEEK_END);
	size_t fileLen = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	std::vector<char> byte_buff;
	byte_buff.resize(fileLen + 1);
	fread_s(byte_buff.data(), fileLen, fileLen, 1, fp);
	fclose(fp);
	xmlDoc.Parse(byte_buff.data());
	//寻找目标元素
	tinyxml2::XMLElement* elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "MapTest"))
		{
			elem = pElem;
			break;
		}
	}
	if (!elem)
	{
		MessageBoxW(L"配置文件找不到MapTest元素", L"读取配置文件设置失败", MB_ICONERROR);
		return;
	}
	std::vector<wchar_t> wbuff;
	UTF8ToUTF16(elem->Attribute("mychar_player1"), &wbuff);

	MyView& view = *pDrawWnd.GetMyView();
	CString cmd;
	cmd.Format(L"spiky.exe MapTest %s %s %d %d", mapfilename.GetString(), wbuff.data(), view.cursorX, view.cursorY);
	MyWinExec(cmd.GetString());
}

void CMapEditor::OnSetRecordEndPos()
{
	MyView& view = *pDrawWnd.GetMyView();
	recordEndPos_x = view.cursorX;
	recordEndPos_y = view.cursorY;
	pDrawWnd.Draw();
}

void CMapEditor::OnStartRecord()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& layer = *pLayer;
	if (layer.selected_entity < 0)
		return;
	auto& step_pxe = *layer.GetPxeStep();
	auto iter = step_pxe.find(layer.selected_entity);
	if (iter == step_pxe.end())
		return;
	EntityLoad& el = iter->second;
	//读取XML文件
	tinyxml2::XMLDocument xmlDoc;
	FILE* fp;
	_wfopen_s(&fp, L"./data/setting.xml", L"rb");
	if (!fp)
	{
		MessageBoxW(L"无法读取setting.xml文件", L"载入配置文件失败", MB_ICONERROR);
		return;
	}
	fseek(fp, 0, SEEK_END);
	size_t fileLen = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	std::vector<char> byte_buff;
	byte_buff.resize(fileLen + 1);
	fread_s(byte_buff.data(), fileLen, fileLen, 1, fp);
	fclose(fp);
	xmlDoc.Parse(byte_buff.data());
	//寻找目标元素
	tinyxml2::XMLElement* elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "Record"))
		{
			elem = pElem;
			break;
		}
	}
	if (!elem)
	{
		MessageBoxW(L"配置文件找不到Record元素", L"读取配置文件设置失败", MB_ICONERROR);
		return;
	}
	std::vector<wchar_t> wbuff;
	UTF8ToUTF16(elem->Attribute("mychar_player1"), &wbuff);
	//启动游戏Exe程序
	MyView& view = *pDrawWnd.GetMyView();
	CString cmd;
	cmd.Format(L"spiky.exe Record %s %s %d %d %d %d", mapfilename.GetString(), wbuff.data(), view.cursorX, view.cursorY, recordEndPos_x, recordEndPos_y);
	MyWinExec(cmd.GetString());
	CWaitRecord dlg;
	dlg.DoModal();
	//压缩并转换成base64储存
	std::vector<BYTE> compressData;
	size_t outLen = 0;
	ZLibCompressData(&compressData, &outLen, dlg.outRecord.data(), dlg.outRecord.size() * sizeof(DWORD));
	//转换Base64
	std::string base64;
	Base64Encode(base64, compressData.data(), outLen);
	//转成wchar_t
	UTF8ToUTF16(base64.c_str(), &wbuff);
	//编辑
	layer.undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
	el.arg3 = wbuff.data();
	pDrawWnd.ResetEntityPlay();
	Draw();
}

void CMapEditor::OnEnChangeEditEntityname()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& layer = *pLayer;
	if (layer.selected_entity < 0)
		return;
	auto& step_pxe = *layer.GetPxeStep();
	CString str;
	edit_entityName.GetWindowTextW(str);
	auto iter = step_pxe.find(layer.selected_entity);
	if (iter == step_pxe.end())
		return;
	EntityLoad& el = iter->second;
	if (str != el.name.c_str())
	{
		layer.undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
		el.name = str.GetString();
		pDrawWnd.ResetEntityPlay();
		Draw();
	}
}


void CMapEditor::OnEnChangeEditEntityid()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& layer = *pLayer;
	if (layer.selected_entity < 0)
		return;
	auto& step_pxe = *layer.GetPxeStep();
	CString str;
	edit_entityID.GetWindowTextW(str);
	auto iter = step_pxe.find(layer.selected_entity);
	if (iter == step_pxe.end())
		return;
	EntityLoad& el = iter->second;
	if (str != el.eid.c_str())
	{
		layer.undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
		el.eid = str.GetString();
		pDrawWnd.ResetEntityPlay();
		Draw();
	}
}


void CMapEditor::OnEnChangeEditEvent()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& layer = *pLayer;
	if (layer.selected_entity < 0)
		return;
	auto& step_pxe = *layer.GetPxeStep();
	CString str;
	edit_event.GetWindowTextW(str);
	auto iter = step_pxe.find(layer.selected_entity);
	if (iter == step_pxe.end())
		return;
	EntityLoad& el = iter->second;
	if (str != el.eventName.c_str())
	{
		layer.undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
		el.eventName = str.GetString();
		pDrawWnd.ResetEntityPlay();
		Draw();
	}
}

void CMapEditor::OnEnChangeEditArg()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& layer = *pLayer;
	if (layer.selected_entity < 0)
		return;
	auto& step_pxe = *layer.GetPxeStep();
	CString str;
	edit_arg.GetWindowTextW(str);
	auto iter = step_pxe.find(layer.selected_entity);
	if (iter == step_pxe.end())
		return;
	EntityLoad& el = iter->second;
	if (str != el.arg.c_str())
	{
		layer.undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
		el.arg = str.GetString();
		pDrawWnd.ResetEntityPlay();
		Draw();
	}
}

void CMapEditor::OnEnChangeEditArg2()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& layer = *pLayer;
	if (layer.selected_entity < 0)
		return;
	auto& step_pxe = *layer.GetPxeStep();
	CString str;
	edit_arg2.GetWindowTextW(str);
	auto iter = step_pxe.find(layer.selected_entity);
	if (iter == step_pxe.end())
		return;
	EntityLoad& el = iter->second;
	if (str != el.arg2.c_str())
	{
		layer.undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
		el.arg2 = str.GetString();
		pDrawWnd.ResetEntityPlay();
		Draw();
	}
}

void CMapEditor::OnEnChangeEditArg3()
{
	MyMapLayer* pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	auto& layer = *pLayer;
	if (layer.selected_entity < 0)
		return;
	auto& step_pxe = *layer.GetPxeStep();
	CString str;
	edit_arg3.GetWindowTextW(str);
	auto iter = step_pxe.find(layer.selected_entity);
	if (iter == step_pxe.end())
		return;
	EntityLoad& el = iter->second;
	if (str != el.arg3.c_str())
	{
		layer.undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
		el.arg3 = str.GetString();
		pDrawWnd.ResetEntityPlay();
		Draw();
	}
}

void CMapEditor::OnTvnSelchangedTreeEntitylist(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
	*pResult = 0;
	auto pLayer = GetSelectLayer();
	if (!pLayer)
		return;
	if (pLayer->selected_entity < 0)
		return;
	auto& step_pxe = *pLayer->GetPxeStep();
	auto iter = step_pxe.find(pLayer->selected_entity);
	if (iter == step_pxe.end())
		return;
	auto item = tree_entityList.GetSelectedItem();
	if (!item)
		return;
	CString str = tree_entityList.GetItemText(item).GetString();
	//如果带了".dll"则不改变
	if (str.Find(L".dll") >= 0)
		return;
	if (str != iter->second.name.c_str())
	{
		pLayer->undoRedo.BeginStep(CMAPEDITOR_DATATYPE_PXE_STR);
		iter->second.name = str.GetString();
		pDrawWnd.ResetEntityPlay();
		Draw();
	}
}

void CMapEditor::RedrawControlWnd()
{
	//控件重绘
	CRect rc;
	static_info->GetClientRect(&rc);
	static_info->InvalidateRect(&rc);
}

void CMapEditor::ShowMapInfo(bool bShow)
{
	auto v = bShow ? SW_SHOW : SW_HIDE;
	radio_paint.ShowWindow(v);
	radio_replace.ShowWindow(v);
	radio_fill.ShowWindow(v);
	radio_rect.ShowWindow(v);
	radio_copy.ShowWindow(v);
	radio_paste.ShowWindow(v);
	button_brushWnd.ShowWindow(v);
	pBrushPreview.ShowWindow(v);
	auto m = bShow ? MF_ENABLED : MF_DISABLED;
	GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_WALL_ADJUST, m);
}

void CMapEditor::ShowEntityInfo(bool bShow)
{
	auto v = bShow ? SW_SHOW : SW_HIDE;
	static_entityType->ShowWindow(v);
	edit_entityName.ShowWindow(v);
	static_entityID->ShowWindow(v);
	edit_entityID.ShowWindow(v);
	static_entityOption->ShowWindow(v);
	button_entityOption.ShowWindow(v);
	static_event->ShowWindow(v);
	edit_event.ShowWindow(v);
	static_arg->ShowWindow(v);
	edit_arg.ShowWindow(v);
	static_arg2->ShowWindow(v);
	edit_arg2.ShowWindow(v);
	static_arg3->ShowWindow(v);
	edit_arg3.ShowWindow(v);
}

void CMapEditor::EnableControl(bool bEnable)
{
	//实体列表
	static_layerList->EnableWindow(bEnable);
	list_layerList.EnableWindow(bEnable);
	OnLbnSelchangeListLayerlist();
}

void CMapEditor::EnableEdit(bool bEnable)
{
	//显示
	static_display->EnableWindow(bEnable);
	radio_editMap.EnableWindow(bEnable);
	radio_editEntity.EnableWindow(bEnable);
	check_fGround.EnableWindow(bEnable);
	check_entity.EnableWindow(bEnable);
	check_bGround.EnableWindow(bEnable);
	check_entityLabel.EnableWindow(bEnable);
	check_bk.EnableWindow(bEnable);
	check_entityShow.EnableWindow(bEnable);
	check_pxaType.EnableWindow(bEnable);
	check_grid.EnableWindow(bEnable);
	//信息
	EnableMapEdit(bEnable);
	//实体信息
	if (!bEnable)
		EnableEntityEdit(false);
}

void CMapEditor::EnableMapEdit(bool bEnable)
{
	static_info->EnableWindow(bEnable);
	radio_paint.EnableWindow(bEnable);
	radio_replace.EnableWindow(bEnable);
	radio_fill.EnableWindow(bEnable);
	radio_rect.EnableWindow(bEnable);
	radio_copy.EnableWindow(bEnable);
	radio_paste.EnableWindow(bEnable);
	button_brushWnd.EnableWindow(bEnable);
	auto m = bEnable ? MF_ENABLED : MF_DISABLED;
	GetMenu()->GetSubMenu(CMAPEDITOR_MENUINDEX_EDIT)->EnableMenuItem(ID_WALL_ADJUST, m);
}

void CMapEditor::EnableEntityEdit(bool bEnable)
{
	static_entityType->EnableWindow(bEnable);
	edit_entityName.EnableWindow(bEnable);
	static_entityID->EnableWindow(bEnable);
	edit_entityID.EnableWindow(bEnable);
	static_entityOption->EnableWindow(bEnable);
	button_entityOption.EnableWindow(bEnable);
	static_event->EnableWindow(bEnable);
	edit_event.EnableWindow(bEnable);
	static_arg->EnableWindow(bEnable);
	edit_arg.EnableWindow(bEnable);
	static_arg2->EnableWindow(bEnable);
	edit_arg2.EnableWindow(bEnable);
	static_arg3->EnableWindow(bEnable);
	edit_arg3.EnableWindow(bEnable);
}

void CMapEditor::StepCopyToSaved()
{
	saved = mapSet;
}

CString CMapEditor::GetSelectLayerName()
{
	int sel = list_layerList.GetCurSel();
	if (sel < 0)
		return L"";
	CString name;
	list_layerList.GetText(sel, name);
	return name;
}

void CMapEditor::SwitchPaintMenu(MyMapLayer* pLayer)
{
	if (pLayer->layerType == 2)
	{
		if (radio_paste.GetCheck())
		{
			radio_paste.SetCheck(false);
			radio_paint.SetCheck(true);
			OnBnClickedRadioPaint();
		}
		radio_copy.SetWindowTextW(L"擦除");
		radio_paste.ShowWindow(SW_HIDE);
	}
	else
	{
		radio_copy.SetWindowTextW(L"复制");
		if (radio_editMap.GetCheck())
			radio_paste.ShowWindow(SW_SHOW);
	}
}

void CMapEditor::RefreshEntityList()
{
	tree_entityList.DeleteAllItems();
	auto entityRes = pDrawWnd.GetEntityRes();
	std::unordered_map<std::wstring, std::vector<std::wstring>> infoList;
	entityRes->GetLoadedEntityDllInfo(&infoList);
	for (auto& p : infoList)
	{
		HTREEITEM item = tree_entityList.InsertItem(p.first.c_str(), TVI_ROOT);
		for (auto& t : p.second)
			tree_entityList.InsertItem(t.c_str(), item);
	}
}
