/* Copyright 2015, Michele Santullo
 * This file is part of DoorKeeper.
 *
 * DoorKeeper is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * DoorKeeper is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with DoorKeeper.  If not, see <http://www.gnu.org/licenses/>.
 */

namespace dk {
	///--------------------------------------------------------------------------
	///--------------------------------------------------------------------------
	template <uint32_t D>
	LayerBase<D>::LayerBase (const coords& parCount, const coords& parTileSize, const coords& parMasterTileSize) :
		m_count(parCount / (parMasterTileSize / parTileSize)),
		m_tilesize(parTileSize),
		m_mastersize(parMasterTileSize),
		m_haveFrom(0),
		m_haveTo(0)
	{
		DK_ASSERT((parMasterTileSize / parTileSize) * parTileSize == parMasterTileSize);
	}

	///--------------------------------------------------------------------------
	///--------------------------------------------------------------------------
	template <uint32_t D>
	void LayerBase<D>::preload (const coords& parFrom, const coords& parTo) {
		if (parFrom < m_haveFrom or parTo > m_haveTo) {
			this->onPreload(parFrom, parTo);
			m_haveFrom = parFrom;
			m_haveTo = parTo;
		}
	}

	///--------------------------------------------------------------------------
	///--------------------------------------------------------------------------
	template <typename T, uint32_t D>
	Layer<T, D>::Layer (const coords& parTileSize, const coords& parMasterTileSize, BaseMapSource<D>* parTilemap) :
		LayerBase<D>(parTilemap->mapSize(), parTileSize, parMasterTileSize),
		m_tilemap(parTilemap)
	{
		DK_ASSERT(m_tilemap);
	}

	///--------------------------------------------------------------------------
	///--------------------------------------------------------------------------
	template <typename T, uint32_t D>
	typename Layer<T, D>::iterator Layer<T, D>::begin() {
		return iterator(&m_tiles, m_tilemap->pixel_conv(), coords(0), this->m_count);
	}

	///--------------------------------------------------------------------------
	///--------------------------------------------------------------------------
	template <typename T, uint32_t D>
	typename Layer<T, D>::iterator Layer<T, D>::end() {
		return iterator(&m_tiles, m_tilemap->pixel_conv(), make_past_end_coords<D>(this->m_count - 1), make_past_end_coords<D>(this->m_count - 1));
	}

	///--------------------------------------------------------------------------
	///--------------------------------------------------------------------------
	template <typename T, uint32_t D>
	void Layer<T, D>::onPreload (const coords& parFrom, const coords& parTo) {
		m_tiles.clear();
		m_tilemap->fetch(m_tiles, parFrom, parTo);
#if !defined(NDEBUG)
		std::cout << "Preloading layer from " << parFrom << " to " << parTo << '\n';
#endif
	}
}
