#pragma once

#include <optional>
#include <string>
#include <variant>
#include <vector>
#include <stdexcept>
#include <functional>

namespace psemek::ui
{

	// Doesn't own the actual text. Instead,
	// it is supposed to reference a string
	// stored elsewhere. Beware of SSO!
	struct tagged_text
	{
		struct opening_tag
		{
			std::string type;
			std::optional<std::string> attribute;
		};

		struct closing_tag
		{
			std::string type;
		};

		using token = std::variant<std::string, opening_tag, closing_tag>;

		std::vector<token> tokens;

		struct parse_error
			: std::runtime_error
		{
			parse_error(std::string error, std::size_t position, std::string text);

			std::size_t position() const noexcept { return position_; }

		private:
			std::size_t position_;
		};

		static tagged_text parse(std::string_view text);

		using mapper = std::function<std::optional<std::vector<token>>(token const &)>;
	};

}
