#pragma once

#include <vector>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <tmxlite/Map.hpp>
#include "SFMLOrthogonalLayer.hpp"
#include "Launcher.hpp"
#include "Player.hpp"
#include "IEntity.hpp"
#include "BlockLayer.hpp"
#include "Collider.hpp"
#include "Grid.hpp"
#include "Spike.hpp"
#include "Sand.hpp"
#include "Fruit.hpp"

#define LAYER_COUNT 3

class Core {
public:
	Core() = delete;
	Core(sf::RenderWindow* window);
	virtual ~Core();
	score_t getScore(); // TODO why can't I set this to const??;
	bool hasQuit();
	void run();
private:
	void registerEntity(IEntity* entity);
	void deregisterEntity(IEntity* entity);

	void events();
	void update(float delta);
    void reset();
	
	enum State {
		SPLASH, INGAME, END
	};
	State m_state;
	
	std::vector<IEntity*> m_entities;
	
	score_t m_score;
	bool m_running;
	bool m_paused;
	
	Collider m_collider;
	Renderer m_renderer;
	std::vector<Spike> m_spikes;
	std::vector<Sand> m_sand;
	std::vector<Fruit> m_fruit;
	
	sf::RenderWindow* m_window;
 	Player m_player;
	
	BlockLayer m_blockLayer;
	Grid m_grid;
	
	sf::Sound m_music;
	
	sf::Sprite m_background;
	tmx::Map m_map;
	std::array<MapLayer, LAYER_COUNT> m_layer;
	
	sf::Clock m_interlude_clock;
	sf::Clock m_fruit_clock;
	sf::Clock m_global_clock;
	
	sf::Sprite m_splash;
	bool m_victory;
	sf::Text m_victory_text;
};