void UserSettingsParser::Parse(LPCTSTR path, SchemeLoaderState* pState)
{
	if(!FileExists(path))
	{
		return;
	}

	XMLParserCallback<UserSettingsParser> callback(*this, &UserSettingsParser::startElement, &UserSettingsParser::endElement, &UserSettingsParser::characterData);

	XMLParser parser;
	parser.SetParseState(&callback);
	
	callback.SetUserData((void*)pState);

	pState->m_pParser = &parser;

	pState->m_State = 0;

	try
	{
		parser.LoadFile(path);
	}
	catch (SchemeParserException& E)
	{
		CString err;
		err.Format(_T("Error Parsing Scheme UserSettings XML: %s\n (file: %s, line: %d, column %d)"), 
			E.GetMessage(), E.GetFileName(), E.GetLine(), E.GetColumn());
		
		LOG(err);
	}
	catch (XMLParserException& E)
	{
		CString err;
		err.Format(_T("Error Parsing Scheme UserSettings XML: %s\n (file: %s, line: %d, column %d)"), 
			XML_ErrorString(E.GetErrorCode()), E.GetFileName(), E.GetLine(), E.GetColumn());
		
		LOG(err);
	}
}
void Level::ParseLevelConfig(std::wstring fileName)
{
	XMLParser* parser = new XMLParser();
	parser->LoadFile(fileName);

	while (parser->Parse(L"Level"))
	{
		// Skip the tag if its not an opening tag.
		if (parser->GetTagType() != XMLParser::OPENING)
		{
			continue;
		}

		// Read the tag if its an opening tag
		std::wstring tagName = parser->GetTagName();
		std::wstring tagContent = parser->GetTagContent();

		if (tagName.compare(L"ID") == 0)
		{
			m_LevelName = tagContent;
		}
		else if (tagName.compare(L"StandardConfig") == 0)
		{
			m_StandardConfigPath = tagContent;
		}
		else if (tagName.compare(L"SVG") == 0)
		{
			m_SVGPath = tagContent;
			m_ActorLayoutPtr->AddSVGShape(String(m_SVGPath.c_str()));
		}
		else if (tagName.compare(L"Visuals") == 0)
		{
			m_VisualsPath = tagContent;
			m_ImgVisualsPtr = new Bitmap(String(m_VisualsPath.c_str()));

			// Add a polygonal shape around the level
			std::vector<DOUBLE2> levelBoundaries(4);
			levelBoundaries[0] = DOUBLE2(0, 0);
			levelBoundaries[1] = DOUBLE2(0, m_ImgVisualsPtr->GetHeight());
			levelBoundaries[2] = DOUBLE2(m_ImgVisualsPtr->GetWidth(), m_ImgVisualsPtr->GetHeight());
			levelBoundaries[3] = DOUBLE2(m_ImgVisualsPtr->GetWidth(), 0);

			m_ActorLayoutPtr->AddChainShape(levelBoundaries, true);
		}
		else if (tagName.compare(L"Shadows") == 0)
		{
			m_ShadowsPath = tagContent;
			m_ImgShadowsPtr = new Bitmap(String(m_ShadowsPath.c_str()));
		}
		else if (tagName.compare(L"Navigation") == 0)
		{
			// Loads an image that is converted and used a navigation grid
			m_NavigationPath = tagContent;
			Bitmap* navigationImg = new Bitmap(String(m_NavigationPath.c_str()));
			// Create a navigation grid for the pathfinding algorithm.
			std::vector<std::vector<COLOR>> rawPixelData = navigationImg->GetRawPixelData();
			m_NavigationGrid = std::vector<std::vector<bool>>(navigationImg->GetHeight(), std::vector<bool>(navigationImg->GetWidth()));
			for (int i = 0; i < navigationImg->GetHeight(); ++i)
			{
				for (int j = 0; j < navigationImg->GetWidth(); ++j)
				{
					COLOR color = rawPixelData[i][j];
					int avarageValue = (color.red + color.green + color.blue) / 3;
					
					if (avarageValue < 128)
					{
						m_NavigationGrid[i][j] = false;
					}
					else
					{
						m_NavigationGrid[i][j] = true;
					}
				}

				rawPixelData[i].clear();
			}
			rawPixelData.clear();

			delete navigationImg;
			
		}
		else if (tagName.compare(L"Objective") == 0)
		{
			m_ObjectivePath = tagContent;
			m_ImgIntroPtr = new Bitmap(String(m_ObjectivePath.c_str()));
		}
		else if (tagName.compare(L"AudioMainMusic") == 0)
		{
			m_AudioMainMusic = tagContent;
		}
		else if (tagName.compare(L"AudioCompletedMusic") == 0)
		{
			m_AudioCompletedMusic = tagContent;
		}
		else if (tagName.compare(L"AudioCompletedEffect") == 0)
		{
			m_AudioCompletedEffect = tagContent;
		}
		else if (tagName.compare(L"EndZone") == 0)
		{
			if (m_EndZonePtr != nullptr)
			{
				DeleteResource(m_EndZonePtr);
			}

			m_EndZonePtr = new LevelEndZone(parser);
			m_EndZonePtr->SetActive(false);
		}
		else if (tagName.compare(L"Score") == 0)
		{
			if (m_ScorePtr != nullptr)
			{
				DeleteResource(m_ScorePtr);
			}

			m_ScorePtr = new LevelScore(parser);
		}
		else if (tagName.compare(L"TargetTime") == 0)
		{
			m_TargetCompletionTime = std::stod(tagContent);
		}
		else if (tagName.compare(L"Door") == 0)
		{
			m_DoorPtrs.push_back(new Door(parser));
		}
		else if (tagName.compare(L"Pickup") == 0)
		{
			m_PickupPtrs.push_back(new Pickup(parser));
		}
		else if (tagName.compare(L"Enemies") == 0)
		{

			// Sub-parsing level.
			// Per enemy type (a patrolling or stationary unit)
			while (parser->Parse(L"Enemies"))
			{
				if (parser->GetTagType() != XMLParser::OPENING)
				{
					continue;
				}

				tagName = parser->GetTagName();
				if (tagName.compare(L"Patrol") == 0)
				{
					m_EnemyPtrs.push_back(new PatrollingEnemy(parser));
				}
				else if (tagName.compare(L"Guard") == 0)
				{
					m_EnemyPtrs.push_back(new GuardingEnemy(parser));
				}
			}
		}
		else if (tagName.compare(L"Hostages") == 0)
		{
			// Sub-level parsing for hostages
			while (parser->Parse(L"Hostages"))
			{
				if (parser->GetTagType() != XMLParser::OPENING)
				{
					continue;
				}

				tagName = parser->GetTagName();
				if (tagName.compare(L"Hostage") == 0)
				{
					m_HostagePtrs.push_back(new Hostage(parser));
				}
			}
		}
		else if (tagName.compare(L"Player") == 0)
		{
			m_PlayerPtr = new Player(parser);
			m_CameraPtr = new Camera(m_PlayerPtr);
			m_CameraPtr->Tick(0.0);

			m_HUD->SetTarget(m_PlayerPtr);
		}
	}

	delete parser;
}