#pragma once
#include <cstdint>
#include <vector>

#include "Deer/Enviroment.h"
#include "EntitySerializationStruct.h"

namespace Deer {
	struct EnvironmentEntity {
		Environment& environment;
		EnvironmentEntity(Environment& env) : environment(env) {}
	};

	template <class Archive>
	void save(Archive& archive, const Deer::Environment& environment) {
		EnvironmentEntity envEnt(const_cast<Deer::Environment&>(environment));
		archive(cereal::make_nvp("entities", envEnt));
	}

	template <class Archive>
	void load(Archive& archive, Deer::Environment& environment) {
		EnvironmentEntity envEnt(environment);
		archive(cereal::make_nvp("entities", envEnt));
	}

	template <class Archive>
	void save(Archive& archive, EnvironmentEntity const& m_entities) {
		archive(cereal::make_size_tag(static_cast<cereal::size_type>(
		    m_entities.environment.getEntityCount())));

		for (uint16_t i = 0; i < m_entities.environment.getEntityCount(); i++) {
			while (!m_entities.environment.entityExists(i)) {
				i++;
			}

			EntitySerializationStruct serializationStruct;
			serializationStruct.env =
			    const_cast<Environment*>(&m_entities.environment);
			serializationStruct.entityID = i;

			archive(serializationStruct);
		}
	}

	template <class Archive>
	void load(Archive& archive, EnvironmentEntity& m_entities) {
		cereal::size_type size;
		archive(cereal::make_size_tag(size));

		for (int i = 0; i < size; i++) {
			EntitySerializationStruct serializationStruct;
			serializationStruct.env = &m_entities.environment;

			archive(serializationStruct);
		}
	}
}  // namespace Deer