#include "DeerRender/Shader.h"
#include "DeerStudio/EditorDataImporter.h"

namespace Deer {
	static std::unordered_map<std::string, std::string> preProcess(const std::string& source) {
		std::unordered_map<std::string, std::string> shaderSource;

		const std::string typeToken = "#type ";
		size_t pos = 0;

		while (pos < source.size()) {
			size_t typePos = source.find(typeToken, pos);
			if (typePos == std::string::npos)
				break;

			size_t typeEnd = source.find_first_of("\n\r", typePos);
			if (typeEnd == std::string::npos)
				break;

			std::string shaderType = source.substr(typePos + typeToken.size(), typeEnd - typePos - typeToken.size());
			size_t nextTypePos = source.find(typeToken, typeEnd);

			std::string shaderSourceStr = source.substr(typeEnd + 1, nextTypePos - typeEnd - 1);
			shaderSource[shaderType] = shaderSourceStr;

			pos = nextTypePos;
		}

		return shaderSource;
	}

	template <>
	Scope<ShaderData> StorageData::deserialize<EditorDataImporter, ShaderData>() {
		std::string str_data((char*)data.get(), size);

		std::unordered_map<std::string, std::string> types = preProcess(str_data);

		Scope<ShaderData> shaderData = MakeScope<ShaderData>();
		if (types.contains("vertex")) {
			shaderData->vertexShader = types["vertex"];
		}

		if (types.contains("fragment")) {
			shaderData->fragmentShader = types["fragment"];
		}

		return shaderData;
	}
} // namespace Deer