#include "fade.h"
#include "const.h"

// Constructor
Fade::Fade(SDL_Renderer *renderer)
{
	mRenderer = renderer;

	mBackbuffer = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAME_WIDTH, GAME_HEIGHT);
	if (mBackbuffer == nullptr)
		printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError());
}

// Destructor
Fade::~Fade()
{
	SDL_DestroyTexture(mBackbuffer);
	mBackbuffer = nullptr;
}

// Inicializa las variables
void Fade::init(Uint8 r, Uint8 g, Uint8 b)
{
	mFadeType = FADE_CENTER;
	mEnabled = false;
	mFinished = false;
	mCounter = 0;
	mR = r;
	mG = g;
	mB = b;
}

// Pinta una transición en pantalla
void Fade::render()
{
	if (mEnabled && !mFinished)
	{
		switch (mFadeType)
		{
		case FADE_FULLSCREEN:
			mRect1 = {0, 0, GAME_WIDTH, GAME_HEIGHT};

			for (int i = 0; i < 256; i += 4)
			{
				// Dibujamos sobre el renderizador
				SDL_SetRenderTarget(mRenderer, nullptr);

				// Copia el backbuffer con la imagen que había al renderizador
				SDL_RenderCopy(mRenderer, mBackbuffer, nullptr, nullptr);

				SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, i);
				SDL_RenderFillRect(mRenderer, &mRect1);

				// Vuelca el renderizador en pantalla
				SDL_RenderPresent(mRenderer);
			}

			// Deja todos los buffers del mismo color
			SDL_SetRenderTarget(mRenderer, mBackbuffer);
			SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
			SDL_RenderClear(mRenderer);

			SDL_SetRenderTarget(mRenderer, nullptr);
			SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
			SDL_RenderClear(mRenderer);
			break;

		case FADE_CENTER:
			mRect1 = {0, 0, GAME_WIDTH, 0};
			mRect2 = {0, 0, GAME_WIDTH, 0};

			SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 64);

			for (int i = 0; i < mCounter; i++)
			{
				mRect1.h = mRect2.h = i * 4;
				mRect2.y = GAME_HEIGHT - (i * 4);

				SDL_RenderFillRect(mRenderer, &mRect1);
				SDL_RenderFillRect(mRenderer, &mRect2);
			}

			if ((mCounter * 4) > GAME_HEIGHT)
				mFinished = true;
			break;

		case FADE_RANDOM_SQUARE:
			mRect1 = {0, 0, 32, 32};

			for (Uint16 i = 0; i < 50; i++)
			{
				// Crea un color al azar
				mR = 255 * (rand() % 2);
				mG = 255 * (rand() % 2);
				mB = 255 * (rand() % 2);
				SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 64);

				// Dibujamos sobre el backbuffer
				SDL_SetRenderTarget(mRenderer, mBackbuffer);

				mRect1.x = rand() % (GAME_WIDTH - mRect1.w);
				mRect1.y = rand() % (GAME_HEIGHT - mRect1.h);
				SDL_RenderFillRect(mRenderer, &mRect1);

				// Volvemos a usar el renderizador de forma normal
				SDL_SetRenderTarget(mRenderer, nullptr);

				// Copiamos el backbuffer al renderizador
				SDL_RenderCopy(mRenderer, mBackbuffer, nullptr, nullptr);

				// Volcamos el renderizador en pantalla
				SDL_RenderPresent(mRenderer);
				SDL_Delay(100);
			}
			break;

		default:
			break;
		}
	}

	if (mFinished)
	{
		SDL_SetRenderDrawColor(mRenderer, mR, mG, mB, 255);
		SDL_RenderClear(mRenderer);
	}
}

// Actualiza las variables internas
void Fade::update()
{
	if (mEnabled)
		mCounter++;
}

// Activa el fade
void Fade::activateFade()
{
	mEnabled = true;
	mFinished = false;
	mCounter = 0;
}

// Comprueba si está activo
bool Fade::isEnabled()
{
	return mEnabled;
}

// Comprueba si ha terminado la transicion
bool Fade::hasEnded()
{
	return mFinished;
}

// Establece el tipo de fade
void Fade::setFadeType(Uint8 fadeType)
{
	mFadeType = fadeType;
}