/*
	Copyright 2016, 2017 Michele "King_DuckZ" Santullo

	This file is part of MyCurry.

	MyCurry 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.

	MyCurry 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 MyCurry.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "texture.hpp"
#include "sdlmain.hpp"
#include <SDL_image.h>
#include <cassert>

namespace curry {
	namespace {
		using SDLTextureAuto = std::unique_ptr<SDL_Texture, void(*)(SDL_Texture*)>;

		SDLTextureAuto load_texture (const char* parPath, cloonel::SDLMain& parSDLMain, bool parWithKey, RGBA parKey) {
			using SurfaceType = std::unique_ptr<SDL_Surface, void(*)(SDL_Surface*)>;

			SurfaceType surface(IMG_Load(parPath), &SDL_FreeSurface);
			if (parWithKey) {
				SDL_SetColorKey(
					surface.get(),
					SDL_TRUE,
					SDL_MapRGB(surface->format, parKey.r, parKey.g, parKey.b)
				);
			}
			return SDLTextureAuto(
				SDL_CreateTextureFromSurface(parSDLMain.GetRenderer(), surface.get()),
				&SDL_DestroyTexture
			);
		}
	} //unnamed namespace

	Texture::Texture() :
		m_texture(nullptr, &SDL_DestroyTexture)
	{
	}

	Texture::Texture (const char* parPath, cloonel::SDLMain& parSDLMain) :
		Texture()
	{
		this->load(parPath, parSDLMain);
	}

	Texture::~Texture() noexcept = default;

	SDL_Texture* Texture::texture() {
		return m_texture.get();
	}

	const SDL_Texture* Texture::texture() const {
		return m_texture.get();
	}

	void Texture::load (const char* parPath, cloonel::SDLMain& parSDLMain) {
		m_texture = load_texture(parPath, parSDLMain, false, RGBA());
	}

	void Texture::load (const char* parPath, cloonel::SDLMain& parSDLMain, RGBA parColorKey) {
		m_texture = load_texture(parPath, parSDLMain, true, parColorKey);
	}

	void Texture::unload() noexcept {
		m_texture.reset(nullptr);
	}

	vec2us Texture::width_height() const {
		int w, h;
		assert(m_texture);
		SDL_QueryTexture(m_texture.get(), nullptr, nullptr, &w, &h);
		return vec2us(static_cast<uint16_t>(w), static_cast<uint16_t>(h));
	}
} //namespace curry
