#pragma once
#include "ifdefs.h"
#include "sprite.h"
#include "movingsprite.h"
#include "player.h"
#include "map.h"
#include "text.h"
#include "const.h"
#include "jail_audio.h"
#include "utils.h"
#include "screen.h"
#include "asset.h"
#include <math.h>

#ifndef GAME_H
#define GAME_H

// director
class Director
{
private:
	struct _text // Objetos de texto
	{
		Text *white;
	};

	struct _options // Variables relacionadas con las opciones del juego
	{
		Uint32 fullScreenMode;		   // Guarda el valor elegido para el modo de pantalla completa
		Uint32 fullScreenModePrevious; // Guarda el valor previo del modo de pantalla completa
		Uint8 windowSize;			   // Guarda el valor elegido para el tamaño de la ventana
		Uint8 windowSizePrevious;	   // Guarda el valor previo del tamaño de la ventana
	};

	struct _game // Variables para el control del juego
	{
		Uint32 score;	  // Puntuación actual
		Uint8 section;	  // Indicador para el bucle principal
		bool paused;	  // Idica si el juego está en pausa
		Uint32 ticks;	  // Contador de ticks para ajustar la velocidad del juego
		Uint8 ticksSpeed; // Velocidad a la que se repite el bucle de juego
		Uint32 counter;	  // Contador para el juego
	};

	// Recursos
	struct _resourceFile
	{
		std::string file;
	};

	struct _resourceSound
	{
		std::string file;
		JA_Sound sound;
	};

	struct _resourceMusic
	{
		std::string file;
		JA_Music music;
	};

	struct _resourceTexture
	{
		std::string file;
		LTexture *texture;
	};

	struct _resource
	{
		_resourceFile file[TOTAL_FILE];
		_resourceSound sound[TOTAL_SOUND];
		_resourceMusic music[TOTAL_MUSIC];
		_resourceTexture texture[TOTAL_TEXTURE];
	};

	SDL_Window *window;			  // La ventana de la aplicación
	SDL_Renderer *renderer;		  // El renderizador donde se dibuja todo
	SDL_Event *eventHandler;	  // Manejador de eventos
	SDL_Texture *backbuffer;	  // Texturas
	SDL_Joystick *gameController; // Manejador para el mando 1
	SDL_Haptic *controllerHaptic; // Manejador para la vibración del mando

	_game game; // Contiene las variables de la sección de juego
	//_menu menu;							// Variable con los objetos menu
	_resource resource;					// Contiene todos los objetos y variables asociados a recursos
	_options options;					// Contiene todas las opciones del programa
	_text text;							// Variable con los objetos texto
	bool gameControllerFound;			// Indica si se ha encontrado algun mando conectado
	double sen[360];					// Vector con los valores del seno para 360 grados
	Player *player;						// El jugador
	Map *map;							// El mapa del juego
	Screen *screen;						// Objeto para pintar en pantalla
	Asset *asset;						// Objeto con todos los ficheros de recursos
	Uint32 scoreData[TOTAL_SCORE_DATA]; // Datos del fichero de puntuación
	std::string path;					// Path donde está el ejecutable del juego
	enum _section						// Lista con todas las secciones en las que se divide el programa
	{
		GAME,
		TITLE,
		QUIT,
		NONE
	};
	_section section; // Seccion actual del programa
	bool quit;		  // Indica si hay que terminar el programa

	// Inicializa todas las variables
	void init(std::string _path);

	// Inicializa las variables de las opciones
	void initOptions();

	// Inicializa las variables del juego
	void initGame();

	// Limpia las variables del juego
	void quitGame();

	// Arranca SDL y crea la ventana
	bool initSDL();

	// Crea los objetos del programa
	void initObjects();

	// Borra los objetos del programa
	void deleteObjects();

	// Establece el valor de la variable
	void setPath(std::string _path);

	// Crea el indice de ficheros de recursos
	void setFileList();

	// Comprueba que todos los ficheros de recursos existen
	bool checkResourceList();

	// Inicializa la variable con los ficheros de recursos
	bool initResourceList();

	// Carga los recursos necesarios
	bool loadMedia(Uint8 section);

	// Descrga los recursos necesarios
	bool unLoadMedia(Uint8 section);

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

	// Establece el valor de la variable
	void changeGameSection(_section sectionPrevious, _section sectionNext);

	// Cambia el valor de la variable de modo de pantalla completa
	void changeFullScreenMode();

	// Comprueba si hay que salir
	bool isRunning();

	// Bucle para el logo del juego
	void runLogo();

	// Bucle para la intro del juego
	void runIntro();

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

	// Bucle para el juego
	void runGame();

	// Pinta la sección de juego
	void renderGame();

	// Actualiza la lógica del juego
	void updateGame();

public:
	// Constructor
	Director(std::string _path);

	// Destructor
	~Director();

	// Bucle principal
	void run();
};

#endif
