#pragma once
#include <SDL2/SDL.h>

#include "utils.h"
#include "const.h"
#include "sprite.h"
#include "animatedsprite.h"
#include "text.h"
#include "input.h"
#include "screen.h"
#include "asset.h"
#include "room.h"
#include "item_tracker.h"
#include "room_tracker.h"
#include "player.h"
#include "jail_audio.h"
#include "scoreboard.h"
#include "debug.h"
#include "test.h"

#ifndef GAME_H
#define GAME_H

// Game
class Game
{
private:
	SDL_Renderer *renderer;	  // El renderizador de la ventana
	SDL_Event *eventHandler;  // Manejador de eventos
	Screen *screen;			  // Objeto encargado de manejar el renderizador
	Room *room;				  // Objeto encargado de gestionar cada habitación del juego
	Player *player;			  // Objeto con el jugador
	ItemTracker *itemTracker; // Lleva el control de los objetos recogidos
	RoomTracker *roomTracker; // Lleva el control de las habitaciones visitadas
	Asset *asset;			  // Objeto con la ruta a todos los ficheros de recursos
	Input *input;			  // Objeto pata gestionar la entrada
	Text *text;				  // Objeto para los textos del juego
	ScoreBoard *scoreboard;	  // Objeto encargado de gestionar el marcador
	JA_Music music;			  // Musica que suena durante el juego
	Debug *debug;			  // Objeto para gestionar la información de debug
	Uint32 ticks;				  // Contador de ticks para ajustar la velocidad del programa
	Uint32 ticksSpeed;			  // Velocidad a la que se repiten los bucles del programa
	section_t section;		  // Seccion actual dentro del juego
	std::string currentRoom;  // Fichero de la habitación actual
	player_t spawnPoint;	  // Lugar de la habitación donde aparece el jugador
	JA_Sound deathSound;	  // Sonido a reproducir cuando muere el jugador
	board_t board;			  // Estructura con los datos del marcador
	bool paused;			  // Indica si el juego se encuentra en pausa
	bool blackScreen;		  // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador
	int blackScreenCounter;	  // Contador para temporizar la pantalla en negro
	Test *test;

	// Actualiza el juego, las variables, comprueba la entrada, etc.
	void update();

	// Pinta los objetos en pantalla
	void render();

	// Comprueba los eventos de la cola
	void checkEventHandler();

	// Pone la información de debug en pantalla
	void updateDebugInfo();

	// Pone la información de debug en pantalla
	void renderDebugInfo();

	// Escribe el nombre de la pantalla
	void renderRoomName();

	// Cambia de habitación
	bool changeRoom(std::string file);

	// Comprueba si el jugador esta en el borde de la pantalla y actua
	void checkPlayerOnBorder();

	// Comprueba las colisiones del jugador con los enemigos
	bool checkPlayerAndEnemies();

	// Comprueba las colisiones del jugador con los objetos
	void checkPlayerAndItems();

	// Comprueba si el jugador esta vivo
	void checkIfPlayerIsAlive();

	// Comprueba si ha terminado la partida
	void checkEndGame();

	// Mata al jugador
	void killPlayer();

	// Recarga todas las texturas
	void reLoadTextures();

	// Establece la pantalla en negro
	void setBlackScreen();

	// Actualiza las variables relativas a la pantalla en negro
	void updateBlackScreen();

	// Dibuja la pantalla negra
	void renderBlackScreen();
	
public:
	// Constructor
	Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Debug *debug);

	// Destructor
	~Game();

	// Bucle para el juego
	section_t run();
};

#endif
