#ifndef idD3EDC396AA314474B3D909559FFC0247
#define idD3EDC396AA314474B3D909559FFC0247

#include "doorkeeper/primitivetypes.hpp"
#include "doorkeeper/components/tileiterator.hpp"
#include "doorkeeper/components/basemapsource.hpp"
#include "doorkeeper/implem/helpers.hpp"
#include <algorithm>
#include <vector>
#include <memory>
#include <cstdint>
#if !defined(NDEBUG)
#include <iostream>
#endif

namespace dk {
	template <uint32_t D>
	class Viewport;

	template <uint32_t D>
	class LayerBase {
	public:
		typedef Vector<D> coords;

		LayerBase ( const coords& parCount, const coords& parTileSize, const coords& parMasterTileSize );
		virtual ~LayerBase ( void ) noexcept = default;

		void preload ( const coords& parFrom, const coords& parTo );
		coords count ( void ) const { return m_mastersize / m_tilesize * m_count; }
		const coords& mapSize ( void ) const { return m_count; }

	protected:
		coords m_count;
		coords m_tilesize;
		coords m_mastersize;

	private:
		virtual void onPreload ( const coords& parFrom, const coords& parTo ) = 0;

		coords m_haveFrom;
		coords m_haveTo;
	};

	template <typename T, uint32_t D>
	class Layer : public LayerBase<D> {
		friend class Viewport<D>;

	public:
		typedef typename LayerBase<D>::coords coords;
		typedef TileIterator<T, D> iterator;
		typedef TileIterator<const T, D> const_iterator;

		Layer ( const Layer& ) = delete;
		Layer ( Layer&& ) = default;
		Layer ( const coords& parTileSize, const coords& parMasterTileSize, BaseMapSource<D>* parTilemap );
		virtual ~Layer ( void ) noexcept = default;

		Layer& operator= ( const Layer& ) = delete;

		iterator begin ( void );
		iterator end ( void );

	private:
		virtual void onPreload ( const coords& parFrom, const coords& parTo );

		std::vector<T> m_tiles;
		BaseMapSource<D>* m_tilemap;
	};
} //namespace dk

#include "doorkeeper/implem/layer.inl"

#endif
