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

#include "utils.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 "player.h"
#include "jail_audio.h"
#include "scoreboard.h"
#include "debug.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
	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
	bool musicEnabled;		  // Indica si ha de sonar la musica durante el juego
	int ticks;				  // Contador de ticks para ajustar la velocidad del programa
	int 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
	bool debugEnabled;		  // Indica si el modo debug está activo
	int playerLives;		  // Lleva la cuenta de ls vidas restantes del jugador
	int itemsPicked;		  // Lleva la cuenta de los objetos recogidos
	Uint32 clock;			  // Cuenta el tiempo que dura la partida

	// 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();

	// Mata al jugador
	void killPlayer();

	// Recarga todas las texturas
	void reLoadTextures();

public:
	// Constructor
	Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Debug *debug);

	// Destructor
	~Game();

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

#endif
