#pragma once

#include "background.h"
#include "balloon.h"
#include "bullet.h"
#include "const.h"
#include "globals.h"
#include "ltexture.h"
#include "menu.h"
#include "player.h"
#include "struct.h"
#include "text.h"

#ifndef GAMEDIRECTOR_H
#define GAMEDIRECTOR_H

//GameDirector
class GameDirector
{
public:
	//Constructor
	GameDirector();

	//Iniciador
	void init();

	//Hace una pausa de milisegundos
	void sleep(Uint16 time);

	//Establece el valor de la variable
	void setScore(Uint32 score);

	//Establece el valor de la variable
	void setHiScore(Uint32 score);

	//Actualiza el valor de HiScore en caso necesario
	void updateHiScore();

	//Transforma un valor numérico en una cadena de 6 cifras
	std::string updateScoreText(Uint32 num);

	//Pinta el marcador en pantalla usando un objeto texto
	void renderScoreBoard(Text &text);

	//Mueve todos los globos activos
	void moveBalloons();

	//Pinta en pantalla todos los globos activos
	void renderBalloons();

	//Devuelve el primer indice no activo del vector de globos
	Uint8 getBallonFreeIndex();

	//Crea un globo nuevo en el vector de globos
	Uint8 createNewBalloon(int x, int y, Uint8 kind, float velx, Uint16 stoppedtimer);

	//Establece a cero todos los valores del vector de objetos globo
	void resetBalloons();

	//Explosiona un globo. Lo destruye y crea otros dos si es el caso
	void popBalloon(Uint8 index);

	//Detiene todos los globos
	void stopAllBalloons();

	//Pone en marcha todos los globos
	void startAllBalloons();

	//Obtiene el numero de globos activos
	Uint8 countBalloons();

	//Comprueba la colisión entre el jugador y los globos activos
	bool checkPlayerBallonCollision();

	//Comprueba y procesa la colisión entre las balas y los globos
	void processBulletBallonCollision();

	//Mueve las balas activas
	void moveBullets();

	//Pinta las balas activas
	void renderBullets();

	//Devuelve el primer indice no activo del vector de balas
	Uint8 getBulletFreeIndex();

	//Establece a cero todos los valores del vector de objetos bala
	void resetBullets();

	//Crea un objeto bala
	void createBullet(int x, int y, Uint8 kind);

	//Calcula y establece el valor de amenaza en funcion de los globos activos
	void calculateMenaceLevel();

	//Obtiene el valor de la variable
	Uint8 getMenaceLevel();

	//Gestiona el nivel de amenaza
	void checkMenaceLevel();

	//Gestiona la entrada de teclado y mando durante el juego
	void checkGameInput();

	//Gestiona la entrada de teclado y mando durante el menu
	void checkMenuInput(Menu* menu);

	//Obtiene el valor de la variable
	Uint8 getGameStatus();

	//Establece el valor de la variable
	void setGameStatus(Uint8 status);

	//Pinta una transición en pantalla
	void renderTransition(Uint8 index);

	//Pinta el texto GetReady en pantalla
	void renderGetReady();

	//Bucle para el titulo del juego
	void runTitle();

	//Bucle para el juego
	void runGame();

	//Bucle para el menu de pausa del juego
	void runPausedGame();

private:
	//Manejador de eventos
	SDL_Event eventHandler;

	//El jugador
	Player player;

	//Vector con los objetos globo
	Balloon balloon[50];
#ifdef TEST
	Balloon balloonTest;
	Bullet bulletTest;
#endif

	//Vector con los objetos bala
	Bullet bullet[50];

	//Fondo del juego
	Background gameBackground;

	//Fondo de la pantalla de titulo
	Background titleBackground;

	//Texto blanco
	Text whiteText;

	//Texto negro
	Text blackText;

	//Menu de la pantalla de título
	Menu menuTitle;

	//Menú de la pantalla de pausa
	Menu menuPause;

	//Indicador para el bucle principal
	Uint8 mGameStatus;

	//Puntuación actual y puntuación máxima
	Uint32 mScore;
	Uint32 mHiScore;

	//Cadena de texto con la puntuación actual y la puntuación máxima de 6 cifras
	std::string mScoreText;
	std::string mHiScoreText;

	//Número máximo de globos y balas que puede almacenar el vector
	Uint8 mMaxBalloons;
	Uint8 mMaxBullets;

	//Contador de ticks para ajustar la velocidad del juego
	Uint32 mOldTicks;

	//Velocidad a la que se repite el bucle de juego
	Uint8 mGameSpeed;

	//Nivel de amenaza actual
	Uint8 mMenaceLevel;

	//Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral,
	//se generan más globos. Si el umbral aumenta, aumenta el numero de globos
	Uint8 mMenaceLevelThreshold;

	//Indica si ha de aparecer el texto de GetReady en pantalla
	bool mGetReady;
};

#endif