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

#include "utils.h"
#include "asset.h"
#include "screen.h"
#include "enemy.h"
#include "item.h"
#include "item_tracker.h"
#include "const.h"
#include "jail_audio.h"
#include "debug.h"
#include <string>
#include <vector>

#ifndef ROOM_H
#define ROOM_H

/*
Cada habitación se crea y destruye cada vez que se entra o sale de la misma
Cada habitacion tiene lo siguiente:
 - ID (numerico)
 - NOMBRE (texto)
 - COLOR DE FONDO (texto)
 - COLOR DEL BORDE (texto)
 - SET DE TILES (texto, hace referencia a un png de la colección)
 - LIMITE SUPERIOR (ID de la habitación superior), INFERIOR, IZQUIERDO y DERECHO
 - MAPA DE TILES (array con los indices de los tiles a utilizar) <-- hay que decidir si cada tile del set ya
   tierne propiedades o se ponen en un mapa aparte
 - LISTADO DE ENEMIGOS (tipo, posicion, dx, dy)
 - LISTADO DE ITEMS (tipo, posicion)
*/
enum tile_e
{
	t_empty,
	t_wall,
	t_passable,
	t_slope_l,
	t_slope_r,
	t_death
};

// Clase Room
class Room
{
private:
	std::string name;					  // Nombre de la habitación
	color_t bgColor;					  // Color de fondo de la habitación
	color_t borderColor;				  // Color de fondo de la habitación
	std::string roomUp;					  // Identificador de la habitación que se encuentra arriba
	std::string roomDown;				  // Identificador de la habitación que se encuentra abajp
	std::string roomLeft;				  // Identificador de la habitación que se encuentra a la izquierda
	std::string roomRight;				  // Identificador de la habitación que se encuentra a la derecha
	std::string tileset;				  // Imagen con los graficos para la habitación
	std::vector<int> tilemap;			  // Indice de los tiles a dibujar en la habitación
	std::vector<Enemy *> enemies;		  // Listado con los enemigos de la habitación
	std::vector<Item *> items;			  // Listado con los items que hay en la habitación
	LTexture *texture;					  // Textura con los graficos de la habitación
	Asset *asset;						  // Objeto con la ruta a todos los ficheros de recursos
	Screen *screen;						  // Objeto encargado de dibujar en pantalla
	ItemTracker *itemTracker;			  // Lleva el control de los objetos recogidos
	SDL_Renderer *renderer;				  // El renderizador de la ventana
	SDL_Texture *mapTexture;			  // Textura para dibujar el mapa de la habitación
	JA_Sound itemSound;					  // Sonido producido al coger un objeto
	int *itemsPicked;					  // Puntero a la cantidad de items recogidos que lleva el juego
	Debug *debug;						  // Objeto para gestionar la información de debug
	std::vector<SDL_Rect> bottomSurfaces; // Lista con las superficies de colisón inferiores

	int tileSize;	  // Ancho del tile en pixels
	int mapWidth;	  // Ancho del mapa en tiles
	int mapHeight;	  // Alto del mapa en tiles
	int tilesetWidth; // Ancho del tileset en tiles

	// Carga las variables desde un fichero
	bool load(std::string file_path);

	// Asigna variables a partir de dos cadenas
	bool setVars(std::string var, std::string value);

	// Asigna variables a una estructura enemy_t
	bool setEnemy(enemy_t *enemy, std::string var, std::string value);

	// Asigna variables a una estructura item_t
	bool setItem(item_t *item, std::string var, std::string value);

	// Pinta el mapa de la habitación en la textura
	void fillMapTexture();

public:
	// Constructor
	Room(std::string file_path, SDL_Renderer *renderer, Screen *screen, Asset *asset, ItemTracker *item_tracker, int *items, Debug *debug);

	// Destructor
	~Room();

	// Devuelve el nombre de la habitación
	std::string getName();

	// Devuelve el color de la habitación
	color_t getBGColor();

	// Dibuja el mapa en pantalla
	void renderMap();

	// Dibuja los enemigos en pantalla
	void renderEnemies();

	// Dibuja los objetos en pantalla
	void renderItems();

	// Actualiza las variables y objetos de la habitación
	void update();

	// Devuelve la cadena del fichero de la habitación contigua segun el borde
	std::string getRoom(int border);

	// Devuelve el tipo de tile que hay en ese pixel
	tile_e getTile(SDL_Point point);

	// Indica si hay colision con un enemigo a partir de un rectangulo
	bool enemyCollision(SDL_Rect &rect);

	// Indica si hay colision con un objeto a partir de un rectangulo
	bool itemCollision(SDL_Rect &rect);

	// Recarga la textura
	void reLoadTexture();

	// Obten el tamaño del tile
	int getTileSize();

	// Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
	int getSlopeHeight(SDL_Point p, tile_e slope);
};

#endif
