//	Darkstar Engine  (c) UnderWorld Interactive Studio (all coding by Svarog    2008)
//
//      Данный файл является частью Darkstar Engine. Любое использование кода файла
//      без согласия компании, является нарушением закона об авторском праве (в слу-
//      чае если не оговорено обратное).
//
//      Имя файла: parser_class.hpp
//      Краткое описание: Парсер для файлов со стандартной семантикой
//

#ifndef DSE_KERNEL_PARSER_PARSER_CLASS_HPP
#define DSE_KERNEL_PARSER_PARSER_CLASS_HPP

#include <Darkstar/common.hpp>
#include <Darkstar/Kernel/FileSystem/dfile.hpp>

namespace ker
{
	struct Pair
	{
		std::string name;
		std::string value;
	};

	struct PairInfo
	{
		std::string value;
		unsigned int line_in_file;
	};

	struct Section
	{
		unsigned int section_start_line;

		std::string section_name;
		// if it exists
		std::string section_value;
		std::vector<shared_ptr<Section> > sections;
		std::map<std::string, PairInfo> values;

		Section(const std::string& name, const std::string& value = "");
	};

	static const std::string ROOT_SECTION_NAME = "";

	class Parser
	{
	private:
		std::string filename;

		shared_ptr<Section> root_section;

		shared_ptr<Section> cur_section;

		enum STRING_TYPE
		{
			UNKNOWN = -1,
			OPEN_BRACKET = 0,
			CLOSE_BRACKET = 1,
			SECTION_NAME = 2,
			SECTION_NAME_VALUE = 3,
			PAIR_NAME_VALUE = 4,
		};

		struct FileString
		{
			std::string str;
			unsigned int number;
			STRING_TYPE type;
		};

		std::vector<FileString> file;

		bool was_success;
		bool permit_space_in_value;

		unsigned int cur_string_num;

		bool _parseNextBlock();
		bool _parseStringToPair(const std::string& str, Pair& pair, bool value_can_be_empty = false) const;

		// return false if must be skip
		// return true and convert string to suitable format in other cases
		bool _processString(std::string& str) const;
		bool _getStringType(unsigned int number);
	public:
		Parser(DFile& file, bool permit_space_in_values = false);
		~Parser();

		bool getIsParsedSuccessfully() const;

		const shared_ptr<Section>& getRootSection() const;
	};
};

#endif