#include "GamePxa.h"
#include "main.h"
PxaData* GamePxa::GetPxa(const wchar_t* pxaName)
{
	auto iter = loadedPxa.find(pxaName);
	if (iter == loadedPxa.end())
	{
		PxaData pxaData;
		LoadPxa(&pxaData, pxaName);
		loadedPxa.insert(std::make_pair(pxaName, pxaData));
		return &loadedPxa.at(pxaName);
	}
	return &iter->second;
}

void GamePxa::LoadPxa(PxaData* outPxaData, const wchar_t* pxafileName)
{
	wchar_t wbuff[MAX_PATH];
	swprintf_s(wbuff, L"./data/pxa/%s.pxa", pxafileName);
	//载入文件数据
	FILE* fp;
	_wfopen_s(&fp, wbuff, L"rb");
	if (!fp)
	{
		wchar_t err[MAX_PATH];
		swprintf_s(err, L"找不到地形文件%s", wbuff);
		MessageBoxW(hwnd, err, L"载入资源错误", MB_ICONERROR);
		return;
	}
	fseek(fp, 0, SEEK_END);
	size_t fileLen = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	std::vector<BYTE> filebuff;
	filebuff.resize(fileLen);
	fread_s(filebuff.data(), filebuff.size(), fileLen, 1, fp);
	fclose(fp);
	std::vector<BYTE> byte_buff;
	size_t len = 0;
	ZLibUncompressData(&byte_buff, &len, filebuff.data(), fileLen);
	LoadPxaXML(outPxaData, (const wchar_t*)byte_buff.data());
}

void GamePxa::LoadPxaXML(PxaData* outPxaData, const wchar_t* xml)
{
	std::vector<char> gbk_buff;
	UTF16ToGBK(xml, &gbk_buff);
	tinyxml2::XMLDocument xmlDoc;
	xmlDoc.Parse(gbk_buff.data());
	tinyxml2::XMLElement* elem = nullptr;
	//寻找TileSet元素
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "TileSet"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem)
	{
		//读取TileSet
		outPxaData->tileW = elem->IntAttribute("TileW");
		outPxaData->tileH = elem->IntAttribute("TileH");
		outPxaData->bInterArea = elem->BoolAttribute("InterArea");
	}
	//寻找Pxa元素
	elem = nullptr;
	for (tinyxml2::XMLElement* pElem = xmlDoc.FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
	{
		if (!strcmp(pElem->Name(), "Pxa"))
		{
			elem = pElem;
			break;
		}
	}
	if (elem == nullptr)
	{
		MessageBoxW(hwnd, L"载入地图XML文件错误，找不到Pxa元素", L"载入资源错误", MB_ICONERROR);
		return;
	}
	outPxaData->pxa.clear();
	//遍历所有的ID元素
	for (elem = elem->FirstChildElement(); elem; elem = elem->NextSiblingElement())
	{
		//跳过不是Rect的元素
		if (strcmp(elem->Name(), "ID"))
			continue;
		//给step赋值
		auto& step = outPxaData->pxa;
		int x = elem->IntAttribute("x");
		int y = elem->IntAttribute("y");
		int pxa = elem->IntAttribute("pxa");
		step[MAKELONG(x, y)] = pxa;
	}
	//更新到数组的版本
	outPxaData->UpdatePxaArr();
}

bool GamePxa::IsBackPxa(int pxaID)
{
	return pxaID == 0 || pxaID == 0x40 || IsWindPxa(pxaID);
}

bool GamePxa::IsWindPxa(int pxaID)
{
	return (pxaID >= 0x60 && pxaID <= 0x67) || (pxaID >= 0x70 && pxaID <= 0x77);
}

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